Merge changes If24a29e6,I59c0a7ed,I2e82f0ba,Ie238338a

* changes:
  Pull members from internal AndroidPackage to system API
  Remove ParsingPackageRead
  Remove ParsingPackageImpl
  Remove PackageInfoWithoutStateUtils
This commit is contained in:
Winson Chiu
2022-08-26 17:57:11 +00:00
committed by Android (Google) Code Review
37 changed files with 4880 additions and 6032 deletions

View File

@@ -26,7 +26,7 @@ import android.perftests.utils.BenchmarkState
import android.perftests.utils.PerfStatusReporter
import androidx.test.filters.LargeTest
import com.android.internal.util.ConcurrentUtils
import com.android.server.pm.pkg.parsing.ParsingPackageImpl
import com.android.server.pm.parsing.pkg.PackageImpl
import com.android.server.pm.pkg.parsing.ParsingPackageUtils
import libcore.io.IoUtils
import org.junit.Rule
@@ -190,7 +190,7 @@ public class PackageParsingPerfTest {
}
class ParallelParser2(cacher: PackageCacher2? = null)
: ParallelParser<ParsingPackageImpl>(cacher) {
: ParallelParser<PackageImpl>(cacher) {
val input = ThreadLocal.withInitial {
// For testing, just disable enforcement to avoid hooking up to compat framework
ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
@@ -208,17 +208,18 @@ public class PackageParsingPerfTest {
path: String,
manifestArray: TypedArray,
isCoreApp: Boolean
) = ParsingPackageImpl(
) = PackageImpl(
packageName,
baseApkPath,
path,
manifestArray
manifestArray,
isCoreApp,
)
})
override fun parseImpl(file: File) =
parser.parsePackage(input.get()!!.reset(), file, 0, null).result
as ParsingPackageImpl
as PackageImpl
}
abstract class PackageCacher<PackageType : Parcelable>(private val cacheDir: File) {
@@ -274,8 +275,8 @@ public class PackageParsingPerfTest {
/**
* Re-implementation of the server side PackageCacher, as it's inaccessible here.
*/
class PackageCacher2(cacheDir: File) : PackageCacher<ParsingPackageImpl>(cacheDir) {
class PackageCacher2(cacheDir: File) : PackageCacher<PackageImpl>(cacheDir) {
override fun fromParcel(parcel: Parcel) =
ParsingPackageImpl(parcel)
PackageImpl(parcel)
}
}

View File

@@ -44,7 +44,6 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.net.Uri;
@@ -52,23 +51,21 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Pair;
import android.util.Slog;
import android.util.apk.SourceStampVerificationResult;
import android.util.apk.SourceStampVerifier;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.integrity.engine.RuleEvaluationEngine;
import com.android.server.integrity.model.IntegrityCheckResult;
import com.android.server.integrity.model.RuleMetadata;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import java.io.ByteArrayInputStream;
@@ -297,8 +294,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
PackageInfo packageInfo = getPackageArchiveInfo(intent.getData());
if (packageInfo == null) {
Pair<SigningDetails, Bundle> packageSigningAndMetadata =
getPackageSigningAndMetadata(intent.getData());
if (packageSigningAndMetadata == null) {
Slog.w(TAG, "Cannot parse package " + packageName);
// We can't parse the package.
mPackageManagerInternal.setIntegrityVerificationResult(
@@ -306,8 +304,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
return;
}
List<String> appCertificates = getCertificateFingerprint(packageInfo);
List<String> appCertificateLineage = getCertificateLineage(packageInfo);
var signingDetails = packageSigningAndMetadata.first;
List<String> appCertificates = getCertificateFingerprint(packageName, signingDetails);
List<String> appCertificateLineage = getCertificateLineage(packageName, signingDetails);
List<String> installerCertificates =
getInstallerCertificateFingerprint(installerPackageName);
@@ -320,7 +319,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
builder.setInstallerName(getPackageNameNormalized(installerPackageName));
builder.setInstallerCertificates(installerCertificates);
builder.setIsPreInstalled(isSystemApp(packageName));
builder.setAllowedInstallersAndCert(getAllowedInstallers(packageInfo));
Map<String, String> allowedInstallers =
getAllowedInstallers(packageSigningAndMetadata.second);
builder.setAllowedInstallersAndCert(allowedInstallers);
extractSourceStamp(intent.getData(), builder);
AppInstallMetadata appInstallMetadata = builder.build();
@@ -331,7 +333,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
"To be verified: "
+ appInstallMetadata
+ " installers "
+ getAllowedInstallers(packageInfo));
+ allowedInstallers);
}
IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata);
if (!result.getMatchedRules().isEmpty() || DEBUG_INTEGRITY_COMPONENT) {
@@ -443,38 +445,37 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
if (installer.equals(ADB_INSTALLER) || installer.equals(UNKNOWN_INSTALLER)) {
return Collections.emptyList();
}
try {
PackageInfo installerInfo =
mContext.getPackageManager()
.getPackageInfo(installer, PackageManager.GET_SIGNING_CERTIFICATES);
return getCertificateFingerprint(installerInfo);
} catch (PackageManager.NameNotFoundException e) {
var installerPkg = mPackageManagerInternal.getPackage(installer);
if (installerPkg == null) {
Slog.w(TAG, "Installer package " + installer + " not found.");
return Collections.emptyList();
}
return getCertificateFingerprint(installerPkg.getPackageName(),
installerPkg.getSigningDetails());
}
private List<String> getCertificateFingerprint(@NonNull PackageInfo packageInfo) {
private List<String> getCertificateFingerprint(@NonNull String packageName,
@NonNull SigningDetails signingDetails) {
ArrayList<String> certificateFingerprints = new ArrayList();
for (Signature signature : getSignatures(packageInfo)) {
for (Signature signature : getSignatures(packageName, signingDetails)) {
certificateFingerprints.add(getFingerprint(signature));
}
return certificateFingerprints;
}
private List<String> getCertificateLineage(@NonNull PackageInfo packageInfo) {
private List<String> getCertificateLineage(@NonNull String packageName,
@NonNull SigningDetails signingDetails) {
ArrayList<String> certificateLineage = new ArrayList();
for (Signature signature : getSignatureLineage(packageInfo)) {
for (Signature signature : getSignatureLineage(packageName, signingDetails)) {
certificateLineage.add(getFingerprint(signature));
}
return certificateLineage;
}
/** Get the allowed installers and their associated certificate hashes from <meta-data> tag. */
private Map<String, String> getAllowedInstallers(@NonNull PackageInfo packageInfo) {
private Map<String, String> getAllowedInstallers(@Nullable Bundle metaData) {
Map<String, String> packageCertMap = new HashMap<>();
if (packageInfo.applicationInfo != null && packageInfo.applicationInfo.metaData != null) {
Bundle metaData = packageInfo.applicationInfo.metaData;
if (metaData != null) {
String allowedInstallers = metaData.getString(ALLOWED_INSTALLERS_METADATA_NAME);
if (allowedInstallers != null) {
// parse the metadata for certs.
@@ -540,32 +541,25 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
}
}
private static Signature[] getSignatures(@NonNull PackageInfo packageInfo) {
SigningInfo signingInfo = packageInfo.signingInfo;
if (signingInfo == null || signingInfo.getApkContentsSigners().length < 1) {
throw new IllegalArgumentException("Package signature not found in " + packageInfo);
private static Signature[] getSignatures(@NonNull String packageName,
@NonNull SigningDetails signingDetails) {
Signature[] signatures = signingDetails.getSignatures();
if (signatures == null || signatures.length < 1) {
throw new IllegalArgumentException("Package signature not found in " + packageName);
}
// We are only interested in evaluating the active signatures.
return signingInfo.getApkContentsSigners();
return signatures;
}
private static Signature[] getSignatureLineage(@NonNull PackageInfo packageInfo) {
// Obtain the signing info of the package.
SigningInfo signingInfo = packageInfo.signingInfo;
if (signingInfo == null) {
throw new IllegalArgumentException(
"Package signature not found in " + packageInfo);
}
private static Signature[] getSignatureLineage(@NonNull String packageName,
@NonNull SigningDetails signingDetails) {
// Obtain the active signatures of the package.
Signature[] signatureLineage = getSignatures(packageInfo);
Signature[] signatureLineage = getSignatures(packageName, signingDetails);
var pastSignatures = signingDetails.getPastSigningCertificates();
// Obtain the past signatures of the package.
if (!signingInfo.hasMultipleSigners() && signingInfo.hasPastSigningCertificates()) {
Signature[] pastSignatures = signingInfo.getSigningCertificateHistory();
if (signatureLineage.length == 1 && !ArrayUtils.isEmpty(pastSignatures)) {
// Merge the signatures and return.
Signature[] allSignatures =
new Signature[signatureLineage.length + pastSignatures.length];
@@ -614,15 +608,15 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
}
}
private PackageInfo getPackageArchiveInfo(Uri dataUri) {
@Nullable
private Pair<SigningDetails, Bundle> getPackageSigningAndMetadata(Uri dataUri) {
File installationPath = getInstallationPath(dataUri);
if (installationPath == null) {
throw new IllegalArgumentException("Installation path is null, package not found");
}
try (PackageParser2 parser = mParserSupplier.get()) {
ParsedPackage pkg = parser.parsePackage(installationPath, 0, false);
int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA;
var pkg = parser.parsePackage(installationPath, 0, false);
// APK signatures is already verified elsewhere in PackageManager. We do not need to
// verify it again since it could cause a timeout for large APKs.
final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
@@ -632,17 +626,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
Slog.w(TAG, result.getErrorMessage(), result.getException());
return null;
}
pkg.setSigningDetails(result.getResult());
return PackageInfoUtils.generate(
pkg,
null,
flags,
0,
0,
null,
PackageUserStateInternal.DEFAULT,
UserHandle.getCallingUserId(),
null);
return Pair.create(result.getResult(), pkg.getMetaData());
} catch (Exception e) {
Slog.w(TAG, "Exception reading " + dataUri, e);
return null;

View File

@@ -143,7 +143,6 @@ import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationUtils;
@@ -905,7 +904,7 @@ public class ComputerEngine implements Computer {
a, flags, ps.getUserStateOrDefault(userId), userId, ps);
}
if (resolveComponentName().equals(component)) {
return PackageInfoWithoutStateUtils.generateDelegateActivityInfo(mResolveActivity,
return PackageInfoUtils.generateDelegateActivityInfo(mResolveActivity,
flags, PackageUserStateInternal.DEFAULT, userId);
}
return null;
@@ -1591,10 +1590,9 @@ public class ComputerEngine implements Computer {
return result;
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
ephemeralInstaller.activityInfo =
PackageInfoWithoutStateUtils.generateDelegateActivityInfo(
instantAppInstallerActivity(), 0 /*flags*/,
ps.getUserStateOrDefault(userId), userId);
ephemeralInstaller.activityInfo = PackageInfoUtils.generateDelegateActivityInfo(
instantAppInstallerActivity(), 0 /*flags*/,
ps.getUserStateOrDefault(userId), userId);
ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
@@ -1681,7 +1679,7 @@ public class ComputerEngine implements Computer {
ai.setVersionCode(ps.getVersionCode());
ai.flags = ps.getFlags();
ai.privateFlags = ps.getPrivateFlags();
pi.applicationInfo = PackageInfoWithoutStateUtils.generateDelegateApplicationInfo(
pi.applicationInfo = PackageInfoUtils.generateDelegateApplicationInfo(
ai, flags, state, userId);
if (DEBUG_PACKAGE_INFO) {

View File

@@ -116,7 +116,6 @@ import com.android.server.pm.pkg.component.ParsedComponent;
import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedProcess;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.resolution.ComponentResolver;
import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
@@ -2687,8 +2686,8 @@ public final class Settings implements Watchable, Snappable {
for (final PackageSetting pkg : mPackages.values()) {
// TODO(b/135203078): This doesn't handle multiple users
final String dataPath = pkg.getPkg() == null ? null :
PackageInfoWithoutStateUtils.getDataDir(pkg.getPkg(),
UserHandle.USER_SYSTEM).getAbsolutePath();
PackageInfoUtils.getDataDir(pkg.getPkg(), UserHandle.USER_SYSTEM)
.getAbsolutePath();
if (pkg.getPkg() == null || dataPath == null) {
if (!"android".equals(pkg.getPackageName())) {
@@ -4619,7 +4618,7 @@ public final class Settings implements Watchable, Snappable {
pw.append(prefix).append(" queriesIntents=")
.println(ps.getPkg().getQueriesIntents());
}
File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
File dataDir = PackageInfoUtils.getDataDir(pkg, UserHandle.myUserId());
pw.print(prefix); pw.print(" dataDir="); pw.println(dataDir.getAbsolutePath());
pw.print(prefix); pw.print(" supportsScreens=[");
boolean first = true;

View File

@@ -53,8 +53,8 @@ import com.android.server.LocalServices;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.PackageManagerServiceCompilerMapping;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
@@ -488,7 +488,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
final String packageName = pkg.getPackageName();
final String apkPath = pkg.getBaseApkPath();
// TODO(b/143971007): Use a cross-user directory
File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
File dataDir = PackageInfoUtils.getDataDir(pkg, UserHandle.myUserId());
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
if (pkg.isPrivileged() || pkg.isUseEmbeddedDex()
|| pkg.isDefaultToDeviceProtectedStorage()) {

View File

@@ -16,13 +16,13 @@
package com.android.server.pm.dex;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import android.os.Binder;
import android.os.UserHandle;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.server.pm.Installer;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.File;
@@ -42,7 +42,7 @@ public class ViewCompiler {
final String packageName = pkg.getPackageName();
final String apkPath = pkg.getBaseApkPath();
// TODO(b/143971007): Use a cross-user directory
File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId());
File dataDir = PackageInfoUtils.getDataDir(pkg, UserHandle.myUserId());
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);

View File

@@ -23,33 +23,49 @@ import android.annotation.UserIdInt;
import android.apex.ApexInfo;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.Attribution;
import android.content.pm.ComponentInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PathPermission;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProcessInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.overlay.OverlayPaths;
import android.os.Environment;
import android.os.PatternMatcher;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageStateUnserialized;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.PackageUserStateUtils;
import com.android.server.pm.pkg.SELinuxUtil;
import com.android.server.pm.pkg.component.ComponentParseUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedAttribution;
import com.android.server.pm.pkg.component.ParsedComponent;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedMainComponent;
@@ -58,11 +74,13 @@ import com.android.server.pm.pkg.component.ParsedPermissionGroup;
import com.android.server.pm.pkg.component.ParsedProcess;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.pm.pkg.parsing.ParsingUtils;
import libcore.util.EmptyArray;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -79,6 +97,9 @@ import java.util.Set;
public class PackageInfoUtils {
private static final String TAG = ParsingUtils.TAG;
private static final String SYSTEM_DATA_PATH =
Environment.getDataDirectoryPath() + File.separator + "system";
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@@ -117,9 +138,155 @@ public class PackageInfoUtils {
return null;
}
PackageInfo info = PackageInfoWithoutStateUtils.generateWithoutComponentsUnchecked(pkg,
gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, userId,
apexInfo, applicationInfo);
PackageInfo info = new PackageInfo();
info.packageName = pkg.getPackageName();
info.splitNames = pkg.getSplitNames();
AndroidPackageUtils.fillVersionCodes(pkg, info);
info.baseRevisionCode = pkg.getBaseRevisionCode();
info.splitRevisionCodes = pkg.getSplitRevisionCodes();
info.versionName = pkg.getVersionName();
info.sharedUserId = pkg.getSharedUserId();
info.sharedUserLabel = pkg.getSharedUserLabel();
info.applicationInfo = applicationInfo;
info.installLocation = pkg.getInstallLocation();
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|| (info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
info.requiredForAllUsers = pkg.isRequiredForAllUsers();
}
info.restrictedAccountType = pkg.getRestrictedAccountType();
info.requiredAccountType = pkg.getRequiredAccountType();
info.overlayTarget = pkg.getOverlayTarget();
info.targetOverlayableName = pkg.getOverlayTargetOverlayableName();
info.overlayCategory = pkg.getOverlayCategory();
info.overlayPriority = pkg.getOverlayPriority();
info.mOverlayIsStatic = pkg.isOverlayIsStatic();
info.compileSdkVersion = pkg.getCompileSdkVersion();
info.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
info.firstInstallTime = firstInstallTime;
info.lastUpdateTime = lastUpdateTime;
if ((flags & PackageManager.GET_GIDS) != 0) {
info.gids = gids;
}
if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
int size = pkg.getConfigPreferences().size();
if (size > 0) {
info.configPreferences = new ConfigurationInfo[size];
pkg.getConfigPreferences().toArray(info.configPreferences);
}
size = pkg.getRequestedFeatures().size();
if (size > 0) {
info.reqFeatures = new FeatureInfo[size];
pkg.getRequestedFeatures().toArray(info.reqFeatures);
}
size = pkg.getFeatureGroups().size();
if (size > 0) {
info.featureGroups = new FeatureGroupInfo[size];
pkg.getFeatureGroups().toArray(info.featureGroups);
}
}
if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
int size = ArrayUtils.size(pkg.getPermissions());
if (size > 0) {
info.permissions = new PermissionInfo[size];
for (int i = 0; i < size; i++) {
info.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
flags);
}
}
final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
size = usesPermissions.size();
if (size > 0) {
info.requestedPermissions = new String[size];
info.requestedPermissionsFlags = new int[size];
for (int i = 0; i < size; i++) {
final ParsedUsesPermission usesPermission = usesPermissions.get(i);
info.requestedPermissions[i] = usesPermission.getName();
// The notion of required permissions is deprecated but for compatibility.
info.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_REQUIRED;
if (grantedPermissions != null
&& grantedPermissions.contains(usesPermission.getName())) {
info.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_GRANTED;
}
if ((usesPermission.getUsesPermissionFlags()
& ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
info.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
}
if (pkg.getImplicitPermissions().contains(info.requestedPermissions[i])) {
info.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_IMPLICIT;
}
}
}
}
if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
int size = ArrayUtils.size(pkg.getAttributions());
if (size > 0) {
info.attributions = new Attribution[size];
for (int i = 0; i < size; i++) {
ParsedAttribution parsedAttribution = pkg.getAttributions().get(i);
if (parsedAttribution != null) {
info.attributions[i] = new Attribution(parsedAttribution.getTag(),
parsedAttribution.getLabel());
}
}
}
if (pkg.areAttributionsUserVisible()) {
info.applicationInfo.privateFlagsExt
|= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
} else {
info.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
} else {
info.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
if (apexInfo != null) {
File apexFile = new File(apexInfo.modulePath);
info.applicationInfo.sourceDir = apexFile.getPath();
info.applicationInfo.publicSourceDir = apexFile.getPath();
info.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
info.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
if (apexInfo.isFactory) {
info.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
} else {
info.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
info.isApex = true;
info.isActiveApex = apexInfo.isActive;
}
final SigningDetails signingDetails = pkg.getSigningDetails();
// deprecated method of getting signing certificates
if ((flags & PackageManager.GET_SIGNATURES) != 0) {
if (signingDetails.hasPastSigningCertificates()) {
// Package has included signing certificate rotation information. Return the oldest
// cert so that programmatic checks keep working even if unaware of key rotation.
info.signatures = new Signature[1];
info.signatures[0] = signingDetails.getPastSigningCertificates()[0];
} else if (signingDetails.hasSignatures()) {
// otherwise keep old behavior
int numberOfSigs = signingDetails.getSignatures().length;
info.signatures = new Signature[numberOfSigs];
System.arraycopy(signingDetails.getSignatures(), 0, info.signatures, 0,
numberOfSigs);
}
}
// replacement for GET_SIGNATURES
if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
if (signingDetails != SigningDetails.UNKNOWN) {
// only return a valid SigningInfo if there is signing information to report
info.signingInfo = new SigningInfo(signingDetails);
} else {
info.signingInfo = null;
}
}
info.isStub = pkg.isStub();
info.coreApp = pkg.isCoreApp();
@@ -215,9 +382,70 @@ public class PackageInfoUtils {
return info;
}
private static void updateApplicationInfo(ApplicationInfo ai, long flags,
PackageUserState state) {
if ((flags & PackageManager.GET_META_DATA) == 0) {
ai.metaData = null;
}
if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
ai.sharedLibraryFiles = null;
ai.sharedLibraryInfos = null;
}
// CompatibilityMode is global state.
if (!ParsingPackageUtils.sCompatibilityModeEnabled) {
ai.disableCompatibilityMode();
}
ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED)
| flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED)
| flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED);
ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT)
| flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
| flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN);
if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
ai.enabled = true;
} else if (state.getEnabledState()
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
} else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state.getEnabledState()
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
ai.enabled = false;
}
ai.enabledSetting = state.getEnabledState();
if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
final OverlayPaths overlayPaths = state.getAllOverlayPaths();
if (overlayPaths != null) {
ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
}
}
@Nullable
public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai,
@PackageManager.ApplicationInfoFlagsBits long flags,
@NonNull PackageUserState state, int userId) {
if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) {
return null;
}
ai = new ApplicationInfo(ai);
ai.initForUser(userId);
ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes
: ai.iconRes;
updateApplicationInfo(ai, flags, state);
return ai;
}
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@VisibleForTesting
@Nullable
public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg,
@PackageManager.ApplicationInfoFlagsBits long flags,
@@ -232,8 +460,10 @@ public class PackageInfoUtils {
return null;
}
ApplicationInfo info = PackageInfoWithoutStateUtils.generateApplicationInfoUnchecked(pkg,
flags, state, userId, false /* assignUserFields */);
// Make shallow copy so we can store the metadata/libraries safely
ApplicationInfo info = AndroidPackageUtils.toAppInfoWithoutState(pkg);
updateApplicationInfo(info, flags, state);
initForUser(info, pkg, userId);
@@ -265,6 +495,7 @@ public class PackageInfoUtils {
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@VisibleForTesting
@Nullable
public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
@PackageManager.ComponentInfoFlagsBits long flags,
@@ -276,8 +507,9 @@ public class PackageInfoUtils {
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@VisibleForTesting
@Nullable
private static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull PackageUserStateInternal state, @Nullable ApplicationInfo applicationInfo,
@UserIdInt int userId, @Nullable PackageStateInternal pkgSetting) {
@@ -293,10 +525,61 @@ public class PackageInfoUtils {
return null;
}
final ActivityInfo info = PackageInfoWithoutStateUtils.generateActivityInfoUnchecked(
a, flags, applicationInfo);
assignSharedFieldsForComponentInfo(info, a, pkgSetting, userId);
return info;
// Make shallow copies so we can store the metadata safely
ActivityInfo ai = new ActivityInfo();
ai.targetActivity = a.getTargetActivity();
ai.processName = a.getProcessName();
ai.exported = a.isExported();
ai.theme = a.getTheme();
ai.uiOptions = a.getUiOptions();
ai.parentActivityName = a.getParentActivityName();
ai.permission = a.getPermission();
ai.taskAffinity = a.getTaskAffinity();
ai.flags = a.getFlags();
ai.privateFlags = a.getPrivateFlags();
ai.launchMode = a.getLaunchMode();
ai.documentLaunchMode = a.getDocumentLaunchMode();
ai.maxRecents = a.getMaxRecents();
ai.configChanges = a.getConfigChanges();
ai.softInputMode = a.getSoftInputMode();
ai.persistableMode = a.getPersistableMode();
ai.lockTaskLaunchMode = a.getLockTaskLaunchMode();
ai.screenOrientation = a.getScreenOrientation();
ai.resizeMode = a.getResizeMode();
ai.setMaxAspectRatio(a.getMaxAspectRatio());
ai.setMinAspectRatio(a.getMinAspectRatio());
ai.supportsSizeChanges = a.isSupportsSizeChanges();
ai.requestedVrComponent = a.getRequestedVrComponent();
ai.rotationAnimation = a.getRotationAnimation();
ai.colorMode = a.getColorMode();
ai.windowLayout = a.getWindowLayout();
ai.attributionTags = a.getAttributionTags();
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = a.getMetaData();
// Backwards compatibility, coerce to null if empty
ai.metaData = metaData.isEmpty() ? null : metaData;
} else {
ai.metaData = null;
}
ai.applicationInfo = applicationInfo;
ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId);
return ai;
}
@Nullable
public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull PackageUserState state, int userId) {
if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) {
return null;
}
// This is used to return the ResolverActivity or instantAppInstallerActivity;
// we will just always make a copy.
final ActivityInfo ai = new ActivityInfo(a);
ai.applicationInfo =
generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId);
return ai;
}
/**
@@ -312,8 +595,9 @@ public class PackageInfoUtils {
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@VisibleForTesting
@Nullable
private static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
public static ServiceInfo generateServiceInfo(AndroidPackage pkg, ParsedService s,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state,
@Nullable ApplicationInfo applicationInfo, int userId,
@Nullable PackageStateInternal pkgSetting) {
@@ -328,15 +612,28 @@ public class PackageInfoUtils {
return null;
}
final ServiceInfo info = PackageInfoWithoutStateUtils.generateServiceInfoUnchecked(
s, flags, applicationInfo);
assignSharedFieldsForComponentInfo(info, s, pkgSetting, userId);
return info;
// Make shallow copies so we can store the metadata safely
ServiceInfo si = new ServiceInfo();
si.exported = s.isExported();
si.flags = s.getFlags();
si.permission = s.getPermission();
si.processName = s.getProcessName();
si.mForegroundServiceType = s.getForegroundServiceType();
si.applicationInfo = applicationInfo;
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = s.getMetaData();
// Backwards compatibility, coerce to null if empty
si.metaData = metaData.isEmpty() ? null : metaData;
}
assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, userId);
return si;
}
/**
* @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage.
*/
@VisibleForTesting
@Nullable
public static ProviderInfo generateProviderInfo(AndroidPackage pkg, ParsedProvider p,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserStateInternal state,
@@ -355,10 +652,33 @@ public class PackageInfoUtils {
if (applicationInfo == null) {
return null;
}
ProviderInfo info = PackageInfoWithoutStateUtils.generateProviderInfoUnchecked(p, flags,
applicationInfo);
assignSharedFieldsForComponentInfo(info, p, pkgSetting, userId);
return info;
// Make shallow copies so we can store the metadata safely
ProviderInfo pi = new ProviderInfo();
pi.exported = p.isExported();
pi.flags = p.getFlags();
pi.processName = p.getProcessName();
pi.authority = p.getAuthority();
pi.isSyncable = p.isSyncable();
pi.readPermission = p.getReadPermission();
pi.writePermission = p.getWritePermission();
pi.grantUriPermissions = p.isGrantUriPermissions();
pi.forceUriPermissions = p.isForceUriPermissions();
pi.multiprocess = p.isMultiProcess();
pi.initOrder = p.getInitOrder();
pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]);
pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]);
if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
pi.uriPermissionPatterns = null;
}
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = p.getMetaData();
// Backwards compatibility, coerce to null if empty
pi.metaData = metaData.isEmpty() ? null : metaData;
}
pi.applicationInfo = applicationInfo;
assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, userId);
return pi;
}
/**
@@ -373,22 +693,37 @@ public class PackageInfoUtils {
return null;
}
InstrumentationInfo info =
PackageInfoWithoutStateUtils.generateInstrumentationInfo(i, pkg, flags, userId,
false /* assignUserFields */);
InstrumentationInfo info = new InstrumentationInfo();
info.targetPackage = i.getTargetPackage();
info.targetProcesses = i.getTargetProcesses();
info.handleProfiling = i.isHandleProfiling();
info.functionalTest = i.isFunctionalTest();
info.sourceDir = pkg.getBaseApkPath();
info.publicSourceDir = pkg.getBaseApkPath();
info.splitNames = pkg.getSplitNames();
info.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths();
info.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0
? null : pkg.getSplitCodePaths();
info.splitDependencies = pkg.getSplitDependencies().size() == 0
? null : pkg.getSplitDependencies();
initForUser(info, pkg, userId);
if (info == null) {
return null;
}
info.primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
info.secondaryCpuAbi = AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting);
info.nativeLibraryDir = pkg.getNativeLibraryDir();
info.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir();
assignStateFieldsForPackageItemInfo(info, i, pkgSetting, userId);
assignFieldsPackageItemInfoParsedComponent(info, i, pkgSetting, userId);
if ((flags & PackageManager.GET_META_DATA) == 0) {
info.metaData = null;
} else {
var metaData = i.getMetaData();
// Backwards compatibility, coerce to null if empty
info.metaData = metaData.isEmpty() ? null : metaData;
}
return info;
}
@@ -401,8 +736,25 @@ public class PackageInfoUtils {
// TODO(b/135203078): Remove null checks and make all usages @NonNull
if (p == null) return null;
// For now, permissions don't have state-adjustable fields; return directly
return PackageInfoWithoutStateUtils.generatePermissionInfo(p, flags);
PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission());
assignFieldsPackageItemInfoParsedComponent(pi, p);
pi.group = p.getGroup();
pi.requestRes = p.getRequestRes();
pi.protectionLevel = p.getProtectionLevel();
pi.descriptionRes = p.getDescriptionRes();
pi.flags = p.getFlags();
pi.knownCerts = p.getKnownCerts();
if ((flags & PackageManager.GET_META_DATA) == 0) {
pi.metaData = null;
} else {
var metaData = p.getMetaData();
// Backwards compatibility, coerce to null if empty
pi.metaData = metaData.isEmpty() ? null : metaData;
}
return pi;
}
@Nullable
@@ -410,8 +762,27 @@ public class PackageInfoUtils {
@PackageManager.ComponentInfoFlagsBits long flags) {
if (pg == null) return null;
// For now, permissions don't have state-adjustable fields; return directly
return PackageInfoWithoutStateUtils.generatePermissionGroupInfo(pg, flags);
PermissionGroupInfo pgi = new PermissionGroupInfo(
pg.getRequestDetailRes(),
pg.getBackgroundRequestRes(),
pg.getBackgroundRequestDetailRes()
);
assignFieldsPackageItemInfoParsedComponent(pgi, pg);
pgi.descriptionRes = pg.getDescriptionRes();
pgi.priority = pg.getPriority();
pgi.requestRes = pg.getRequestRes();
pgi.flags = pg.getFlags();
if ((flags & PackageManager.GET_META_DATA) == 0) {
pgi.metaData = null;
} else {
var metaData = pg.getMetaData();
// Backwards compatibility, coerce to null if empty
pgi.metaData = metaData.isEmpty() ? null : metaData;
}
return pgi;
}
@Nullable
@@ -456,25 +827,64 @@ public class PackageInfoUtils {
|| (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
}
private static void assignSharedFieldsForComponentInfo(@NonNull ComponentInfo componentInfo,
@NonNull ParsedMainComponent mainComponent, @Nullable PackageStateInternal pkgSetting,
int userId) {
assignStateFieldsForPackageItemInfo(componentInfo, mainComponent, pkgSetting, userId);
componentInfo.descriptionRes = mainComponent.getDescriptionRes();
componentInfo.directBootAware = mainComponent.isDirectBootAware();
componentInfo.enabled = mainComponent.isEnabled();
componentInfo.splitName = mainComponent.getSplitName();
componentInfo.attributionTags = mainComponent.getAttributionTags();
private static boolean checkUseInstalledOrHidden(long flags,
@NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) {
// Returns false if the package is hidden system app until installed.
if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
&& !state.isInstalled()
&& appInfo != null && appInfo.hiddenUntilInstalled) {
return false;
}
// If available for the target user, or trying to match uninstalled packages and it's
// a system app.
return PackageUserStateUtils.isAvailable(state, flags)
|| (appInfo != null && appInfo.isSystemApp()
&& ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
|| (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
}
private static void assignStateFieldsForPackageItemInfo(
@NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component,
private static void assignFieldsComponentInfoParsedMainComponent(
@NonNull ComponentInfo info, @NonNull ParsedMainComponent component) {
assignFieldsPackageItemInfoParsedComponent(info, component);
info.descriptionRes = component.getDescriptionRes();
info.directBootAware = component.isDirectBootAware();
info.enabled = component.isEnabled();
info.splitName = component.getSplitName();
info.attributionTags = component.getAttributionTags();
}
private static void assignFieldsPackageItemInfoParsedComponent(
@NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) {
packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component);
packageItemInfo.icon = ComponentParseUtils.getIcon(component);
packageItemInfo.banner = component.getBanner();
packageItemInfo.labelRes = component.getLabelRes();
packageItemInfo.logo = component.getLogo();
packageItemInfo.name = component.getName();
packageItemInfo.packageName = component.getPackageName();
}
private static void assignFieldsComponentInfoParsedMainComponent(
@NonNull ComponentInfo info, @NonNull ParsedMainComponent component,
@Nullable PackageStateInternal pkgSetting, int userId) {
assignFieldsComponentInfoParsedMainComponent(info, component);
Pair<CharSequence, Integer> labelAndIcon =
ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting,
userId);
packageItemInfo.nonLocalizedLabel = labelAndIcon.first;
packageItemInfo.icon = labelAndIcon.second;
info.nonLocalizedLabel = labelAndIcon.first;
info.icon = labelAndIcon.second;
}
private static void assignFieldsPackageItemInfoParsedComponent(
@NonNull PackageItemInfo info, @NonNull ParsedComponent component,
@Nullable PackageStateInternal pkgSetting, int userId) {
assignFieldsPackageItemInfoParsedComponent(info, component);
Pair<CharSequence, Integer> labelAndIcon =
ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting,
userId);
info.nonLocalizedLabel = labelAndIcon.first;
info.icon = labelAndIcon.second;
}
@CheckResult
@@ -487,7 +897,31 @@ public class PackageInfoUtils {
*/
public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting) {
// @formatter:off
int pkgWithoutStateFlags = PackageInfoWithoutStateUtils.appInfoFlags(pkg)
int pkgWithoutStateFlags = flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
| flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
| flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
| flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
| flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
| flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
| flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
| flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
| flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
| flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
| flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
| flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
| flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
| flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
| flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
| flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
| flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
| flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
| flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
| flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
| flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
| flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
| flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
| flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
| flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
| flag(pkg.isSystem(), ApplicationInfo.FLAG_SYSTEM)
| flag(pkg.isFactoryTest(), ApplicationInfo.FLAG_FACTORY_TEST);
@@ -511,7 +945,24 @@ public class PackageInfoUtils {
public static int appInfoPrivateFlags(AndroidPackage pkg,
@Nullable PackageStateInternal pkgSetting) {
// @formatter:off
int pkgWithoutStateFlags = PackageInfoWithoutStateUtils.appInfoPrivateFlags(pkg)
int pkgWithoutStateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
| flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
| flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
| flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
| flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
| flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
| flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
| flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
| flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
| flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
| flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
| flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
| flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
| flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
| flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
| flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
| flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
| flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING)
| flag(pkg.isSystemExt(), ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT)
| flag(pkg.isPrivileged(), ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
| flag(pkg.isOem(), ApplicationInfo.PRIVATE_FLAG_OEM)
@@ -519,6 +970,16 @@ public class PackageInfoUtils {
| flag(pkg.isProduct(), ApplicationInfo.PRIVATE_FLAG_PRODUCT)
| flag(pkg.isOdm(), ApplicationInfo.PRIVATE_FLAG_ODM)
| flag(pkg.isSignedWithPlatformKey(), ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY);
Boolean resizeableActivity = pkg.getResizeableActivity();
if (resizeableActivity != null) {
if (resizeableActivity) {
pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
} else {
pkgWithoutStateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
}
}
return appInfoPrivateFlags(pkgWithoutStateFlags, pkgSetting);
// @formatter:on
}
@@ -536,7 +997,10 @@ public class PackageInfoUtils {
public static int appInfoPrivateFlagsExt(AndroidPackage pkg,
@Nullable PackageStateInternal pkgSetting) {
// @formatter:off
int pkgWithoutStateFlags = PackageInfoWithoutStateUtils.appInfoPrivateFlagsExt(pkg);
int pkgWithoutStateFlags = flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
| flag(pkg.hasRequestForegroundServiceExemption(), ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
| flag(pkg.areAttributionsUserVisible(), ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE)
| flag(pkg.isOnBackInvokedCallbackEnabled(), ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK);
return appInfoPrivateFlagsExt(pkgWithoutStateFlags, pkgSetting);
// @formatter:on
}
@@ -557,7 +1021,7 @@ public class PackageInfoUtils {
output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid()));
if ("android".equals(packageName)) {
output.dataDir = PackageInfoWithoutStateUtils.SYSTEM_DATA_PATH;
output.dataDir = SYSTEM_DATA_PATH;
return;
}
@@ -599,7 +1063,7 @@ public class PackageInfoUtils {
PackageImpl pkg = ((PackageImpl) input);
String packageName = input.getPackageName();
if ("android".equals(packageName)) {
output.dataDir = PackageInfoWithoutStateUtils.SYSTEM_DATA_PATH;
output.dataDir = SYSTEM_DATA_PATH;
return;
}
@@ -634,6 +1098,22 @@ public class PackageInfoUtils {
}
}
@NonNull
public static File getDataDir(AndroidPackage pkg, int userId) {
if ("android".equals(pkg.getPackageName())) {
return Environment.getDataSystemDirectory();
}
if (pkg.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
return Environment.getDataUserDePackageDirectory(pkg.getVolumeUuid(), userId,
pkg.getPackageName());
} else {
return Environment.getDataUserCePackageDirectory(pkg.getVolumeUuid(), userId,
pkg.getPackageName());
}
}
/**
* Wraps {@link PackageInfoUtils#generateApplicationInfo} with a cache.
*/

View File

@@ -16,11 +16,7 @@
package com.android.server.pm.parsing.pkg;
import android.annotation.NonNull;
import com.android.internal.content.om.OverlayConfig;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
import com.android.server.pm.pkg.AndroidPackageApi;
/**
@@ -33,13 +29,6 @@ import com.android.server.pm.pkg.AndroidPackageApi;
*
* @hide
*/
public interface AndroidPackage extends ParsingPackageRead, AndroidPackageApi,
OverlayConfig.PackageProvider.Package {
public interface AndroidPackage extends AndroidPackageApi, OverlayConfig.PackageProvider.Package {
/**
* The package name as declared in the manifest, since the package can be renamed. For example,
* static shared libs use synthetic package names.
*/
@NonNull
String getManifestPackageName();
}

View File

@@ -19,16 +19,11 @@ package com.android.server.pm.parsing.pkg;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.DexMetadataHelper;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.os.incremental.IncrementalManager;
@@ -38,7 +33,13 @@ import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.util.ArrayUtils;
import com.android.server.SystemConfig;
import com.android.server.pm.PackageManagerException;
import com.android.server.pm.pkg.AndroidPackageApi;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.ParsingPackageHidden;
import java.io.IOException;
import java.util.ArrayList;
@@ -259,11 +260,6 @@ public class AndroidPackageUtils {
return ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED;
}
public static int getIcon(ParsingPackageRead pkg) {
return (ParsingPackageUtils.sUseRoundIcon && pkg.getRoundIconRes() != 0)
? pkg.getRoundIconRes() : pkg.getIconRes();
}
/**
* Returns false iff the provided flags include the {@link PackageManager#MATCH_SYSTEM_ONLY}
* flag and the provided package is not a system package. Otherwise returns {@code true}.
@@ -338,4 +334,13 @@ public class AndroidPackageUtils {
return pkg.getManifestPackageName();
}
public static void fillVersionCodes(@NonNull AndroidPackage pkg, @NonNull PackageInfo info) {
info.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
info.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
}
public static ApplicationInfo toAppInfoWithoutState(AndroidPackageApi pkg) {
return ((ParsingPackageHidden) pkg).toAppInfoWithoutState();
}
}

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2020 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.parsing.pkg;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import com.android.server.pm.pkg.parsing.PkgWithoutStateAppInfo;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.pkg.PackageState;
/**
* Equivalent of {@link PkgWithoutStateAppInfo} but contains fields that are set inside {@link
* PackageManagerService} and thus are not available to the core SDK.
* <p>
* Everything in this interface is @SystemApi(client = SYSTEM_SERVER), but the interface itself is
* not.
*/
public interface PkgAppInfo extends PkgWithoutStateAppInfo {
/**
* @see ApplicationInfo#nativeLibraryDir
*/
@Nullable
String getNativeLibraryDir();
/**
* @see ApplicationInfo#nativeLibraryRootDir
*/
@Nullable
String getNativeLibraryRootDir();
/**
* @see ApplicationInfo#secondaryNativeLibraryDir
*/
@Nullable
String getSecondaryNativeLibraryDir();
/**
* This is an appId, the {@link ApplicationInfo#uid} if the user ID is
* {@link android.os.UserHandle#SYSTEM}.
*
* @deprecated Use {@link PackageState#getAppId()} instead.
*/
@Deprecated
int getUid();
/**
* @see ApplicationInfo#FLAG_FACTORY_TEST
*/
boolean isFactoryTest();
/**
* @see ApplicationInfo#nativeLibraryRootRequiresIsa
*/
boolean isNativeLibraryRootRequiresIsa();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ODM
*/
boolean isOdm();
/**
* @see ApplicationInfo#PRIVATE_FLAG_OEM
*/
boolean isOem();
/**
* @see ApplicationInfo#PRIVATE_FLAG_PRIVILEGED
*/
boolean isPrivileged();
/**
* @see ApplicationInfo#PRIVATE_FLAG_PRODUCT
*/
boolean isProduct();
/**
* @see ApplicationInfo#PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY
*/
boolean isSignedWithPlatformKey();
/**
* @see ApplicationInfo#FLAG_SYSTEM
*/
boolean isSystem();
/**
* @see ApplicationInfo#PRIVATE_FLAG_SYSTEM_EXT
*/
boolean isSystemExt();
/**
* @see ApplicationInfo#PRIVATE_FLAG_VENDOR
*/
boolean isVendor();
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2020 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.parsing.pkg;
import android.content.pm.PackageInfo;
import com.android.server.pm.pkg.parsing.PkgWithoutStatePackageInfo;
import com.android.server.pm.PackageManagerService;
/**
* Equivalent of {@link PkgWithoutStatePackageInfo} but contains fields that are set inside {@link
* PackageManagerService} and thus are not available to the core SDK.
* <p>
* Everything in this interface is @SystemApi(client = SYSTEM_SERVER), but the interface itself is
* not.
*/
public interface PkgPackageInfo extends PkgWithoutStatePackageInfo {
/**
* @see PackageInfo#coreApp
*/
boolean isCoreApp();
/**
* @see PackageInfo#isStub
*/
boolean isStub();
}

View File

@@ -26,8 +26,8 @@ import android.os.Debug;
import android.util.DebugUtils;
import android.util.Slog;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
/** @hide */
public class PackageUserStateUtils {
@@ -155,7 +155,7 @@ public class PackageUserStateUtils {
}
public static boolean isPackageEnabled(@NonNull PackageUserState state,
@NonNull ParsingPackageRead pkg) {
@NonNull AndroidPackage pkg) {
switch (state.getEnabledState()) {
case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
return true;

View File

@@ -22,8 +22,8 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VER
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForStringSet;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForStringSet;
import android.annotation.NonNull;
import android.annotation.Nullable;

View File

@@ -16,7 +16,7 @@
package com.android.server.pm.pkg.component;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import static java.util.Collections.emptyMap;

View File

@@ -16,7 +16,7 @@
package com.android.server.pm.pkg.component;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import android.annotation.NonNull;
import android.annotation.Nullable;

View File

@@ -16,7 +16,7 @@
package com.android.server.pm.pkg.component;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import android.annotation.NonNull;
import android.annotation.Nullable;

View File

@@ -16,7 +16,7 @@
package com.android.server.pm.pkg.component;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import android.annotation.NonNull;
import android.annotation.Nullable;

View File

@@ -16,7 +16,7 @@
package com.android.server.pm.pkg.component;
import static com.android.server.pm.pkg.parsing.ParsingPackageImpl.sForInternedString;
import static com.android.server.pm.parsing.pkg.PackageImpl.sForInternedString;
import android.annotation.NonNull;
import android.annotation.Nullable;

View File

@@ -1,991 +0,0 @@
/*
* Copyright (C) 2022 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.parsing;
import android.annotation.CheckResult;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.apex.ApexInfo;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.Attribution;
import android.content.pm.ComponentInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PathPermission;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.overlay.OverlayPaths;
import android.os.Environment;
import android.os.PatternMatcher;
import android.os.UserHandle;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateUtils;
import com.android.server.pm.pkg.SELinuxUtil;
import com.android.server.pm.pkg.component.ComponentParseUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedAttribution;
import com.android.server.pm.pkg.component.ParsedComponent;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedPermissionGroup;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import libcore.util.EmptyArray;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @hide
**/
public class PackageInfoWithoutStateUtils {
public static final String SYSTEM_DATA_PATH =
Environment.getDataDirectoryPath() + File.separator + "system";
@Nullable
public static PackageInfo generate(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
int userId) {
return generateWithComponents(pkg, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions,
state, userId, null);
}
@Nullable
public static PackageInfo generate(ParsingPackageRead pkg, ApexInfo apexInfo, int flags) {
return generateWithComponents(pkg, EmptyArray.INT, flags, 0, 0, Collections.emptySet(),
PackageUserState.DEFAULT, UserHandle.getCallingUserId(), apexInfo);
}
@Nullable
private static PackageInfo generateWithComponents(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
int userId, @Nullable ApexInfo apexInfo) {
ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
if (applicationInfo == null) {
return null;
}
PackageInfo info = generateWithoutComponents(pkg, gids, flags, firstInstallTime,
lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
if (info == null) {
return null;
}
if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
final int N = pkg.getActivities().size();
if (N > 0) {
int num = 0;
final ActivityInfo[] res = new ActivityInfo[N];
for (int i = 0; i < N; i++) {
final ParsedActivity a = pkg.getActivities().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
flags)) {
if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
a.getName())) {
continue;
}
res[num++] = generateActivityInfo(pkg, a, flags, state,
applicationInfo, userId);
}
}
info.activities = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_RECEIVERS) != 0) {
final int size = pkg.getReceivers().size();
if (size > 0) {
int num = 0;
final ActivityInfo[] res = new ActivityInfo[size];
for (int i = 0; i < size; i++) {
final ParsedActivity a = pkg.getReceivers().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), a,
flags)) {
res[num++] = generateActivityInfo(pkg, a, flags, state,
applicationInfo, userId);
}
}
info.receivers = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_SERVICES) != 0) {
final int size = pkg.getServices().size();
if (size > 0) {
int num = 0;
final ServiceInfo[] res = new ServiceInfo[size];
for (int i = 0; i < size; i++) {
final ParsedService s = pkg.getServices().get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), s,
flags)) {
res[num++] = generateServiceInfo(pkg, s, flags, state,
applicationInfo, userId);
}
}
info.services = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_PROVIDERS) != 0) {
final int size = pkg.getProviders().size();
if (size > 0) {
int num = 0;
final ProviderInfo[] res = new ProviderInfo[size];
for (int i = 0; i < size; i++) {
final ParsedProvider pr = pkg.getProviders()
.get(i);
if (ComponentParseUtils.isMatch(state, false, pkg.isEnabled(), pr,
flags)) {
res[num++] = generateProviderInfo(pkg, pr, flags, state,
applicationInfo, userId);
}
}
info.providers = ArrayUtils.trimToSize(res, num);
}
}
if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
int N = pkg.getInstrumentations().size();
if (N > 0) {
info.instrumentation = new InstrumentationInfo[N];
for (int i = 0; i < N; i++) {
info.instrumentation[i] = generateInstrumentationInfo(
pkg.getInstrumentations().get(i), pkg, flags, userId,
true /* assignUserFields */);
}
}
}
return info;
}
@Nullable
public static PackageInfo generateWithoutComponents(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
return generateWithoutComponentsUnchecked(pkg, gids, flags, firstInstallTime,
lastUpdateTime, grantedPermissions, state, userId, apexInfo, applicationInfo);
}
/**
* This bypasses critical checks that are necessary for usage with data passed outside of system
* server.
* <p>
* Prefer {@link #generateWithoutComponents(ParsingPackageRead, int[], int, long, long, Set,
* PackageUserState, int, ApexInfo, ApplicationInfo)}.
*/
@NonNull
public static PackageInfo generateWithoutComponentsUnchecked(ParsingPackageRead pkg, int[] gids,
@PackageManager.PackageInfoFlagsBits long flags, long firstInstallTime,
long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state,
int userId, @Nullable ApexInfo apexInfo, @NonNull ApplicationInfo applicationInfo) {
PackageInfo pi = new PackageInfo();
pi.packageName = pkg.getPackageName();
pi.splitNames = pkg.getSplitNames();
pi.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
pi.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
pi.baseRevisionCode = pkg.getBaseRevisionCode();
pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
pi.versionName = pkg.getVersionName();
pi.sharedUserId = pkg.getSharedUserId();
pi.sharedUserLabel = pkg.getSharedUserLabel();
pi.applicationInfo = applicationInfo;
pi.installLocation = pkg.getInstallLocation();
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = pkg.isRequiredForAllUsers();
}
pi.restrictedAccountType = pkg.getRestrictedAccountType();
pi.requiredAccountType = pkg.getRequiredAccountType();
pi.overlayTarget = pkg.getOverlayTarget();
pi.targetOverlayableName = pkg.getOverlayTargetOverlayableName();
pi.overlayCategory = pkg.getOverlayCategory();
pi.overlayPriority = pkg.getOverlayPriority();
pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
pi.compileSdkVersion = pkg.getCompileSdkVersion();
pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
pi.firstInstallTime = firstInstallTime;
pi.lastUpdateTime = lastUpdateTime;
if ((flags & PackageManager.GET_GIDS) != 0) {
pi.gids = gids;
}
if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
int size = pkg.getConfigPreferences().size();
if (size > 0) {
pi.configPreferences = new ConfigurationInfo[size];
pkg.getConfigPreferences().toArray(pi.configPreferences);
}
size = pkg.getRequestedFeatures().size();
if (size > 0) {
pi.reqFeatures = new FeatureInfo[size];
pkg.getRequestedFeatures().toArray(pi.reqFeatures);
}
size = pkg.getFeatureGroups().size();
if (size > 0) {
pi.featureGroups = new FeatureGroupInfo[size];
pkg.getFeatureGroups().toArray(pi.featureGroups);
}
}
if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
int size = ArrayUtils.size(pkg.getPermissions());
if (size > 0) {
pi.permissions = new PermissionInfo[size];
for (int i = 0; i < size; i++) {
pi.permissions[i] = generatePermissionInfo(pkg.getPermissions().get(i),
flags);
}
}
final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
size = usesPermissions.size();
if (size > 0) {
pi.requestedPermissions = new String[size];
pi.requestedPermissionsFlags = new int[size];
for (int i = 0; i < size; i++) {
final ParsedUsesPermission usesPermission = usesPermissions.get(i);
pi.requestedPermissions[i] = usesPermission.getName();
// The notion of required permissions is deprecated but for compatibility.
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_REQUIRED;
if (grantedPermissions != null
&& grantedPermissions.contains(usesPermission.getName())) {
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_GRANTED;
}
if ((usesPermission.getUsesPermissionFlags()
& ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
}
if (pkg.getImplicitPermissions().contains(pi.requestedPermissions[i])) {
pi.requestedPermissionsFlags[i] |=
PackageInfo.REQUESTED_PERMISSION_IMPLICIT;
}
}
}
}
if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
int size = ArrayUtils.size(pkg.getAttributions());
if (size > 0) {
pi.attributions = new Attribution[size];
for (int i = 0; i < size; i++) {
pi.attributions[i] = generateAttribution(pkg.getAttributions().get(i));
}
}
if (pkg.areAttributionsUserVisible()) {
pi.applicationInfo.privateFlagsExt
|= ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
} else {
pi.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
} else {
pi.applicationInfo.privateFlagsExt
&= ~ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE;
}
if (apexInfo != null) {
File apexFile = new File(apexInfo.modulePath);
pi.applicationInfo.sourceDir = apexFile.getPath();
pi.applicationInfo.publicSourceDir = apexFile.getPath();
pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
if (apexInfo.isFactory) {
pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
} else {
pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
pi.isApex = true;
pi.isActiveApex = apexInfo.isActive;
}
final SigningDetails signingDetails = pkg.getSigningDetails();
// deprecated method of getting signing certificates
if ((flags & PackageManager.GET_SIGNATURES) != 0) {
if (signingDetails.hasPastSigningCertificates()) {
// Package has included signing certificate rotation information. Return the oldest
// cert so that programmatic checks keep working even if unaware of key rotation.
pi.signatures = new Signature[1];
pi.signatures[0] = signingDetails.getPastSigningCertificates()[0];
} else if (signingDetails.hasSignatures()) {
// otherwise keep old behavior
int numberOfSigs = signingDetails.getSignatures().length;
pi.signatures = new Signature[numberOfSigs];
System.arraycopy(signingDetails.getSignatures(), 0, pi.signatures, 0,
numberOfSigs);
}
}
// replacement for GET_SIGNATURES
if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
if (signingDetails != SigningDetails.UNKNOWN) {
// only return a valid SigningInfo if there is signing information to report
pi.signingInfo = new SigningInfo(signingDetails);
} else {
pi.signingInfo = null;
}
}
return pi;
}
@Nullable
public static ApplicationInfo generateApplicationInfo(ParsingPackageRead pkg,
@PackageManager.ApplicationInfoFlagsBits long flags, PackageUserState state,
int userId) {
if (pkg == null) {
return null;
}
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
return generateApplicationInfoUnchecked(pkg, flags, state, userId,
true /* assignUserFields */);
}
/**
* This bypasses critical checks that are necessary for usage with data passed outside of system
* server.
* <p>
* Prefer {@link #generateApplicationInfo(ParsingPackageRead, int, PackageUserState, int)}.
*
* @param assignUserFields whether to fill the returned {@link ApplicationInfo} with user
* specific fields. This can be skipped when building from a system
* server package, as there are cached strings which can be used rather
* than querying and concatenating the comparatively expensive {@link
* Environment#getDataDirectory(String)}}.
*/
@NonNull
public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
@PackageManager.ApplicationInfoFlagsBits long flags,
@NonNull PackageUserState state, int userId, boolean assignUserFields) {
// Make shallow copy so we can store the metadata/libraries safely
ApplicationInfo ai = ((ParsingPackageHidden) pkg).toAppInfoWithoutState();
if (assignUserFields) {
assignUserFields(pkg, ai, userId);
}
updateApplicationInfo(ai, flags, state);
return ai;
}
private static void updateApplicationInfo(ApplicationInfo ai, long flags,
PackageUserState state) {
if ((flags & PackageManager.GET_META_DATA) == 0) {
ai.metaData = null;
}
if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) == 0) {
ai.sharedLibraryFiles = null;
ai.sharedLibraryInfos = null;
}
// CompatibilityMode is global state.
if (!ParsingPackageUtils.sCompatibilityModeEnabled) {
ai.disableCompatibilityMode();
}
ai.flags |= flag(state.isStopped(), ApplicationInfo.FLAG_STOPPED)
| flag(state.isInstalled(), ApplicationInfo.FLAG_INSTALLED)
| flag(state.isSuspended(), ApplicationInfo.FLAG_SUSPENDED);
ai.privateFlags |= flag(state.isInstantApp(), ApplicationInfo.PRIVATE_FLAG_INSTANT)
| flag(state.isVirtualPreload(), ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD)
| flag(state.isHidden(), ApplicationInfo.PRIVATE_FLAG_HIDDEN);
if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
ai.enabled = true;
} else if (state.getEnabledState()
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
} else if (state.getEnabledState() == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state.getEnabledState()
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
ai.enabled = false;
}
ai.enabledSetting = state.getEnabledState();
if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
final OverlayPaths overlayPaths = state.getAllOverlayPaths();
if (overlayPaths != null) {
ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
ai.overlayPaths = overlayPaths.getOverlayPaths().toArray(new String[0]);
}
}
@Nullable
public static ApplicationInfo generateDelegateApplicationInfo(@Nullable ApplicationInfo ai,
@PackageManager.ApplicationInfoFlagsBits long flags,
@NonNull PackageUserState state, int userId) {
if (ai == null || !checkUseInstalledOrHidden(flags, state, ai)) {
return null;
}
// This is used to return the ResolverActivity or instantAppInstallerActivity;
// we will just always make a copy.
ai = new ApplicationInfo(ai);
ai.initForUser(userId);
ai.icon = (ParsingPackageUtils.sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes
: ai.iconRes;
updateApplicationInfo(ai, flags, state);
return ai;
}
@Nullable
public static ActivityInfo generateDelegateActivityInfo(@Nullable ActivityInfo a,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull PackageUserState state, int userId) {
if (a == null || !checkUseInstalledOrHidden(flags, state, a.applicationInfo)) {
return null;
}
// This is used to return the ResolverActivity or instantAppInstallerActivity;
// we will just always make a copy.
final ActivityInfo ai = new ActivityInfo(a);
ai.applicationInfo =
generateDelegateApplicationInfo(ai.applicationInfo, flags, state, userId);
return ai;
}
@Nullable
public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
@Nullable ApplicationInfo applicationInfo, int userId) {
if (a == null) return null;
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
if (applicationInfo == null) {
applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
}
if (applicationInfo == null) {
return null;
}
return generateActivityInfoUnchecked(a, flags, applicationInfo);
}
/**
* This bypasses critical checks that are necessary for usage with data passed outside of system
* server.
* <p>
* Prefer {@link #generateActivityInfo(ParsingPackageRead, ParsedActivity, long,
* PackageUserState, ApplicationInfo, int)}.
*/
@NonNull
public static ActivityInfo generateActivityInfoUnchecked(@NonNull ParsedActivity a,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull ApplicationInfo applicationInfo) {
// Make shallow copies so we can store the metadata safely
ActivityInfo ai = new ActivityInfo();
assignSharedFieldsForComponentInfo(ai, a);
ai.targetActivity = a.getTargetActivity();
ai.processName = a.getProcessName();
ai.exported = a.isExported();
ai.theme = a.getTheme();
ai.uiOptions = a.getUiOptions();
ai.parentActivityName = a.getParentActivityName();
ai.permission = a.getPermission();
ai.taskAffinity = a.getTaskAffinity();
ai.flags = a.getFlags();
ai.privateFlags = a.getPrivateFlags();
ai.launchMode = a.getLaunchMode();
ai.documentLaunchMode = a.getDocumentLaunchMode();
ai.maxRecents = a.getMaxRecents();
ai.configChanges = a.getConfigChanges();
ai.softInputMode = a.getSoftInputMode();
ai.persistableMode = a.getPersistableMode();
ai.lockTaskLaunchMode = a.getLockTaskLaunchMode();
ai.screenOrientation = a.getScreenOrientation();
ai.resizeMode = a.getResizeMode();
ai.setMaxAspectRatio(a.getMaxAspectRatio());
ai.setMinAspectRatio(a.getMinAspectRatio());
ai.supportsSizeChanges = a.isSupportsSizeChanges();
ai.requestedVrComponent = a.getRequestedVrComponent();
ai.rotationAnimation = a.getRotationAnimation();
ai.colorMode = a.getColorMode();
ai.windowLayout = a.getWindowLayout();
ai.attributionTags = a.getAttributionTags();
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = a.getMetaData();
// Backwards compatibility, coerce to null if empty
ai.metaData = metaData.isEmpty() ? null : metaData;
}
ai.applicationInfo = applicationInfo;
ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
return ai;
}
@Nullable
public static ActivityInfo generateActivityInfo(ParsingPackageRead pkg, ParsedActivity a,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
int userId) {
return generateActivityInfo(pkg, a, flags, state, null, userId);
}
@Nullable
public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
@Nullable ApplicationInfo applicationInfo, int userId) {
if (s == null) return null;
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
if (applicationInfo == null) {
applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
}
if (applicationInfo == null) {
return null;
}
return generateServiceInfoUnchecked(s, flags, applicationInfo);
}
/**
* This bypasses critical checks that are necessary for usage with data passed outside of system
* server.
* <p>
* Prefer {@link #generateServiceInfo(ParsingPackageRead, ParsedService, long, PackageUserState,
* ApplicationInfo, int)}.
*/
@NonNull
public static ServiceInfo generateServiceInfoUnchecked(@NonNull ParsedService s,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull ApplicationInfo applicationInfo) {
// Make shallow copies so we can store the metadata safely
ServiceInfo si = new ServiceInfo();
assignSharedFieldsForComponentInfo(si, s);
si.exported = s.isExported();
si.flags = s.getFlags();
si.permission = s.getPermission();
si.processName = s.getProcessName();
si.mForegroundServiceType = s.getForegroundServiceType();
si.applicationInfo = applicationInfo;
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = s.getMetaData();
// Backwards compatibility, coerce to null if empty
si.metaData = metaData.isEmpty() ? null : metaData;
}
return si;
}
@Nullable
public static ServiceInfo generateServiceInfo(ParsingPackageRead pkg, ParsedService s,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
int userId) {
return generateServiceInfo(pkg, s, flags, state, null, userId);
}
@Nullable
public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
@Nullable ApplicationInfo applicationInfo, int userId) {
if (p == null) return null;
if (!checkUseInstalled(pkg, state, flags)) {
return null;
}
if (applicationInfo == null) {
applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
}
if (applicationInfo == null) {
return null;
}
return generateProviderInfoUnchecked(p, flags, applicationInfo);
}
/**
* This bypasses critical checks that are necessary for usage with data passed outside of system
* server.
* <p>
* Prefer {@link #generateProviderInfo(ParsingPackageRead, ParsedProvider, long,
* PackageUserState, ApplicationInfo, int)}.
*/
@NonNull
public static ProviderInfo generateProviderInfoUnchecked(@NonNull ParsedProvider p,
@PackageManager.ComponentInfoFlagsBits long flags,
@NonNull ApplicationInfo applicationInfo) {
// Make shallow copies so we can store the metadata safely
ProviderInfo pi = new ProviderInfo();
assignSharedFieldsForComponentInfo(pi, p);
pi.exported = p.isExported();
pi.flags = p.getFlags();
pi.processName = p.getProcessName();
pi.authority = p.getAuthority();
pi.isSyncable = p.isSyncable();
pi.readPermission = p.getReadPermission();
pi.writePermission = p.getWritePermission();
pi.grantUriPermissions = p.isGrantUriPermissions();
pi.forceUriPermissions = p.isForceUriPermissions();
pi.multiprocess = p.isMultiProcess();
pi.initOrder = p.getInitOrder();
pi.uriPermissionPatterns = p.getUriPermissionPatterns().toArray(new PatternMatcher[0]);
pi.pathPermissions = p.getPathPermissions().toArray(new PathPermission[0]);
if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
pi.uriPermissionPatterns = null;
}
if ((flags & PackageManager.GET_META_DATA) != 0) {
var metaData = p.getMetaData();
// Backwards compatibility, coerce to null if empty
pi.metaData = metaData.isEmpty() ? null : metaData;
}
pi.applicationInfo = applicationInfo;
return pi;
}
@Nullable
public static ProviderInfo generateProviderInfo(ParsingPackageRead pkg, ParsedProvider p,
@PackageManager.ComponentInfoFlagsBits long flags, PackageUserState state,
int userId) {
return generateProviderInfo(pkg, p, flags, state, null, userId);
}
/**
* @param assignUserFields see {@link #generateApplicationInfoUnchecked(ParsingPackageRead,
* long, PackageUserState, int, boolean)}
*/
@Nullable
public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
ParsingPackageRead pkg, @PackageManager.ComponentInfoFlagsBits long flags, int userId,
boolean assignUserFields) {
if (i == null) return null;
InstrumentationInfo ii = new InstrumentationInfo();
assignSharedFieldsForPackageItemInfo(ii, i);
ii.targetPackage = i.getTargetPackage();
ii.targetProcesses = i.getTargetProcesses();
ii.handleProfiling = i.isHandleProfiling();
ii.functionalTest = i.isFunctionalTest();
ii.sourceDir = pkg.getBaseApkPath();
ii.publicSourceDir = pkg.getBaseApkPath();
ii.splitNames = pkg.getSplitNames();
ii.splitSourceDirs = pkg.getSplitCodePaths().length == 0 ? null : pkg.getSplitCodePaths();
ii.splitPublicSourceDirs = pkg.getSplitCodePaths().length == 0
? null : pkg.getSplitCodePaths();
ii.splitDependencies = pkg.getSplitDependencies().size() == 0
? null : pkg.getSplitDependencies();
if (assignUserFields) {
assignUserFields(pkg, ii, userId);
}
if ((flags & PackageManager.GET_META_DATA) == 0) {
return ii;
}
var metaData = i.getMetaData();
// Backwards compatibility, coerce to null if empty
ii.metaData = metaData.isEmpty() ? null : metaData;
return ii;
}
@Nullable
public static PermissionInfo generatePermissionInfo(ParsedPermission p,
@PackageManager.ComponentInfoFlagsBits long flags) {
if (p == null) return null;
PermissionInfo pi = new PermissionInfo(p.getBackgroundPermission());
assignSharedFieldsForPackageItemInfo(pi, p);
pi.group = p.getGroup();
pi.requestRes = p.getRequestRes();
pi.protectionLevel = p.getProtectionLevel();
pi.descriptionRes = p.getDescriptionRes();
pi.flags = p.getFlags();
pi.knownCerts = p.getKnownCerts();
if ((flags & PackageManager.GET_META_DATA) == 0) {
return pi;
}
var metaData = p.getMetaData();
// Backwards compatibility, coerce to null if empty
pi.metaData = metaData.isEmpty() ? null : metaData;
return pi;
}
@Nullable
public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
@PackageManager.ComponentInfoFlagsBits long flags) {
if (pg == null) return null;
PermissionGroupInfo pgi = new PermissionGroupInfo(
pg.getRequestDetailRes(),
pg.getBackgroundRequestRes(),
pg.getBackgroundRequestDetailRes()
);
assignSharedFieldsForPackageItemInfo(pgi, pg);
pgi.descriptionRes = pg.getDescriptionRes();
pgi.priority = pg.getPriority();
pgi.requestRes = pg.getRequestRes();
pgi.flags = pg.getFlags();
if ((flags & PackageManager.GET_META_DATA) == 0) {
return pgi;
}
var metaData = pg.getMetaData();
// Backwards compatibility, coerce to null if empty
pgi.metaData = metaData.isEmpty() ? null : metaData;
return pgi;
}
@Nullable
public static Attribution generateAttribution(ParsedAttribution pa) {
if (pa == null) return null;
return new Attribution(pa.getTag(), pa.getLabel());
}
private static boolean checkUseInstalledOrHidden(long flags,
@NonNull PackageUserState state, @Nullable ApplicationInfo appInfo) {
// Returns false if the package is hidden system app until installed.
if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
&& !state.isInstalled()
&& appInfo != null && appInfo.hiddenUntilInstalled) {
return false;
}
// If available for the target user, or trying to match uninstalled packages and it's
// a system app.
return PackageUserStateUtils.isAvailable(state, flags)
|| (appInfo != null && appInfo.isSystemApp()
&& ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
|| (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
}
private static void assignSharedFieldsForComponentInfo(@NonNull ComponentInfo componentInfo,
@NonNull ParsedMainComponent mainComponent) {
assignSharedFieldsForPackageItemInfo(componentInfo, mainComponent);
componentInfo.descriptionRes = mainComponent.getDescriptionRes();
componentInfo.directBootAware = mainComponent.isDirectBootAware();
componentInfo.enabled = mainComponent.isEnabled();
componentInfo.splitName = mainComponent.getSplitName();
componentInfo.attributionTags = mainComponent.getAttributionTags();
}
private static void assignSharedFieldsForPackageItemInfo(
@NonNull PackageItemInfo packageItemInfo, @NonNull ParsedComponent component) {
packageItemInfo.nonLocalizedLabel = ComponentParseUtils.getNonLocalizedLabel(component);
packageItemInfo.icon = ComponentParseUtils.getIcon(component);
packageItemInfo.banner = component.getBanner();
packageItemInfo.labelRes = component.getLabelRes();
packageItemInfo.logo = component.getLogo();
packageItemInfo.name = component.getName();
packageItemInfo.packageName = component.getPackageName();
}
@CheckResult
private static int flag(boolean hasFlag, int flag) {
if (hasFlag) {
return flag;
} else {
return 0;
}
}
/**
* @see ApplicationInfo#flags
*/
public static int appInfoFlags(ParsingPackageRead pkg) {
// @formatter:off
return flag(pkg.isExternalStorage(), ApplicationInfo.FLAG_EXTERNAL_STORAGE)
| flag(pkg.isBaseHardwareAccelerated(), ApplicationInfo.FLAG_HARDWARE_ACCELERATED)
| flag(pkg.isAllowBackup(), ApplicationInfo.FLAG_ALLOW_BACKUP)
| flag(pkg.isKillAfterRestore(), ApplicationInfo.FLAG_KILL_AFTER_RESTORE)
| flag(pkg.isRestoreAnyVersion(), ApplicationInfo.FLAG_RESTORE_ANY_VERSION)
| flag(pkg.isFullBackupOnly(), ApplicationInfo.FLAG_FULL_BACKUP_ONLY)
| flag(pkg.isPersistent(), ApplicationInfo.FLAG_PERSISTENT)
| flag(pkg.isDebuggable(), ApplicationInfo.FLAG_DEBUGGABLE)
| flag(pkg.isVmSafeMode(), ApplicationInfo.FLAG_VM_SAFE_MODE)
| flag(pkg.isHasCode(), ApplicationInfo.FLAG_HAS_CODE)
| flag(pkg.isAllowTaskReparenting(), ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
| flag(pkg.isAllowClearUserData(), ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)
| flag(pkg.isLargeHeap(), ApplicationInfo.FLAG_LARGE_HEAP)
| flag(pkg.isUsesCleartextTraffic(), ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC)
| flag(pkg.isSupportsRtl(), ApplicationInfo.FLAG_SUPPORTS_RTL)
| flag(pkg.isTestOnly(), ApplicationInfo.FLAG_TEST_ONLY)
| flag(pkg.isMultiArch(), ApplicationInfo.FLAG_MULTIARCH)
| flag(pkg.isExtractNativeLibs(), ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS)
| flag(pkg.isGame(), ApplicationInfo.FLAG_IS_GAME)
| flag(pkg.isSupportsSmallScreens(), ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS)
| flag(pkg.isSupportsNormalScreens(), ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS)
| flag(pkg.isSupportsLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS)
| flag(pkg.isSupportsExtraLargeScreens(), ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)
| flag(pkg.isResizeable(), ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS)
| flag(pkg.isAnyDensity(), ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES);
// @formatter:on
}
/** @see ApplicationInfo#privateFlags */
public static int appInfoPrivateFlags(ParsingPackageRead pkg) {
// @formatter:off
int privateFlags = flag(pkg.isStaticSharedLibrary(), ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY)
| flag(pkg.isOverlay(), ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY)
| flag(pkg.isIsolatedSplitLoading(), ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING)
| flag(pkg.isHasDomainUrls(), ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS)
| flag(pkg.isProfileableByShell(), ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL)
| flag(pkg.isBackupInForeground(), ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND)
| flag(pkg.isUseEmbeddedDex(), ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX)
| flag(pkg.isDefaultToDeviceProtectedStorage(), ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
| flag(pkg.isDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE)
| flag(pkg.isPartiallyDirectBootAware(), ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE)
| flag(pkg.isAllowClearUserDataOnFailedRestore(), ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE)
| flag(pkg.isAllowAudioPlaybackCapture(), ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE)
| flag(pkg.isRequestLegacyExternalStorage(), ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE)
| flag(pkg.isUsesNonSdkApi(), ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API)
| flag(pkg.isHasFragileUserData(), ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA)
| flag(pkg.isCantSaveState(), ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
| flag(pkg.isResizeableActivityViaSdkVersion(), ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
| flag(pkg.isAllowNativeHeapPointerTagging(), ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING);
// @formatter:on
Boolean resizeableActivity = pkg.getResizeableActivity();
if (resizeableActivity != null) {
if (resizeableActivity) {
privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
} else {
privateFlags |= ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
}
}
return privateFlags;
}
/** @see ApplicationInfo#privateFlagsExt */
public static int appInfoPrivateFlagsExt(ParsingPackageRead pkg) {
// @formatter:off
int privateFlagsExt =
flag(pkg.isProfileable(), ApplicationInfo.PRIVATE_FLAG_EXT_PROFILEABLE)
| flag(pkg.hasRequestForegroundServiceExemption(),
ApplicationInfo.PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION)
| flag(pkg.areAttributionsUserVisible(),
ApplicationInfo.PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE)
| flag(pkg.isOnBackInvokedCallbackEnabled(),
ApplicationInfo.PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK);
// @formatter:on
return privateFlagsExt;
}
private static boolean checkUseInstalled(ParsingPackageRead pkg,
PackageUserState state, @PackageManager.PackageInfoFlagsBits long flags) {
// If available for the target user
return PackageUserStateUtils.isAvailable(state, flags);
}
@NonNull
public static File getDataDir(ParsingPackageRead pkg, int userId) {
if ("android".equals(pkg.getPackageName())) {
return Environment.getDataSystemDirectory();
}
if (pkg.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
return getDeviceProtectedDataDir(pkg, userId);
} else {
return getCredentialProtectedDataDir(pkg, userId);
}
}
@NonNull
public static File getDeviceProtectedDataDir(ParsingPackageRead pkg, int userId) {
return Environment.getDataUserDePackageDirectory(pkg.getVolumeUuid(), userId,
pkg.getPackageName());
}
@NonNull
public static File getCredentialProtectedDataDir(ParsingPackageRead pkg, int userId) {
return Environment.getDataUserCePackageDirectory(pkg.getVolumeUuid(), userId,
pkg.getPackageName());
}
private static void assignUserFields(ParsingPackageRead pkg, ApplicationInfo info, int userId) {
// This behavior is undefined for no-state ApplicationInfos when called by a public API,
// since the uid is never assigned by the system. It will always effectively be appId 0.
info.uid = UserHandle.getUid(userId, UserHandle.getAppId(info.uid));
String pkgName = pkg.getPackageName();
if ("android".equals(pkgName)) {
info.dataDir = SYSTEM_DATA_PATH;
return;
}
// For performance reasons, all these paths are built as strings
String baseDataDirPrefix =
Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator;
String userIdPkgSuffix = File.separator + userId + File.separator + pkgName;
info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE
+ userIdPkgSuffix;
info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix;
if (pkg.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
info.dataDir = info.deviceProtectedDataDir;
} else {
info.dataDir = info.credentialProtectedDataDir;
}
}
private static void assignUserFields(ParsingPackageRead pkg, InstrumentationInfo info,
int userId) {
String pkgName = pkg.getPackageName();
if ("android".equals(pkgName)) {
info.dataDir = SYSTEM_DATA_PATH;
return;
}
// For performance reasons, all these paths are built as strings
String baseDataDirPrefix =
Environment.getDataDirectoryPath(pkg.getVolumeUuid()) + File.separator;
String userIdPkgSuffix = File.separator + userId + File.separator + pkgName;
info.credentialProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_CE
+ userIdPkgSuffix;
info.deviceProtectedDataDir = baseDataDirPrefix + Environment.DIR_USER_DE + userIdPkgSuffix;
if (pkg.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
info.dataDir = info.deviceProtectedDataDir;
} else {
info.dataDir = info.credentialProtectedDataDir;
}
}
}

View File

@@ -24,12 +24,15 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager.Property;
import android.content.pm.PackageManager;
import android.content.pm.SigningDetails;
import android.os.Bundle;
import android.util.ArraySet;
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.R;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedApexSystemService;
import com.android.server.pm.pkg.component.ParsedAttribution;
@@ -43,6 +46,7 @@ import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import java.security.PublicKey;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -52,7 +56,7 @@ import java.util.Set;
* @hide
*/
@SuppressWarnings("UnusedReturnValue")
public interface ParsingPackage extends ParsingPackageRead {
public interface ParsingPackage {
ParsingPackage addActivity(ParsedActivity parsedActivity);
@@ -83,7 +87,7 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage addPreferredActivityFilter(String className, ParsedIntentInfo intentInfo);
/** Add a property to the application scope */
ParsingPackage addProperty(Property property);
ParsingPackage addProperty(PackageManager.Property property);
ParsingPackage addProtectedBroadcast(String protectedBroadcast);
@@ -391,8 +395,139 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage setOnBackInvokedCallbackEnabled(boolean enableOnBackInvokedCallback);
// TODO(b/135203078): This class no longer has access to ParsedPackage, find a replacement
// for moving to the next step
@CallSuper
Object hideAsParsed();
ParsedPackage hideAsParsed();
// The remaining methods are copied out of [AndroidPackage] so that the parsing variant does
// not implement the final API interface and can't accidentally be used without finalizing
// the parsing process.
@NonNull
List<ParsedActivity> getActivities();
@NonNull
List<ParsedAttribution> getAttributions();
@NonNull
String getBaseApkPath();
@Nullable
String getClassLoaderName();
@NonNull
List<ConfigurationInfo> getConfigPreferences();
@NonNull
List<ParsedInstrumentation> getInstrumentations();
@NonNull
Map<String, ArraySet<PublicKey>> getKeySetMapping();
@NonNull
List<String> getLibraryNames();
float getMaxAspectRatio();
int getMaxSdkVersion();
@Nullable
Bundle getMetaData();
float getMinAspectRatio();
int getMinSdkVersion();
String getPackageName();
@Nullable
String getPermission();
@NonNull
List<ParsedPermission> getPermissions();
@NonNull
String getProcessName();
@NonNull
List<ParsedProvider> getProviders();
@NonNull
List<String> getRequestedPermissions();
@Nullable
Boolean getResizeableActivity();
@Nullable
String getSdkLibName();
@NonNull
List<ParsedService> getServices();
@Nullable
String getSharedUserId();
@NonNull
String[] getSplitCodePaths();
@NonNull
String[] getSplitNames();
@Nullable
String getStaticSharedLibName();
int getTargetSdkVersion();
@Nullable
String getTaskAffinity();
int getUiOptions();
@NonNull
List<String> getUsesLibraries();
@NonNull
List<String> getUsesNativeLibraries();
@NonNull
List<ParsedUsesPermission> getUsesPermissions();
@NonNull
List<String> getUsesSdkLibraries();
@Nullable
long[] getUsesSdkLibrariesVersionsMajor();
@NonNull
List<String> getUsesStaticLibraries();
@Nullable
String getZygotePreloadName();
boolean isAllowBackup();
boolean isAllowTaskReparenting();
boolean isAnyDensity();
boolean isBaseHardwareAccelerated();
boolean isCantSaveState();
boolean isProfileable();
boolean isProfileableByShell();
boolean isResizeable();
boolean isResizeableActivityViaSdkVersion();
boolean isStaticSharedLibrary();
boolean isSupportsExtraLargeScreens();
boolean isSupportsLargeScreens();
boolean isSupportsNormalScreens();
boolean isSupportsSmallScreens();
}

View File

@@ -23,12 +23,12 @@ import android.content.pm.PackageInfo;
* Methods that normal consumers should not have access to. This usually means the field is stateful
* or deprecated and should be access through a utility class or a system manager class.
* <p>
* This is a separate interface, not implemented by the base {@link ParsingPackageRead} because Java
* This is a separate interface, not implemented by the base {@link ParsingPackage} because Java
* doesn't support non-public interface methods. The class must be cast to this interface.
*
* @hide
*/
interface ParsingPackageHidden {
public interface ParsingPackageHidden {
/**
* @see PackageInfo#versionCode

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2022 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.parsing;
import android.annotation.Nullable;
import android.content.pm.PackageInfo;
import com.android.internal.R;
/**
* Methods which would've been a part of {@link PkgWithoutStatePackageInfo} or {@link
* PkgWithoutStateAppInfo}, but are removed/deprecated.
* <p>
* This is different from {@link ParsingPackageHidden}. The methods in that interface cannot be
* accessed by anyone except the parsing utilities, whereas the methods in this interface are valid
* and can be accessed by any internal caller that needs it.
*
* @hide
*/
interface ParsingPackageInternal {
/**
* @see PackageInfo#overlayCategory
* @see R.styleable#AndroidManifestResourceOverlay_category
*/
@Nullable
String getOverlayCategory();
/**
* @see PackageInfo#overlayPriority
* @see R.styleable#AndroidManifestResourceOverlay_priority
*/
int getOverlayPriority();
/**
* @see PackageInfo#overlayTarget
* @see R.styleable#AndroidManifestResourceOverlay_targetPackage
*/
@Nullable
String getOverlayTarget();
/**
* @see PackageInfo#targetOverlayableName
* @see R.styleable#AndroidManifestResourceOverlay_targetName
*/
@Nullable
String getOverlayTargetOverlayableName();
/**
* @see PackageInfo#mOverlayIsStatic
*/
boolean isOverlayIsStatic();
}

View File

@@ -1,366 +0,0 @@
/*
* Copyright (C) 2022 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.parsing;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.Property;
import android.content.pm.SigningDetails;
import android.os.Bundle;
import android.util.ArraySet;
import android.util.Pair;
import android.util.SparseIntArray;
import com.android.server.pm.pkg.component.ParsedApexSystemService;
import com.android.server.pm.pkg.component.ParsedAttribution;
import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedPermissionGroup;
import com.android.server.pm.pkg.component.ParsedProcess;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import java.security.PublicKey;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Everything written by {@link ParsingPackage} and readable back.
*
* @hide
*/
public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutStatePackageInfo,
ParsingPackageInternal {
/**
* The names of packages to adopt ownership of permissions from, parsed under {@link
* ParsingPackageUtils#TAG_ADOPT_PERMISSIONS}.
*
* @see R.styleable#AndroidManifestOriginalPackage_name
*/
@NonNull
List<String> getAdoptPermissions();
/**
* @see R.styleable#AndroidManifestApexSystemService
*/
@NonNull
List<ParsedApexSystemService> getApexSystemServices();
@NonNull
List<ParsedAttribution> getAttributions();
/**
* Permissions requested but not in the manifest. These may have been split or migrated from
* previous versions/definitions.
*/
@NonNull
List<String> getImplicitPermissions();
@NonNull
List<ParsedUsesPermission> getUsesPermissions();
/**
* For use with {@link com.android.server.pm.KeySetManagerService}. Parsed in {@link
* ParsingPackageUtils#TAG_KEY_SETS}.
*
* @see R.styleable#AndroidManifestKeySet
* @see R.styleable#AndroidManifestPublicKey
*/
@NonNull
Map<String, ArraySet<PublicKey>> getKeySetMapping();
/**
* Library names this package is declared as, for use by other packages with "uses-library".
*
* @see R.styleable#AndroidManifestLibrary
*/
@NonNull
List<String> getLibraryNames();
/**
* TODO(b/135203078): Make all the Bundles immutable (and non-null by shared empty reference?)
*/
@Nullable
Bundle getMetaData();
@Nullable
Set<String> getMimeGroups();
/**
* @see R.styleable#AndroidManifestExtensionSdk
*/
@Nullable
SparseIntArray getMinExtensionVersions();
/**
* For system use to migrate from an old package name to a new one, moving over data if
* available.
*
* @see R.styleable#AndroidManifestOriginalPackage}
*/
@NonNull
List<String> getOriginalPackages();
/**
* Map of overlayable name to actor name.
*/
@NonNull
Map<String, String> getOverlayables();
/**
* @see android.content.pm.PermissionGroupInfo
*/
@NonNull
List<ParsedPermissionGroup> getPermissionGroups();
/**
* Used to determine the default preferred handler of an {@link Intent}.
* <p>
* Map of component className to intent info inside that component. TODO(b/135203078): Is this
* actually used/working?
*/
@NonNull
List<Pair<String, ParsedIntentInfo>> getPreferredActivityFilters();
/**
* @see android.content.pm.ProcessInfo
*/
@NonNull
Map<String, ParsedProcess> getProcesses();
/**
* System protected broadcasts.
*
* @see R.styleable#AndroidManifestProtectedBroadcast
*/
@NonNull
List<String> getProtectedBroadcasts();
/**
* Intents that this package may query or require and thus requires visibility into.
*
* @see R.styleable#AndroidManifestQueriesIntent
*/
@NonNull
List<Intent> getQueriesIntents();
/**
* Other packages that this package may query or require and thus requires visibility into.
*
* @see R.styleable#AndroidManifestQueriesPackage
*/
@NonNull
List<String> getQueriesPackages();
/**
* Authorities that this package may query or require and thus requires visibility into.
*
* @see R.styleable#AndroidManifestQueriesProvider
*/
@NonNull
Set<String> getQueriesProviders();
/**
* SHA-512 hash of the only APK that can be used to update a system package.
*
* @see R.styleable#AndroidManifestRestrictUpdate
*/
@Nullable
byte[] getRestrictUpdateHash();
/**
* The signature data of all APKs in this package, which must be exactly the same across the
* base and splits.
*/
@NonNull
SigningDetails getSigningDetails();
/**
* Returns the properties set on the application
*/
@NonNull
Map<String, Property> getProperties();
/**
* Flags of any split APKs; ordered by parsed splitName
*/
@Nullable
int[] getSplitFlags();
/**
* @see R.styleable#AndroidManifestSdkLibrary_name
*/
@Nullable
String getSdkLibName();
/**
* @see R.styleable#AndroidManifestSdkLibrary_versionMajor
*/
int getSdkLibVersionMajor();
/**
* @see R.styleable#AndroidManifestStaticLibrary_name
*/
@Nullable
String getStaticSharedLibName();
/**
* @see R.styleable#AndroidManifestStaticLibrary_version
*/
long getStaticSharedLibVersion();
/**
* For use with {@link com.android.server.pm.KeySetManagerService}. Parsed in {@link
* ParsingPackageUtils#TAG_KEY_SETS}.
*
* @see R.styleable#AndroidManifestUpgradeKeySet
*/
@NonNull
Set<String> getUpgradeKeySets();
/**
* @see R.styleable#AndroidManifestUsesLibrary
*/
@NonNull
List<String> getUsesLibraries();
/**
* @see R.styleable#AndroidManifestUsesNativeLibrary
*/
@NonNull
List<String> getUsesNativeLibraries();
/**
* Like {@link #getUsesLibraries()}, but marked optional by setting {@link
* R.styleable#AndroidManifestUsesLibrary_required} to false . Application is expected to handle
* absence manually.
*
* @see R.styleable#AndroidManifestUsesLibrary
*/
@NonNull
List<String> getUsesOptionalLibraries();
/**
* Like {@link #getUsesNativeLibraries()}, but marked optional by setting {@link
* R.styleable#AndroidManifestUsesNativeLibrary_required} to false . Application is expected to
* handle absence manually.
*
* @see R.styleable#AndroidManifestUsesNativeLibrary
*/
@NonNull
List<String> getUsesOptionalNativeLibraries();
/**
* TODO(b/135203078): Move static library stuff to an inner data class
*
* @see R.styleable#AndroidManifestUsesStaticLibrary
*/
@NonNull
List<String> getUsesStaticLibraries();
/**
* @see R.styleable#AndroidManifestUsesStaticLibrary_certDigest
*/
@Nullable
String[][] getUsesStaticLibrariesCertDigests();
/**
* @see R.styleable#AndroidManifestUsesStaticLibrary_version
*/
@Nullable
long[] getUsesStaticLibrariesVersions();
/**
* TODO(b/135203078): Move SDK library stuff to an inner data class
*
* @see R.styleable#AndroidManifestUsesSdkLibrary
*/
@NonNull
List<String> getUsesSdkLibraries();
/**
* @see R.styleable#AndroidManifestUsesSdkLibrary_certDigest
*/
@Nullable
String[][] getUsesSdkLibrariesCertDigests();
/**
* @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
*/
@Nullable
long[] getUsesSdkLibrariesVersionsMajor();
boolean hasPreserveLegacyExternalStorage();
/**
* @see R.styleable#AndroidManifestApplication_forceQueryable
*/
boolean isForceQueryable();
/**
* @see ApplicationInfo#FLAG_IS_GAME
*/
@Deprecated
boolean isGame();
/**
* The install time abi override to choose 32bit abi's when multiple abi's are present. This is
* only meaningful for multiarch applications. The use32bitAbi attribute is ignored if
* cpuAbiOverride is also set.
*
* @see R.attr#use32bitAbi
*/
boolean isUse32BitAbi();
/**
* Set if the any of components are visible to instant applications.
*
* @see R.styleable#AndroidManifestActivity_visibleToInstantApps
* @see R.styleable#AndroidManifestProvider_visibleToInstantApps
* @see R.styleable#AndroidManifestService_visibleToInstantApps
*/
boolean isVisibleToInstantApps();
/**
* Whether the enabled settings of components in the application should be reset to the default,
* when the application's user data is cleared.
*
* @see R.styleable#AndroidManifestApplication_resetEnabledSettingsOnAppDataCleared
*/
boolean isResetEnabledSettingsOnAppDataCleared();
/**
* The resource ID used to provide the application's locales configuration.
*
* @see R.styleable#AndroidManifestApplication_localeConfig
*/
int getLocaleConfigRes();
/**
* @see R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback
*/
boolean isOnBackInvokedCallbackEnabled();
/**
* Returns true if R.styleable#AndroidManifest_sharedUserMaxSdkVersion is set to a value
* smaller than the current SDK version.
* @see R.styleable#AndroidManifest_sharedUserMaxSdkVersion
*/
boolean isLeavingSharedUid();
}

View File

@@ -91,6 +91,8 @@ import com.android.internal.os.ClassLoaderFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.pm.SharedUidMigration;
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.CompatibilityPermissionInfo;
import com.android.server.pm.pkg.component.ComponentMutateUtils;
import com.android.server.pm.pkg.component.ComponentParseUtils;
@@ -264,7 +266,7 @@ public class ParsingPackageUtils {
* @see #parseDefault(ParseInput, File, int, List, boolean)
*/
@NonNull
public static ParseResult<ParsingPackage> parseDefaultOneTime(File file,
public static ParseResult<ParsedPackage> parseDefaultOneTime(File file,
@ParseFlags int parseFlags,
@NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions,
boolean collectCertificates) {
@@ -278,11 +280,11 @@ public class ParsingPackageUtils {
* feature support.
*/
@NonNull
public static ParseResult<ParsingPackage> parseDefault(ParseInput input, File file,
public static ParseResult<ParsedPackage> parseDefault(ParseInput input, File file,
@ParseFlags int parseFlags,
@NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions,
boolean collectCertificates) {
ParseResult<ParsingPackage> result;
ParseResult<ParsedPackage> result;
ParsingPackageUtils parser = new ParsingPackageUtils(null /*separateProcesses*/,
null /*displayMetrics*/, splitPermissions, new Callback() {
@@ -301,15 +303,17 @@ public class ParsingPackageUtils {
@NonNull String baseApkPath,
@NonNull String path,
@NonNull TypedArray manifestArray, boolean isCoreApp) {
return new ParsingPackageImpl(packageName, baseApkPath, path, manifestArray);
return PackageImpl.forParsing(packageName, baseApkPath, path, manifestArray,
isCoreApp);
}
});
result = parser.parsePackage(input, file, parseFlags, /* frameworkSplits= */ null);
if (result.isError()) {
return input.error(result);
var parseResult = parser.parsePackage(input, file, parseFlags, /* frameworkSplits= */ null);
if (parseResult.isError()) {
return input.error(parseResult);
}
final ParsingPackage pkg = result.getResult();
var pkg = parseResult.getResult().hideAsParsed();
if (collectCertificates) {
final ParseResult<SigningDetails> ret =
ParsingPackageUtils.getSigningDetails(input, pkg, false /*skipVerify*/);
@@ -319,9 +323,6 @@ public class ParsingPackageUtils {
pkg.setSigningDetails(ret.getResult());
}
// Need to call this to finish the parsing stage
pkg.hideAsParsed();
return input.success(pkg);
}
@@ -348,7 +349,7 @@ public class ParsingPackageUtils {
* package name and version codes, a single base APK, and unique split names.
* <p>
* Note that this <em>does not</em> perform signature verification; that must be done separately
* in {@link #getSigningDetails(ParseInput, ParsingPackageRead, boolean)}.
* in {@link #getSigningDetails(ParseInput, ParsedPackage, boolean)}.
* <p>
* If {@code useCaches} is true, the package parser might return a cached result from a previous
* parse of the same {@code packageFile} with the same {@code flags}. Note that this method does
@@ -380,7 +381,7 @@ public class ParsingPackageUtils {
* differences.
* <p>
* Note that this <em>does not</em> perform signature verification; that must be done separately
* in {@link #getSigningDetails(ParseInput, ParsingPackageRead, boolean)}.
* in {@link #getSigningDetails(ParseInput, ParsedPackage, boolean)}.
*/
private ParseResult<ParsingPackage> parseClusterPackage(ParseInput input, File packageDir,
List<File> frameworkSplits, int flags) {
@@ -457,7 +458,7 @@ public class ParsingPackageUtils {
* Parse the given APK file, treating it as as a single monolithic package.
* <p>
* Note that this <em>does not</em> perform signature verification; that must be done separately
* in {@link #getSigningDetails(ParseInput, ParsingPackageRead, boolean)}.
* in {@link #getSigningDetails(ParseInput, ParsedPackage, boolean)}.
*/
private ParseResult<ParsingPackage> parseMonolithicPackage(ParseInput input, File apkFile,
int flags) {
@@ -3067,18 +3068,41 @@ public class ParsingPackageUtils {
*/
@CheckResult
public static ParseResult<SigningDetails> getSigningDetails(ParseInput input,
ParsingPackageRead pkg, boolean skipVerify) {
ParsedPackage pkg, boolean skipVerify) {
return getSigningDetails(input, pkg.getBaseApkPath(), pkg.isStaticSharedLibrary(),
pkg.getTargetSdkVersion(), pkg.getSplitCodePaths(), skipVerify);
}
@CheckResult
private static ParseResult<SigningDetails> getSigningDetails(ParseInput input,
ParsingPackage pkg, boolean skipVerify) {
return getSigningDetails(input, pkg.getBaseApkPath(), pkg.isStaticSharedLibrary(),
pkg.getTargetSdkVersion(), pkg.getSplitCodePaths(), skipVerify);
}
/**
* Collect certificates from all the APKs described in the given package. Also asserts that
* all APK contents are signed correctly and consistently.
*
* TODO(b/155513789): Remove this in favor of collecting certificates during the original parse
* call if requested. Leaving this as an optional method for the caller means we have to
* construct a dummy ParseInput.
*/
@CheckResult
public static ParseResult<SigningDetails> getSigningDetails(ParseInput input,
String baseApkPath, boolean isStaticSharedLibrary, int targetSdkVersion,
String[] splitCodePaths, boolean skipVerify) {
SigningDetails signingDetails = SigningDetails.UNKNOWN;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
ParseResult<SigningDetails> result = getSigningDetails(
input,
pkg.getBaseApkPath(),
baseApkPath,
skipVerify,
pkg.isStaticSharedLibrary(),
isStaticSharedLibrary,
signingDetails,
pkg.getTargetSdkVersion()
targetSdkVersion
);
if (result.isError()) {
return input.error(result);
@@ -3088,17 +3112,16 @@ public class ParsingPackageUtils {
final File frameworkRes = new File(Environment.getRootDirectory(),
"framework/framework-res.apk");
boolean isFrameworkResSplit = frameworkRes.getAbsolutePath()
.equals(pkg.getBaseApkPath());
String[] splitCodePaths = pkg.getSplitCodePaths();
.equals(baseApkPath);
if (!ArrayUtils.isEmpty(splitCodePaths) && !isFrameworkResSplit) {
for (int i = 0; i < splitCodePaths.length; i++) {
result = getSigningDetails(
input,
splitCodePaths[i],
skipVerify,
pkg.isStaticSharedLibrary(),
isStaticSharedLibrary,
signingDetails,
pkg.getTargetSdkVersion()
targetSdkVersion
);
if (result.isError()) {
return input.error(result);
@@ -3312,7 +3335,6 @@ public class ParsingPackageUtils {
return keySetMapping;
}
/**
* Callback interface for retrieving information that may be needed while parsing
* a package.

View File

@@ -1,659 +0,0 @@
/*
* Copyright (C) 2022 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.parsing;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.util.SparseArray;
import java.util.Set;
/**
* Container for fields that are eventually exposed through {@link ApplicationInfo}.
* <p>
* The following are dependent on system state and explicitly removed from this interface. They must
* be accessed by other means:
* <ul>
* <li>{@link ApplicationInfo#credentialProtectedDataDir}</li>
* <li>{@link ApplicationInfo#dataDir}</li>
* <li>{@link ApplicationInfo#deviceProtectedDataDir}</li>
* <li>{@link ApplicationInfo#enabledSetting}</li>
* <li>{@link ApplicationInfo#enabled}</li>
* <li>{@link ApplicationInfo#FLAG_INSTALLED}</li>
* <li>{@link ApplicationInfo#FLAG_STOPPED}</li>
* <li>{@link ApplicationInfo#FLAG_SUSPENDED}</li>
* <li>{@link ApplicationInfo#FLAG_UPDATED_SYSTEM_APP}</li>
* <li>{@link ApplicationInfo#hiddenUntilInstalled}</li>
* <li>{@link ApplicationInfo#primaryCpuAbi}</li>
* <li>{@link ApplicationInfo#PRIVATE_FLAG_HIDDEN}</li>
* <li>{@link ApplicationInfo#PRIVATE_FLAG_INSTANT}</li>
* <li>{@link ApplicationInfo#PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER}</li>
* <li>{@link ApplicationInfo#PRIVATE_FLAG_VIRTUAL_PRELOAD}</li>
* <li>{@link ApplicationInfo#resourceDirs}</li>
* <li>{@link ApplicationInfo#secondaryCpuAbi}</li>
* <li>{@link ApplicationInfo#seInfoUser}</li>
* <li>{@link ApplicationInfo#seInfo}</li>
* <li>{@link ApplicationInfo#sharedLibraryFiles}</li>
* <li>{@link ApplicationInfo#sharedLibraryInfos}</li>
* <li>{@link ApplicationInfo#uid}</li>
* </ul>
* The following are derived from other fields and thus not provided specifically:
* <ul>
* <li>{@link ApplicationInfo#getBaseResourcePath}</li>
* <li>{@link ApplicationInfo#getResourcePath}</li>
* <li>{@link ApplicationInfo#getSplitResourcePaths}</li>
* <li>{@link ApplicationInfo#publicSourceDir}</li>
* <li>{@link ApplicationInfo#scanPublicSourceDir}</li>
* <li>{@link ApplicationInfo#splitPublicSourceDirs}</li>
* <li>{@link ApplicationInfo#storageUuid}</li>
* </ul>
* The following were deprecated at migration time and thus removed from this interface:
* <ul>
* <li>{@link ApplicationInfo#FLAG_IS_GAME}</li>
* <li>{@link ApplicationInfo#targetSandboxVersion}</li>
* <li>{@link ApplicationInfo#versionCode}</li>
* </ul>
* TODO: The following fields are just not available at all. Never filled, even by legacy parsing?
* <ul>
* <li>{@link ApplicationInfo#FLAG_IS_DATA_ONLY}</li>
* </ul>
*
* @hide
*/
public interface PkgWithoutStateAppInfo {
/**
* @see ApplicationInfo#areAttributionsUserVisible()
* @see R.styleable#AndroidManifestApplication_attributionsAreUserVisible
*/
@Nullable
boolean areAttributionsUserVisible();
/**
* @see ApplicationInfo#appComponentFactory
* @see R.styleable#AndroidManifestApplication_appComponentFactory
*/
@Nullable
String getAppComponentFactory();
/**
* @see ApplicationInfo#AUTO_REVOKE_ALLOWED
* @see ApplicationInfo#AUTO_REVOKE_DISCOURAGED
* @see ApplicationInfo#AUTO_REVOKE_DISALLOWED
*/
int getAutoRevokePermissions();
/**
* @see ApplicationInfo#backupAgentName
* @see R.styleable#AndroidManifestApplication_backupAgent
*/
@Nullable
String getBackupAgentName();
/**
* @see ApplicationInfo#banner
* @see R.styleable#AndroidManifestApplication_banner
*/
int getBanner();
/**
* @see ApplicationInfo#sourceDir
* @see ApplicationInfo#getBaseCodePath
*/
@NonNull
String getBaseApkPath();
/**
* @see ApplicationInfo#category
* @see R.styleable#AndroidManifestApplication_appCategory
*/
int getCategory();
/**
* @see ApplicationInfo#classLoaderName
* @see R.styleable#AndroidManifestApplication_classLoader
*/
@Nullable
String getClassLoaderName();
/**
* @see ApplicationInfo#className
* @see R.styleable#AndroidManifestApplication_name
*/
@Nullable
String getClassName();
/**
* @see ApplicationInfo#compatibleWidthLimitDp
* @see R.styleable#AndroidManifestSupportsScreens_compatibleWidthLimitDp
*/
int getCompatibleWidthLimitDp();
/**
* @see ApplicationInfo#compileSdkVersion
* @see R.styleable#AndroidManifest_compileSdkVersion
*/
int getCompileSdkVersion();
/**
* @see ApplicationInfo#compileSdkVersionCodename
* @see R.styleable#AndroidManifest_compileSdkVersionCodename
*/
@Nullable
String getCompileSdkVersionCodeName();
/**
* @see ApplicationInfo#dataExtractionRulesRes
* @see R.styleable#AndroidManifestApplication_dataExtractionRules
*/
int getDataExtractionRules();
/**
* @see ApplicationInfo#descriptionRes
* @see R.styleable#AndroidManifestApplication_description
*/
int getDescriptionRes();
/**
* @see ApplicationInfo#fullBackupContent
* @see R.styleable#AndroidManifestApplication_fullBackupContent
*/
int getFullBackupContent();
/**
* @see ApplicationInfo#getGwpAsanMode()
* @see R.styleable#AndroidManifestApplication_gwpAsanMode
*/
@ApplicationInfo.GwpAsanMode
int getGwpAsanMode();
/**
* @see ApplicationInfo#iconRes
* @see R.styleable#AndroidManifestApplication_icon
*/
int getIconRes();
/**
* @see ApplicationInfo#installLocation
* @see R.styleable#AndroidManifest_installLocation
*/
int getInstallLocation();
/**
* @see ApplicationInfo#labelRes
* @see R.styleable#AndroidManifestApplication_label
*/
int getLabelRes();
/**
* @see ApplicationInfo#largestWidthLimitDp
* @see R.styleable#AndroidManifestSupportsScreens_largestWidthLimitDp
*/
int getLargestWidthLimitDp();
/**
* @see ApplicationInfo#logo
* @see R.styleable#AndroidManifestApplication_logo
*/
int getLogo();
/**
* @see ApplicationInfo#longVersionCode
*/
long getLongVersionCode();
/**
* @see ApplicationInfo#manageSpaceActivityName
* @see R.styleable#AndroidManifestApplication_manageSpaceActivity
*/
@Nullable
String getManageSpaceActivityName();
/**
* @see ApplicationInfo#maxAspectRatio
* @see R.styleable#AndroidManifestApplication_maxAspectRatio
*/
float getMaxAspectRatio();
/**
* @see ApplicationInfo#getMemtagMode()
* @see R.styleable#AndroidManifestApplication_memtagMode
*/
@ApplicationInfo.MemtagMode
int getMemtagMode();
/**
* @see ApplicationInfo#minAspectRatio
* @see R.styleable#AndroidManifestApplication_minAspectRatio
*/
float getMinAspectRatio();
/**
* @see ApplicationInfo#minSdkVersion
* @see R.styleable#AndroidManifestUsesSdk_minSdkVersion
*/
int getMinSdkVersion();
/**
* @see R.styleable#AndroidManifestUsesSdk_maxSdkVersion
*/
int getMaxSdkVersion();
/**
* @see ApplicationInfo#getNativeHeapZeroInitialized()
* @see R.styleable#AndroidManifestApplication_nativeHeapZeroInitialized
*/
@ApplicationInfo.NativeHeapZeroInitialized
int getNativeHeapZeroInitialized();
/**
* @see ApplicationInfo#networkSecurityConfigRes
* @see R.styleable#AndroidManifestApplication_networkSecurityConfig
*/
int getNetworkSecurityConfigRes();
/**
* If {@link R.styleable#AndroidManifestApplication_label} is a string literal, this is it.
* Otherwise, it's stored as {@link #getLabelRes()}.
*
* @see ApplicationInfo#nonLocalizedLabel
* @see R.styleable#AndroidManifestApplication_label
*/
@Nullable
CharSequence getNonLocalizedLabel();
/**
* @see ApplicationInfo#scanSourceDir
* @see ApplicationInfo#getCodePath
*/
@NonNull
String getPath();
/**
* @see ApplicationInfo#permission
* @see R.styleable#AndroidManifestApplication_permission
*/
@Nullable
String getPermission();
/**
* @see ApplicationInfo#knownActivityEmbeddingCerts
* @see R.styleable#AndroidManifestApplication_knownActivityEmbeddingCerts
*/
@NonNull
Set<String> getKnownActivityEmbeddingCerts();
/**
* @see ApplicationInfo#processName
* @see R.styleable#AndroidManifestApplication_process
*/
@NonNull
String getProcessName();
/**
* @see ApplicationInfo#requiresSmallestWidthDp
* @see R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
*/
int getRequiresSmallestWidthDp();
/**
* Whether or not the app requested explicitly resizeable Activities. Null value means nothing
* was explicitly requested.
*
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE
*/
@Nullable
Boolean getResizeableActivity();
/**
* @see ApplicationInfo#roundIconRes
* @see R.styleable#AndroidManifestApplication_roundIcon
*/
int getRoundIconRes();
/**
* @see ApplicationInfo#splitClassLoaderNames
* @see R.styleable#AndroidManifestApplication_classLoader
*/
@Nullable
String[] getSplitClassLoaderNames();
/**
* @see ApplicationInfo#splitSourceDirs
* @see ApplicationInfo#getSplitCodePaths
*/
@NonNull
String[] getSplitCodePaths();
/**
* @see ApplicationInfo#splitDependencies
*/
@NonNull
SparseArray<int[]> getSplitDependencies();
/**
* @see ApplicationInfo#targetSdkVersion
* @see R.styleable#AndroidManifestUsesSdk_targetSdkVersion
*/
int getTargetSdkVersion();
/**
* @see ApplicationInfo#targetSandboxVersion
* @see R.styleable#AndroidManifest_targetSandboxVersion
*/
int getTargetSandboxVersion();
/**
* @see ApplicationInfo#taskAffinity
* @see R.styleable#AndroidManifestApplication_taskAffinity
*/
@Nullable
String getTaskAffinity();
/**
* @see ApplicationInfo#theme
* @see R.styleable#AndroidManifestApplication_theme
*/
int getTheme();
/**
* @see ApplicationInfo#uiOptions
* @see R.styleable#AndroidManifestApplication_uiOptions
*/
int getUiOptions();
/**
* @see ApplicationInfo#volumeUuid
*/
@Nullable
String getVolumeUuid();
/**
* @see ApplicationInfo#zygotePreloadName
*/
@Nullable
String getZygotePreloadName();
/**
* @see ApplicationInfo#PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION
* @see R.styleable#AndroidManifestApplication_requestForegroundServiceExemption
*/
boolean hasRequestForegroundServiceExemption();
/**
* @see ApplicationInfo#getRequestRawExternalStorageAccess()
* @see R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess
*/
Boolean hasRequestRawExternalStorageAccess();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE
*/
boolean isAllowAudioPlaybackCapture();
/**
* @see ApplicationInfo#FLAG_ALLOW_BACKUP
*/
boolean isAllowBackup();
/**
* @see ApplicationInfo#FLAG_ALLOW_CLEAR_USER_DATA
*/
boolean isAllowClearUserData();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE
*/
boolean isAllowClearUserDataOnFailedRestore();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING
*/
boolean isAllowNativeHeapPointerTagging();
/**
* @see ApplicationInfo#FLAG_ALLOW_TASK_REPARENTING
*/
boolean isAllowTaskReparenting();
/**
* If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link
* android.os.Build.VERSION_CODES#DONUT}.
*
* @see R.styleable#AndroidManifestSupportsScreens_anyDensity
* @see ApplicationInfo#FLAG_SUPPORTS_SCREEN_DENSITIES
*/
boolean isAnyDensity();
/**
* @see ApplicationInfo#PRIVATE_FLAG_BACKUP_IN_FOREGROUND
*/
boolean isBackupInForeground();
/**
* @see ApplicationInfo#FLAG_HARDWARE_ACCELERATED
*/
boolean isBaseHardwareAccelerated();
/**
* @see ApplicationInfo#PRIVATE_FLAG_CANT_SAVE_STATE
*/
boolean isCantSaveState();
/**
* @see ApplicationInfo#crossProfile
*/
boolean isCrossProfile();
/**
* @see ApplicationInfo#FLAG_DEBUGGABLE
*/
boolean isDebuggable();
/**
* @see ApplicationInfo#PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE
*/
boolean isDefaultToDeviceProtectedStorage();
/**
* @see ApplicationInfo#PRIVATE_FLAG_DIRECT_BOOT_AWARE
*/
boolean isDirectBootAware();
/**
* @see ApplicationInfo#enabled
* @see R.styleable#AndroidManifestApplication_enabled
*/
boolean isEnabled();
/**
* @see ApplicationInfo#FLAG_EXTERNAL_STORAGE
*/
boolean isExternalStorage();
/**
* @see ApplicationInfo#FLAG_EXTRACT_NATIVE_LIBS
*/
boolean isExtractNativeLibs();
/**
* @see ApplicationInfo#FLAG_FULL_BACKUP_ONLY
*/
boolean isFullBackupOnly();
/**
* @see ApplicationInfo#FLAG_HAS_CODE
*/
boolean isHasCode();
/**
* @see ApplicationInfo#PRIVATE_FLAG_HAS_DOMAIN_URLS
*/
boolean isHasDomainUrls();
/**
* @see ApplicationInfo#PRIVATE_FLAG_HAS_FRAGILE_USER_DATA
*/
boolean isHasFragileUserData();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ISOLATED_SPLIT_LOADING
*/
boolean isIsolatedSplitLoading();
/**
* @see ApplicationInfo#FLAG_KILL_AFTER_RESTORE
*/
boolean isKillAfterRestore();
/**
* @see ApplicationInfo#FLAG_LARGE_HEAP
*/
boolean isLargeHeap();
/**
* @see ApplicationInfo#FLAG_MULTIARCH
*/
boolean isMultiArch();
/**
* @see ApplicationInfo#PRIVATE_FLAG_IS_RESOURCE_OVERLAY
* @see ApplicationInfo#isResourceOverlay()
*/
boolean isOverlay();
/**
* @see ApplicationInfo#PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE
*/
boolean isPartiallyDirectBootAware();
/**
* @see ApplicationInfo#FLAG_PERSISTENT
*/
boolean isPersistent();
/**
* @see ApplicationInfo#PRIVATE_FLAG_EXT_PROFILEABLE
*/
boolean isProfileable();
/**
* @see ApplicationInfo#PRIVATE_FLAG_PROFILEABLE_BY_SHELL
*/
boolean isProfileableByShell();
/**
* @see ApplicationInfo#PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE
*/
boolean isRequestLegacyExternalStorage();
/**
* If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link
* android.os.Build.VERSION_CODES#DONUT}.
*
* @see R.styleable#AndroidManifestSupportsScreens_resizeable
* @see ApplicationInfo#FLAG_RESIZEABLE_FOR_SCREENS
*/
boolean isResizeable();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
*/
boolean isResizeableActivityViaSdkVersion();
/**
* @see ApplicationInfo#FLAG_RESTORE_ANY_VERSION
*/
boolean isRestoreAnyVersion();
/**
* @see ApplicationInfo#PRIVATE_FLAG_STATIC_SHARED_LIBRARY
*/
boolean isStaticSharedLibrary();
/**
* True means that this package/app contains an SDK library.
*/
boolean isSdkLibrary();
/**
* If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link
* android.os.Build.VERSION_CODES#GINGERBREAD}.
*
* @see R.styleable#AndroidManifestSupportsScreens_xlargeScreens
* @see ApplicationInfo#FLAG_SUPPORTS_XLARGE_SCREENS
*/
boolean isSupportsExtraLargeScreens();
/**
* If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link
* android.os.Build.VERSION_CODES#DONUT}.
*
* @see R.styleable#AndroidManifestSupportsScreens_largeScreens
* @see ApplicationInfo#FLAG_SUPPORTS_LARGE_SCREENS
*/
boolean isSupportsLargeScreens();
/**
* If omitted from manifest, returns true.
*
* @see R.styleable#AndroidManifestSupportsScreens_normalScreens
* @see ApplicationInfo#FLAG_SUPPORTS_NORMAL_SCREENS
*/
boolean isSupportsNormalScreens();
/**
* @see ApplicationInfo#FLAG_SUPPORTS_RTL
*/
boolean isSupportsRtl();
/**
* If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link
* android.os.Build.VERSION_CODES#DONUT}.
*
* @see R.styleable#AndroidManifestSupportsScreens_smallScreens
* @see ApplicationInfo#FLAG_SUPPORTS_SMALL_SCREENS
*/
boolean isSupportsSmallScreens();
/**
* @see ApplicationInfo#FLAG_TEST_ONLY
*/
boolean isTestOnly();
/**
* @see ApplicationInfo#PRIVATE_FLAG_USE_EMBEDDED_DEX
*/
boolean isUseEmbeddedDex();
/**
* @see ApplicationInfo#FLAG_USES_CLEARTEXT_TRAFFIC
*/
boolean isUsesCleartextTraffic();
/**
* @see ApplicationInfo#PRIVATE_FLAG_USES_NON_SDK_API
*/
boolean isUsesNonSdkApi();
/**
* @see ApplicationInfo#FLAG_VM_SAFE_MODE
*/
boolean isVmSafeMode();
}

View File

@@ -1,272 +0,0 @@
/*
* Copyright (C) 2022 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.parsing;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import com.android.internal.R;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import java.util.List;
/**
* Container for fields that are eventually exposed through {@link PackageInfo}.
* <p>
* The following are dependent on system state and explicitly removed from this interface. They must
* be accessed by other means:
* <ul>
* <li>{@link PackageInfo#firstInstallTime}</li>
* <li>{@link PackageInfo#lastUpdateTime}</li>
* <li>{@link PackageInfo#gids}</li>
* </ul>
* The following are derived from other fields and thus not provided specifically:
* <ul>
* <li>{@link PackageInfo#requestedPermissionsFlags}</li>
* </ul>
* The following were deprecated at migration time and thus removed from this interface:
* <ul>
* <li>{@link PackageInfo#mOverlayIsStatic}</li>
* <li>{@link PackageInfo#overlayCategory}</li>
* <li>{@link PackageInfo#overlayPriority}</li>
* <li>{@link PackageInfo#overlayTarget}</li>
* <li>{@link PackageInfo#signatures}</li>
* <li>{@link PackageInfo#targetOverlayableName}</li>
* <li>{@link PackageInfo#versionCodeMajor}</li>
* <li>{@link PackageInfo#versionCode}</li>
* </ul>
* The following are retrieved through other APIs:
* <ul>
* <li>{@link PackageInfo#signingInfo}</li>
* <li>{@link PackageInfo#isApex}</li>
* </ul>
*
* @hide
*/
public interface PkgWithoutStatePackageInfo {
/**
* Set of Activities parsed from the manifest.
*
* This contains minimal system state and does not
* provide the same information as {@link ActivityInfo}. Effective state can be queried through
* {@link android.content.pm.PackageManager#getActivityInfo(ComponentName, int)} or by
* combining state from from com.android.server.pm.pkg.PackageState and
* {@link PackageUserState}.
*
* @see ActivityInfo
* @see PackageInfo#activities
*/
@NonNull
List<ParsedActivity> getActivities();
/**
* @see PackageInfo#baseRevisionCode
*/
int getBaseRevisionCode();
/**
* @see PackageInfo#compileSdkVersion
* @see R.styleable#AndroidManifest_compileSdkVersion
*/
int getCompileSdkVersion();
/**
* @see ApplicationInfo#compileSdkVersionCodename
* @see R.styleable#AndroidManifest_compileSdkVersionCodename
*/
@Nullable
String getCompileSdkVersionCodeName();
/**
* @see PackageInfo#configPreferences
* @see R.styleable#AndroidManifestUsesConfiguration
*/
@NonNull
List<ConfigurationInfo> getConfigPreferences();
/**
* @see PackageInfo#featureGroups
* @see R.styleable#AndroidManifestUsesFeature
*/
@NonNull
List<FeatureGroupInfo> getFeatureGroups();
/**
* @see InstrumentationInfo
* @see PackageInfo#instrumentation
*/
@NonNull
List<ParsedInstrumentation> getInstrumentations();
/**
* @see PackageInfo#getLongVersionCode()
*/
long getLongVersionCode();
/**
* @see PackageInfo#packageName
*/
String getPackageName();
/**
* @see PermissionInfo
* @see PackageInfo#permissions
*/
@NonNull
List<ParsedPermission> getPermissions();
/**
* Set of {@link android.content.ContentProvider ContentProviders} parsed from the manifest.
*
* This contains minimal system state and does not
* provide the same information as {@link ProviderInfo}. Effective state can be queried through
* {@link android.content.pm.PackageManager#getProviderInfo(ComponentName, int)} or by
* combining state from from com.android.server.pm.pkg.PackageState and
* {@link PackageUserState}.
*
* @see ProviderInfo
* @see PackageInfo#providers
*/
@NonNull
List<ParsedProvider> getProviders();
/**
* Set of {@link android.content.BroadcastReceiver BroadcastReceivers} parsed from the manifest.
*
* This contains minimal system state and does not
* provide the same information as {@link ActivityInfo}. Effective state can be queried through
* {@link android.content.pm.PackageManager#getReceiverInfo(ComponentName, int)} or by
* combining state from from com.android.server.pm.pkg.PackageState and
* {@link PackageUserState}.
*
* Since they share several attributes, receivers are parsed as {@link ParsedActivity}, even
* though they represent different functionality.
*
* TODO(b/135203078): Reconsider this and maybe make ParsedReceiver so it's not so confusing
*
* @see ActivityInfo
* @see PackageInfo#receivers
*/
@NonNull
List<ParsedActivity> getReceivers();
/**
* @see PackageInfo#reqFeatures
* @see R.styleable#AndroidManifestUsesFeature
*/
@NonNull
List<FeatureInfo> getRequestedFeatures();
/**
* All the permissions declared. This is an effective set, and may include permissions
* transformed from split/migrated permissions from previous versions, so may not be exactly
* what the package declares in its manifest.
*
* @see PackageInfo#requestedPermissions
* @see R.styleable#AndroidManifestUsesPermission
*/
@NonNull
List<String> getRequestedPermissions();
/**
* @see PackageInfo#requiredAccountType
* @see R.styleable#AndroidManifestApplication_requiredAccountType
*/
@Nullable
String getRequiredAccountType();
/**
* The restricted account authenticator type that is used by this application.
*
* @see PackageInfo#restrictedAccountType
* @see R.styleable#AndroidManifestApplication_restrictedAccountType
*/
@Nullable
String getRestrictedAccountType();
/**
* Set of {@link android.app.Service Services} parsed from the manifest.
*
* This contains minimal system state and does not
* provide the same information as {@link ServiceInfo}. Effective state can be queried through
* {@link android.content.pm.PackageManager#getServiceInfo(ComponentName, int)} or by
* combining state from from com.android.server.pm.pkg.PackageState and
* {@link PackageUserState}.
*
* @see ServiceInfo
* @see PackageInfo#services
*/
@NonNull
List<ParsedService> getServices();
/**
* @see PackageInfo#sharedUserId
* @see R.styleable#AndroidManifest_sharedUserId
*/
@Nullable
String getSharedUserId();
/**
* @see PackageInfo#sharedUserLabel
* @see R.styleable#AndroidManifest_sharedUserLabel
*/
int getSharedUserLabel();
/**
* TODO(b/135203078): Move split stuff to an inner data class
*
* @see ApplicationInfo#splitNames
* @see PackageInfo#splitNames
*/
@NonNull
String[] getSplitNames();
/**
* @see PackageInfo#splitRevisionCodes
*/
@NonNull
int[] getSplitRevisionCodes();
/**
* @see PackageInfo#versionName
*/
@Nullable
String getVersionName();
/**
* @see PackageInfo#requiredForAllUsers
* @see R.styleable#AndroidManifestApplication_requiredForAllUsers
*/
boolean isRequiredForAllUsers();
}

View File

@@ -62,15 +62,20 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag
"toAppInfoToString",
"toAppInfoWithoutState",
"toAppInfoWithoutStateWithoutFlags",
"addMimeGroupsFromComponent",
"assignDerivedFields",
"assignDerivedFields2",
"buildFakeForDeletion",
"buildAppClassNamesByProcess",
"capPermissionPriorities",
"forParsing",
"forTesting",
"getBaseAppDataCredentialProtectedDirForSystemUser",
"getBaseAppDataDeviceProtectedDirForSystemUser",
"getBoolean",
"getBoolean2",
"setBoolean",
"setBoolean2",
"hideAsFinal",
"hideAsParsed",
"markNotActivitiesAsNotExportedIfSingleUser",

View File

@@ -83,6 +83,7 @@ import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import org.mockito.AdditionalMatchers.or
import org.mockito.Mockito
import org.mockito.quality.Strictness
import java.io.File
import java.io.IOException
@@ -139,7 +140,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
.mockStatic(PackageManagerServiceUtils::class.java)
.mockStatic(Environment::class.java)
.mockStatic(SystemServerInitThreadPool::class.java)
.mockStatic(ParsingPackageUtils::class.java)
.mockStatic(ParsingPackageUtils::class.java, Mockito.CALLS_REAL_METHODS)
.mockStatic(LockGuard::class.java)
.mockStatic(EventLog::class.java)
.mockStatic(LocalServices::class.java)

View File

@@ -851,13 +851,16 @@ public class AppsFilterImplTest {
public void testActsOnTargetOfOverlay() throws Exception {
final String actorName = "overlay://test/actorName";
ParsingPackage target = pkg("com.some.package.target")
.addOverlayable("overlayableName", actorName);
ParsingPackage overlay = pkg("com.some.package.overlay")
var target = pkg("com.some.package.target")
.addOverlayable("overlayableName", actorName)
.hideAsParsed();
var overlay = pkg("com.some.package.overlay")
.setOverlay(true)
.setOverlayTarget(target.getPackageName())
.setOverlayTargetOverlayableName("overlayableName");
ParsingPackage actor = pkg("com.some.package.actor");
.setOverlayTargetOverlayableName("overlayableName")
.hideAsParsed();
var actor = pkg("com.some.package.actor")
.hideAsParsed();
final AppsFilterImpl appsFilter = new AppsFilterImpl(
mFeatureConfigMock,
@@ -935,14 +938,16 @@ public class AppsFilterImplTest {
final String actorName = "overlay://test/actorName";
ParsingPackage target = pkg("com.some.package.target")
.addOverlayable("overlayableName", actorName);
ParsingPackage overlay = pkg("com.some.package.overlay")
var target = pkg("com.some.package.target")
.addOverlayable("overlayableName", actorName)
.hideAsParsed();
var overlay = pkg("com.some.package.overlay")
.setOverlay(true)
.setOverlayTarget(target.getPackageName())
.setOverlayTargetOverlayableName("overlayableName");
ParsingPackage actorOne = pkg("com.some.package.actor.one");
ParsingPackage actorTwo = pkg("com.some.package.actor.two");
.setOverlayTargetOverlayableName("overlayableName")
.hideAsParsed();
var actorOne = pkg("com.some.package.actor.one").hideAsParsed();
var actorTwo = pkg("com.some.package.actor.two").hideAsParsed();
PackageSetting ps1 = getPackageSettingFromParsingPackage(actorOne, DUMMY_ACTOR_APPID,
null /*settingBuilder*/);
PackageSetting ps2 = getPackageSettingFromParsingPackage(actorTwo, DUMMY_ACTOR_APPID,
@@ -1594,23 +1599,23 @@ public class AppsFilterImplTest {
final Signature frameworkSignature = Mockito.mock(Signature.class);
final SigningDetails frameworkSigningDetails =
new SigningDetails(new Signature[]{frameworkSignature}, 1);
final ParsingPackage android = pkg("android");
final ParsedPackage android = pkg("android").hideAsParsed();
simulateAddPackage(appsFilter, android, 1000,
b -> b.setSigningDetails(frameworkSigningDetails));
}
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId) {
ParsedPackage newPkgBuilder, int appId) {
return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/);
}
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
ParsedPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/);
}
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
ParsedPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
@Nullable SharedUserSetting sharedUserSetting) {
final PackageSetting setting =
getPackageSettingFromParsingPackage(newPkgBuilder, appId, action);
@@ -1618,9 +1623,28 @@ public class AppsFilterImplTest {
return setting;
}
private PackageSetting getPackageSettingFromParsingPackage(ParsingPackage newPkgBuilder,
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId) {
return simulateAddPackage(filter, newPkgBuilder.hideAsParsed(), appId,
null /*settingBuilder*/);
}
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) {
return simulateAddPackage(filter, newPkgBuilder.hideAsParsed(), appId, action,
null /*sharedUserSetting*/);
}
private PackageSetting simulateAddPackage(AppsFilterImpl filter,
ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action,
@Nullable SharedUserSetting sharedUserSetting) {
return simulateAddPackage(filter, newPkgBuilder.hideAsParsed(), appId, action,
sharedUserSetting);
}
private PackageSetting getPackageSettingFromParsingPackage(ParsedPackage newPkgBuilder,
int appId, @Nullable WithSettingBuilder action) {
AndroidPackage newPkg = ((ParsedPackage) newPkgBuilder.hideAsParsed()).hideAsFinal();
AndroidPackage newPkg = newPkgBuilder.hideAsFinal();
final PackageSettingBuilder settingBuilder = new PackageSettingBuilder()
.setPackage(newPkg)
.setAppId(appId)

View File

@@ -29,13 +29,13 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.pm.ApplicationInfo;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import android.os.Build;
import android.platform.test.annotations.Presubmit;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.pkg.PackageUserStateImpl;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import org.junit.After;
import org.junit.Before;
@@ -220,8 +220,8 @@ public class CompatibilityModeTest {
info.targetSdkVersion = targetSdkVersion;
info.flags |= flags;
when(mMockAndroidPackage.toAppInfoWithoutState()).thenReturn(info);
return PackageInfoWithoutStateUtils.generateApplicationInfoUnchecked(mMockAndroidPackage,
0 /*flags*/, mMockUserState, 0 /*userId*/, false /*assignUserFields*/);
return PackageInfoUtils.generateApplicationInfo(mMockAndroidPackage,
0 /*flags*/, mMockUserState, 0 /*userId*/, null);
}
private void setGlobalCompatibilityMode(boolean enabled) {

View File

@@ -71,6 +71,7 @@ import androidx.test.filters.Suppress;
import com.android.frameworks.servicestests.R;
import com.android.internal.content.InstallLocationUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
@@ -341,9 +342,9 @@ public class PackageManagerTests extends AndroidTestCase {
return Uri.fromFile(outFile);
}
private ParsingPackage parsePackage(Uri packageURI) {
private ParsedPackage parsePackage(Uri packageURI) {
final String archiveFilePath = packageURI.getPath();
ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(
ParseResult<ParsedPackage> result = ParsingPackageUtils.parseDefaultOneTime(
new File(archiveFilePath), 0 /*flags*/, Collections.emptyList(),
false /*collectCertificates*/);
if (result.isError()) {
@@ -433,7 +434,7 @@ public class PackageManagerTests extends AndroidTestCase {
return INSTALL_LOC_ERR;
}
private void assertInstall(ParsingPackage pkg, int flags, int expInstallLocation) {
private void assertInstall(ParsedPackage pkg, int flags, int expInstallLocation) {
try {
String pkgName = pkg.getPackageName();
ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
@@ -581,14 +582,14 @@ public class PackageManagerTests extends AndroidTestCase {
class InstallParams {
Uri packageURI;
ParsingPackage pkg;
ParsedPackage pkg;
InstallParams(String outFileName, int rawResId) {
this.pkg = getParsedPackage(outFileName, rawResId);
this.packageURI = Uri.fromFile(new File(pkg.getPath()));
}
InstallParams(ParsingPackage pkg) {
InstallParams(ParsedPackage pkg) {
this.packageURI = Uri.fromFile(new File(pkg.getPath()));
this.pkg = pkg;
}
@@ -696,7 +697,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
private ParsingPackage getParsedPackage(String outFileName, int rawResId) {
private ParsedPackage getParsedPackage(String outFileName, int rawResId) {
PackageManager pm = mContext.getPackageManager();
File filesDir = mContext.getFilesDir();
File outFile = new File(filesDir, outFileName);
@@ -712,7 +713,7 @@ public class PackageManagerTests extends AndroidTestCase {
private void installFromRawResource(InstallParams ip, int flags, boolean cleanUp, boolean fail,
int result, int expInstallLocation) throws Exception {
PackageManager pm = mContext.getPackageManager();
ParsingPackage pkg = ip.pkg;
ParsedPackage pkg = ip.pkg;
Uri packageURI = ip.packageURI;
if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
// Make sure the package doesn't exist
@@ -1876,7 +1877,7 @@ public class PackageManagerTests extends AndroidTestCase {
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
String apk1Name = "install1.apk";
String apk2Name = "install2.apk";
ParsingPackage pkg1 = getParsedPackage(apk1Name, apk1);
var pkg1 = getParsedPackage(apk1Name, apk1);
try {
InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
@@ -2474,7 +2475,7 @@ public class PackageManagerTests extends AndroidTestCase {
File outFile = new File(filesDir, apk2Name);
int rawResId = apk2;
Uri packageURI = getInstallablePackage(rawResId, outFile);
ParsingPackage pkg = parsePackage(packageURI);
var pkg = parsePackage(packageURI);
try {
getPi().uninstall(pkg.getPackageName(),
PackageManager.DELETE_ALL_USERS,
@@ -2544,8 +2545,8 @@ public class PackageManagerTests extends AndroidTestCase {
int retCode, int expMatchResult) throws Exception {
String apk1Name = "install1.apk";
String apk2Name = "install2.apk";
ParsingPackage pkg1 = getParsedPackage(apk1Name, apk1);
ParsingPackage pkg2 = getParsedPackage(apk2Name, apk2);
var pkg1 = getParsedPackage(apk1Name, apk1);
var pkg2 = getParsedPackage(apk2Name, apk2);
try {
// Clean up before testing first.
@@ -2641,7 +2642,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
PackageManager pm = mContext.getPackageManager();
// Delete app2
ParsingPackage pkg = getParsedPackage(apk2Name, apk2);
var pkg = getParsedPackage(apk2Name, apk2);
try {
getPi().uninstall(pkg.getPackageName(), PackageManager.DELETE_ALL_USERS,
null /*statusReceiver*/);

View File

@@ -67,7 +67,6 @@ import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.CompatibilityPermissionInfo;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedActivityImpl;
@@ -88,7 +87,6 @@ import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.component.ParsedServiceImpl;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import org.junit.Before;
@@ -220,13 +218,13 @@ public class PackageParserTest {
setKnownFields(pkg);
Parcel p = Parcel.obtain();
((Parcelable) pkg).writeToParcel(p, 0 /* flags */);
((Parcelable) pkg.hideAsParsed().hideAsFinal()).writeToParcel(p, 0 /* flags */);
p.setDataPosition(0);
ParsingPackage deserialized = new PackageImpl(p);
AndroidPackage deserialized = new PackageImpl(p);
p.setDataPosition(0);
ParsingPackage deserialized2 = new PackageImpl(p);
AndroidPackage deserialized2 = new PackageImpl(p);
assertSame(deserialized.getPackageName(), deserialized2.getPackageName());
assertSame(deserialized.getPermission(),
@@ -636,27 +634,27 @@ public class PackageParserTest {
final File testFile = extractFile(TEST_APP4_APK);
try {
final ParsedPackage pkg = new TestPackageParser2().parsePackage(testFile, 0, false);
ApplicationInfo appInfo = PackageInfoWithoutStateUtils.generateApplicationInfo(pkg, 0,
PackageUserState.DEFAULT, 0);
ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(pkg, 0,
PackageUserStateInternal.DEFAULT, 0, null);
for (ParsedActivity activity : pkg.getActivities()) {
assertNotNull(activity.getMetaData());
assertNull(PackageInfoWithoutStateUtils.generateActivityInfoUnchecked(activity, 0,
appInfo).metaData);
assertNull(PackageInfoUtils.generateActivityInfo(pkg, activity, 0,
PackageUserStateInternal.DEFAULT, appInfo, 0, null).metaData);
}
for (ParsedProvider provider : pkg.getProviders()) {
assertNotNull(provider.getMetaData());
assertNull(PackageInfoWithoutStateUtils.generateProviderInfoUnchecked(provider, 0,
appInfo).metaData);
assertNull(PackageInfoUtils.generateProviderInfo(pkg, provider, 0,
PackageUserStateInternal.DEFAULT, appInfo, 0, null).metaData);
}
for (ParsedActivity receiver : pkg.getReceivers()) {
assertNotNull(receiver.getMetaData());
assertNull(PackageInfoWithoutStateUtils.generateActivityInfoUnchecked(receiver, 0,
appInfo).metaData);
assertNull(PackageInfoUtils.generateActivityInfo(pkg, receiver, 0,
PackageUserStateInternal.DEFAULT, appInfo, 0, null).metaData);
}
for (ParsedService service : pkg.getServices()) {
assertNotNull(service.getMetaData());
assertNull(PackageInfoWithoutStateUtils.generateServiceInfoUnchecked(service, 0,
appInfo).metaData);
assertNull(PackageInfoUtils.generateServiceInfo(pkg, service, 0,
PackageUserStateInternal.DEFAULT, appInfo, 0, null).metaData);
}
} finally {
testFile.delete();

View File

@@ -34,6 +34,7 @@ import android.content.pm.parsing.result.ParseTypeImpl;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
import android.util.SparseIntArray;
@@ -52,7 +53,6 @@ import com.android.server.pm.pkg.component.ParsedComponent;
import com.android.server.pm.pkg.component.ParsedIntentInfo;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedPermissionUtils;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
@@ -580,21 +580,22 @@ public class PackageParserLegacyCoreTest {
apexInfo.versionCode = 191000070;
int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(apexFile,
ParseResult<ParsedPackage> result = ParsingPackageUtils.parseDefaultOneTime(apexFile,
flags, Collections.emptyList(), false /*collectCertificates*/);
if (result.isError()) {
throw new IllegalStateException(result.getErrorMessage(), result.getException());
}
ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
ParsingPackage pkg = result.getResult();
ParsedPackage pkg = result.getResult();
ParseResult<SigningDetails> ret = ParsingPackageUtils.getSigningDetails(
input, pkg, false /*skipVerify*/);
if (ret.isError()) {
throw new IllegalStateException(ret.getErrorMessage(), ret.getException());
}
pkg.setSigningDetails(ret.getResult());
PackageInfo pi = PackageInfoWithoutStateUtils.generate(pkg, apexInfo, flags);
PackageInfo pi = PackageInfoUtils.generate(pkg.setApex(true).hideAsFinal(), apexInfo,
flags, null, UserHandle.USER_SYSTEM);
assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
assertTrue(pi.applicationInfo.enabled);

View File

@@ -24,6 +24,7 @@ import android.content.pm.parsing.result.ParseResult
import android.platform.test.annotations.Presubmit
import androidx.test.InstrumentationRegistry
import com.android.frameworks.servicestests.R
import com.android.server.pm.parsing.pkg.ParsedPackage
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
@@ -114,7 +115,7 @@ class PackageParsingDeferErrorTest {
assertThat(result.isError).isTrue()
}
private fun parseFile(@RawRes id: Int): ParseResult<ParsingPackage> {
private fun parseFile(@RawRes id: Int): ParseResult<ParsedPackage> {
val file = tempFolder.newFile()
context.resources.openRawResource(id).use { input ->
file.outputStream().use { output ->