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:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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*/);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
Reference in New Issue
Block a user