Merge changes from topic "aosp-apk-in-apex"
* changes: DO NOT MERGE: Fixes NPE when preparing app data during init Support privileged apps installed in APEX. Support non-privileged APKs in APEX. Refactors initial directory scan to be dryer
This commit is contained in:
@@ -55,6 +55,7 @@ public class Environment {
|
|||||||
private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
|
private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
|
||||||
private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
|
private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
|
||||||
private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
|
private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
|
||||||
|
private static final String ENV_APEX_ROOT = "APEX_ROOT";
|
||||||
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
public static final String DIR_ANDROID = "Android";
|
public static final String DIR_ANDROID = "Android";
|
||||||
@@ -78,7 +79,9 @@ public class Environment {
|
|||||||
private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
|
private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
|
||||||
private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
|
private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
|
||||||
private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
|
private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
|
||||||
"/system_ext");
|
"/system_ext");
|
||||||
|
private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT,
|
||||||
|
"/apex");
|
||||||
|
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
private static UserEnvironment sCurrentUser;
|
private static UserEnvironment sCurrentUser;
|
||||||
@@ -245,6 +248,16 @@ public class Environment {
|
|||||||
return DIR_SYSTEM_EXT_ROOT;
|
return DIR_SYSTEM_EXT_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return root directory of the apex mount point, where all the apex modules are made available
|
||||||
|
* to the rest of the system.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static @NonNull File getApexDirectory() {
|
||||||
|
return DIR_APEX_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the system directory for a user. This is for use by system
|
* Return the system directory for a user. This is for use by system
|
||||||
* services to store files relating to the user. This directory will be
|
* services to store files relating to the user. This directory will be
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.content.pm.PackageInfo;
|
|||||||
import android.content.pm.PackageInstaller;
|
import android.content.pm.PackageInstaller;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageParser;
|
import android.content.pm.PackageParser;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.sysprop.ApexProperties;
|
import android.sysprop.ApexProperties;
|
||||||
@@ -47,6 +48,7 @@ import java.io.PrintWriter;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -64,9 +66,9 @@ abstract class ApexManager {
|
|||||||
static final int MATCH_FACTORY_PACKAGE = 1 << 1;
|
static final int MATCH_FACTORY_PACKAGE = 1 << 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerNoOp} depending
|
* Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerFlattenedApex}
|
||||||
* on whenever this device supports APEX, i.e. {@link ApexProperties#updatable()} evaluates to
|
* depending on whether this device supports APEX, i.e. {@link ApexProperties#updatable()}
|
||||||
* {@code true}.
|
* evaluates to {@code true}.
|
||||||
*/
|
*/
|
||||||
static ApexManager create(Context systemContext) {
|
static ApexManager create(Context systemContext) {
|
||||||
if (ApexProperties.updatable().orElse(false)) {
|
if (ApexProperties.updatable().orElse(false)) {
|
||||||
@@ -77,10 +79,28 @@ abstract class ApexManager {
|
|||||||
throw new IllegalStateException("Required service apexservice not available");
|
throw new IllegalStateException("Required service apexservice not available");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new ApexManagerNoOp();
|
return new ApexManagerFlattenedApex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal information about APEX mount points and the original APEX package they refer to.
|
||||||
|
*/
|
||||||
|
static class ActiveApexInfo {
|
||||||
|
public final File apexDirectory;
|
||||||
|
public final File preinstalledApexPath;
|
||||||
|
|
||||||
|
private ActiveApexInfo(File apexDirectory, File preinstalledApexPath) {
|
||||||
|
this.apexDirectory = apexDirectory;
|
||||||
|
this.preinstalledApexPath = preinstalledApexPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@link ActiveApexInfo} records relative to all active APEX packages.
|
||||||
|
*/
|
||||||
|
abstract List<ActiveApexInfo> getActiveApexInfos();
|
||||||
|
|
||||||
abstract void systemReady();
|
abstract void systemReady();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,6 +278,22 @@ abstract class ApexManager {
|
|||||||
return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
List<ActiveApexInfo> getActiveApexInfos() {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(mApexService.getActivePackages())
|
||||||
|
.map(apexInfo -> new ActiveApexInfo(
|
||||||
|
new File(
|
||||||
|
Environment.getApexDirectory() + File.separator
|
||||||
|
+ apexInfo.moduleName),
|
||||||
|
new File(apexInfo.modulePath))).collect(
|
||||||
|
Collectors.toList());
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Unable to retrieve packages from apexservice", e);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void systemReady() {
|
void systemReady() {
|
||||||
mContext.registerReceiver(new BroadcastReceiver() {
|
mContext.registerReceiver(new BroadcastReceiver() {
|
||||||
@@ -549,7 +585,40 @@ abstract class ApexManager {
|
|||||||
* An implementation of {@link ApexManager} that should be used in case device does not support
|
* An implementation of {@link ApexManager} that should be used in case device does not support
|
||||||
* updating APEX packages.
|
* updating APEX packages.
|
||||||
*/
|
*/
|
||||||
private static final class ApexManagerNoOp extends ApexManager {
|
private static final class ApexManagerFlattenedApex extends ApexManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
List<ActiveApexInfo> getActiveApexInfos() {
|
||||||
|
// There is no apexd running in case of flattened apex
|
||||||
|
// We look up the /apex directory and identify the active APEX modules from there.
|
||||||
|
// As "preinstalled" path, we just report /system since in the case of flattened APEX
|
||||||
|
// the /apex directory is just a symlink to /system/apex.
|
||||||
|
List<ActiveApexInfo> result = new ArrayList<>();
|
||||||
|
File apexDir = Environment.getApexDirectory();
|
||||||
|
// In flattened configuration, init special-case the art directory and bind-mounts
|
||||||
|
// com.android.art.{release|debug} to com.android.art. At the time of writing, these
|
||||||
|
// directories are copied from the kArtApexDirNames variable in
|
||||||
|
// system/core/init/mount_namespace.cpp.
|
||||||
|
String[] skipDirs = {"com.android.art.release", "com.android.art.debug"};
|
||||||
|
if (apexDir.isDirectory()) {
|
||||||
|
File[] files = apexDir.listFiles();
|
||||||
|
// listFiles might be null if system server doesn't have permission to read
|
||||||
|
// a directory.
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isDirectory() && !file.getName().contains("@")) {
|
||||||
|
for (String skipDir : skipDirs) {
|
||||||
|
if (file.getName().equals(skipDir)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.add(new ActiveApexInfo(file, Environment.getRootDirectory()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void systemReady() {
|
void systemReady() {
|
||||||
|
|||||||
@@ -67,6 +67,15 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
|
|||||||
codeRoot = Environment.getSystemExtDirectory();
|
codeRoot = Environment.getSystemExtDirectory();
|
||||||
} else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
|
} else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
|
||||||
codeRoot = Environment.getOdmDirectory();
|
codeRoot = Environment.getOdmDirectory();
|
||||||
|
} else if (FileUtils.contains(Environment.getApexDirectory(), codePath)) {
|
||||||
|
String fullPath = codePath.getAbsolutePath();
|
||||||
|
String[] parts = fullPath.split(File.separator);
|
||||||
|
if (parts.length > 2) {
|
||||||
|
codeRoot = new File(parts[1] + File.separator + parts[2]);
|
||||||
|
} else {
|
||||||
|
Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath);
|
||||||
|
codeRoot = Environment.getApexDirectory();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unrecognized code path; take its top real segment as the apk root:
|
// Unrecognized code path; take its top real segment as the apk root:
|
||||||
// e.g. /something/app/blah.apk => /something
|
// e.g. /something/app/blah.apk => /something
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
|
|||||||
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
|
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
|
||||||
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
|
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
|
||||||
|
|
||||||
|
import static com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||||
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
|
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
|
||||||
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
|
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
|
||||||
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
|
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
|
||||||
@@ -374,6 +375,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of all those APKs everywhere.
|
* Keep track of all those APKs everywhere.
|
||||||
@@ -588,16 +590,6 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
private static final String PACKAGE_SCHEME = "package";
|
private static final String PACKAGE_SCHEME = "package";
|
||||||
|
|
||||||
private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
|
|
||||||
|
|
||||||
private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
|
|
||||||
|
|
||||||
private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
|
|
||||||
|
|
||||||
private static final String ODM_OVERLAY_DIR = "/odm/overlay";
|
|
||||||
|
|
||||||
private static final String OEM_OVERLAY_DIR = "/oem/overlay";
|
|
||||||
|
|
||||||
/** Canonical intent used to identify what counts as a "web browser" app */
|
/** Canonical intent used to identify what counts as a "web browser" app */
|
||||||
private static final Intent sBrowserIntent;
|
private static final Intent sBrowserIntent;
|
||||||
static {
|
static {
|
||||||
@@ -757,7 +749,31 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
private final Injector mInjector;
|
private final Injector mInjector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests will instantiate and / or extend to mock dependencies / behaviors.
|
* The list of all system partitions that may contain packages in ascending order of
|
||||||
|
* specificity (the more generic, the earlier in the list a partition appears).
|
||||||
|
*/
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
static final List<SystemPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
|
||||||
|
Arrays.asList(
|
||||||
|
new SystemPartition(Environment.getRootDirectory(), 0 /* scanFlag */,
|
||||||
|
false /* hasOverlays */),
|
||||||
|
new SystemPartition(Environment.getVendorDirectory(), SCAN_AS_VENDOR,
|
||||||
|
true /* hasOverlays */),
|
||||||
|
new SystemPartition(Environment.getOdmDirectory(), SCAN_AS_ODM,
|
||||||
|
true /* hasOverlays */),
|
||||||
|
new SystemPartition(Environment.getOemDirectory(), SCAN_AS_OEM,
|
||||||
|
true /* hasOverlays */),
|
||||||
|
new SystemPartition(Environment.getProductDirectory(), SCAN_AS_PRODUCT,
|
||||||
|
true /* hasOverlays */),
|
||||||
|
new SystemPartition(Environment.getSystemExtDirectory(), SCAN_AS_SYSTEM_EXT,
|
||||||
|
true /* hasOverlays */)));
|
||||||
|
|
||||||
|
private final List<SystemPartition> mDirsToScanAsSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
|
||||||
|
*
|
||||||
|
* NOTE: All getters should return the same instance for every call.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class Injector {
|
static class Injector {
|
||||||
@@ -2410,9 +2426,70 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
static class SystemPartition {
|
||||||
|
public final File folder;
|
||||||
|
public final int scanFlag;
|
||||||
|
public final File appFolder;
|
||||||
|
@Nullable
|
||||||
|
public final File privAppFolder;
|
||||||
|
@Nullable
|
||||||
|
public final File overlayFolder;
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean shouldScanPrivApps(@ScanFlags int scanFlags) {
|
||||||
|
if ((scanFlags & SCAN_AS_OEM) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (scanFlags == 0) { // /system partition
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((scanFlags
|
||||||
|
& (SCAN_AS_VENDOR | SCAN_AS_ODM | SCAN_AS_PRODUCT | SCAN_AS_SYSTEM_EXT)) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SystemPartition(File folder, int scanFlag, boolean hasOverlays) {
|
||||||
|
this.folder = folder;
|
||||||
|
this.scanFlag = scanFlag;
|
||||||
|
this.appFolder = toCanonical(new File(folder, "app"));
|
||||||
|
this.privAppFolder = shouldScanPrivApps(scanFlag)
|
||||||
|
? toCanonical(new File(folder, "priv-app"))
|
||||||
|
: null;
|
||||||
|
this.overlayFolder = hasOverlays ? toCanonical(new File(folder, "overlay")) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsPrivApp(File scanFile) {
|
||||||
|
return FileUtils.contains(privAppFolder, scanFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsApp(File scanFile) {
|
||||||
|
return FileUtils.contains(appFolder, scanFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsPath(String path) {
|
||||||
|
return path.startsWith(folder.getPath() + "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsPrivPath(String path) {
|
||||||
|
return privAppFolder != null && path.startsWith(privAppFolder.getPath() + "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File toCanonical(File dir) {
|
||||||
|
try {
|
||||||
|
return dir.getCanonicalFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// failed to look up canonical path, continue with original one
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PackageManagerService(Context context, Installer installer,
|
public PackageManagerService(Context context, Installer installer,
|
||||||
boolean factoryTest, boolean onlyCore) {
|
boolean factoryTest, boolean onlyCore) {
|
||||||
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
|
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
|
||||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
|
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
|
||||||
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
|
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
|
||||||
SystemClock.uptimeMillis());
|
SystemClock.uptimeMillis());
|
||||||
@@ -2505,7 +2582,18 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
|
|
||||||
mProtectedPackages = new ProtectedPackages(mContext);
|
mProtectedPackages = new ProtectedPackages(mContext);
|
||||||
|
|
||||||
mApexManager = ApexManager.create(context);
|
mApexManager = ApexManager.create(mContext);
|
||||||
|
|
||||||
|
mDirsToScanAsSystem = new ArrayList<>();
|
||||||
|
mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
|
||||||
|
mDirsToScanAsSystem.addAll(mApexManager.getActiveApexInfos().stream()
|
||||||
|
.map(ai -> resolveApexToSystemPartition(ai))
|
||||||
|
.filter(Objects::nonNull).collect(Collectors.toList()));
|
||||||
|
Slog.d(TAG,
|
||||||
|
"Directories scanned as system partitions: [" + mDirsToScanAsSystem.stream().map(
|
||||||
|
d -> (d.folder.getAbsolutePath() + ":" + d.scanFlag))
|
||||||
|
.collect(Collectors.joining(",")) + "]");
|
||||||
|
|
||||||
// CHECKSTYLE:OFF IndentationCheck
|
// CHECKSTYLE:OFF IndentationCheck
|
||||||
synchronized (mInstallLock) {
|
synchronized (mInstallLock) {
|
||||||
// writer
|
// writer
|
||||||
@@ -2640,215 +2728,35 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
// any apps.)
|
// any apps.)
|
||||||
// For security and version matching reason, only consider overlay packages if they
|
// For security and version matching reason, only consider overlay packages if they
|
||||||
// reside in the right directory.
|
// reside in the right directory.
|
||||||
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
|
final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
|
||||||
mDefParseFlags
|
final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
|
||||||
scanFlags
|
final SystemPartition partition = mDirsToScanAsSystem.get(i);
|
||||||
| SCAN_AS_SYSTEM
|
if (partition.overlayFolder == null) {
|
||||||
| SCAN_AS_VENDOR,
|
continue;
|
||||||
0);
|
}
|
||||||
scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
|
scanDirTracedLI(partition.overlayFolder, systemParseFlags,
|
||||||
mDefParseFlags
|
systemScanFlags | partition.scanFlag, 0);
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
}
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRODUCT,
|
|
||||||
0);
|
|
||||||
scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_SYSTEM_EXT,
|
|
||||||
0);
|
|
||||||
scanDirTracedLI(new File(ODM_OVERLAY_DIR),
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_ODM,
|
|
||||||
0);
|
|
||||||
scanDirTracedLI(new File(OEM_OVERLAY_DIR),
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_OEM,
|
|
||||||
0);
|
|
||||||
|
|
||||||
mParallelPackageParserCallback.findStaticOverlayPackages();
|
mParallelPackageParserCallback.findStaticOverlayPackages();
|
||||||
|
|
||||||
// Find base frameworks (resource packages without code).
|
scanDirTracedLI(frameworkDir, systemParseFlags,
|
||||||
scanDirTracedLI(frameworkDir,
|
systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0);
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_NO_DEX
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
if (!mPackages.containsKey("android")) {
|
if (!mPackages.containsKey("android")) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Failed to load frameworks package; check log for warnings");
|
"Failed to load frameworks package; check log for warnings");
|
||||||
}
|
}
|
||||||
|
for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
|
||||||
// Collect privileged system packages.
|
final SystemPartition partition = mDirsToScanAsSystem.get(i);
|
||||||
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
|
if (partition.privAppFolder != null) {
|
||||||
scanDirTracedLI(privilegedAppDir,
|
scanDirTracedLI(partition.privAppFolder, systemParseFlags,
|
||||||
mDefParseFlags
|
systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0);
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
}
|
||||||
scanFlags
|
scanDirTracedLI(partition.appFolder, systemParseFlags,
|
||||||
| SCAN_AS_SYSTEM
|
systemScanFlags | partition.scanFlag, 0);
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect ordinary system packages.
|
|
||||||
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
|
|
||||||
scanDirTracedLI(systemAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect privileged vendor packages.
|
|
||||||
File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
|
|
||||||
try {
|
|
||||||
privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
}
|
||||||
scanDirTracedLI(privilegedVendorAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR
|
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect ordinary vendor packages.
|
|
||||||
File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
|
|
||||||
try {
|
|
||||||
vendorAppDir = vendorAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(vendorAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect privileged odm packages. /odm is another vendor partition
|
|
||||||
// other than /vendor.
|
|
||||||
File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
|
|
||||||
"priv-app");
|
|
||||||
try {
|
|
||||||
privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(privilegedOdmAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR
|
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect ordinary odm packages. /odm is another vendor partition
|
|
||||||
// other than /vendor.
|
|
||||||
File odmAppDir = new File(Environment.getOdmDirectory(), "app");
|
|
||||||
try {
|
|
||||||
odmAppDir = odmAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(odmAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect all OEM packages.
|
|
||||||
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
|
|
||||||
scanDirTracedLI(oemAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_OEM,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collected privileged /product packages.
|
|
||||||
File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
|
|
||||||
try {
|
|
||||||
privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(privilegedProductAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRODUCT
|
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect ordinary /product packages.
|
|
||||||
File productAppDir = new File(Environment.getProductDirectory(), "app");
|
|
||||||
try {
|
|
||||||
productAppDir = productAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(productAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRODUCT,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collected privileged /system_ext packages.
|
|
||||||
File privilegedSystemExtAppDir =
|
|
||||||
new File(Environment.getSystemExtDirectory(), "priv-app");
|
|
||||||
try {
|
|
||||||
privilegedSystemExtAppDir =
|
|
||||||
privilegedSystemExtAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(privilegedSystemExtAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_SYSTEM_EXT
|
|
||||||
| SCAN_AS_PRIVILEGED,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Collect ordinary /system_ext packages.
|
|
||||||
File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
|
|
||||||
try {
|
|
||||||
systemExtAppDir = systemExtAppDir.getCanonicalFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// failed to look up canonical path, continue with original one
|
|
||||||
}
|
|
||||||
scanDirTracedLI(systemExtAppDir,
|
|
||||||
mDefParseFlags
|
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR,
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_SYSTEM_EXT,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// Prune any system packages that no longer exist.
|
// Prune any system packages that no longer exist.
|
||||||
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
|
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
|
||||||
@@ -3016,89 +2924,26 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
logCriticalInfo(Log.WARN, "Expected better " + packageName
|
logCriticalInfo(Log.WARN, "Expected better " + packageName
|
||||||
+ " but never showed up; reverting to system");
|
+ " but never showed up; reverting to system");
|
||||||
|
|
||||||
final @ParseFlags int reparseFlags;
|
@ParseFlags int reparseFlags = 0;
|
||||||
final @ScanFlags int rescanFlags;
|
@ScanFlags int rescanFlags = 0;
|
||||||
if (FileUtils.contains(privilegedAppDir, scanFile)) {
|
for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
|
||||||
reparseFlags =
|
SystemPartition partition = mDirsToScanAsSystem.get(i1);
|
||||||
mDefParseFlags |
|
if (partition.containsPrivApp(scanFile)) {
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
reparseFlags = systemParseFlags;
|
||||||
rescanFlags =
|
rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
|
||||||
scanFlags
|
| partition.scanFlag;
|
||||||
| SCAN_AS_SYSTEM
|
break;
|
||||||
| SCAN_AS_PRIVILEGED;
|
}
|
||||||
} else if (FileUtils.contains(systemAppDir, scanFile)) {
|
if (partition.containsApp(scanFile)) {
|
||||||
reparseFlags =
|
reparseFlags = systemParseFlags;
|
||||||
mDefParseFlags |
|
rescanFlags = systemScanFlags | partition.scanFlag;
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
break;
|
||||||
rescanFlags =
|
}
|
||||||
scanFlags
|
}
|
||||||
| SCAN_AS_SYSTEM;
|
if (rescanFlags == 0) {
|
||||||
} else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
|
|
||||||
|| FileUtils.contains(privilegedOdmAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR
|
|
||||||
| SCAN_AS_PRIVILEGED;
|
|
||||||
} else if (FileUtils.contains(vendorAppDir, scanFile)
|
|
||||||
|| FileUtils.contains(odmAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_VENDOR;
|
|
||||||
} else if (FileUtils.contains(oemAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_OEM;
|
|
||||||
} else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRODUCT
|
|
||||||
| SCAN_AS_PRIVILEGED;
|
|
||||||
} else if (FileUtils.contains(productAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_PRODUCT;
|
|
||||||
} else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_SYSTEM_EXT
|
|
||||||
| SCAN_AS_PRIVILEGED;
|
|
||||||
} else if (FileUtils.contains(systemExtAppDir, scanFile)) {
|
|
||||||
reparseFlags =
|
|
||||||
mDefParseFlags |
|
|
||||||
PackageParser.PARSE_IS_SYSTEM_DIR;
|
|
||||||
rescanFlags =
|
|
||||||
scanFlags
|
|
||||||
| SCAN_AS_SYSTEM
|
|
||||||
| SCAN_AS_SYSTEM_EXT;
|
|
||||||
} else {
|
|
||||||
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
|
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSettings.enableSystemPackageLPw(packageName);
|
mSettings.enableSystemPackageLPw(packageName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -18559,70 +18404,17 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean locationIsPrivileged(String path) {
|
private static @Nullable SystemPartition resolveApexToSystemPartition(
|
||||||
try {
|
ApexManager.ActiveApexInfo apexInfo) {
|
||||||
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
|
for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
|
||||||
final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
|
SystemPartition sp = SYSTEM_PARTITIONS.get(i);
|
||||||
final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
|
if (apexInfo.preinstalledApexPath.getAbsolutePath().startsWith(
|
||||||
final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
|
sp.folder.getAbsolutePath())) {
|
||||||
final File privilegedSystemExtAppDir =
|
return new SystemPartition(apexInfo.apexDirectory, sp.scanFlag,
|
||||||
new File(Environment.getSystemExtDirectory(), "priv-app");
|
false /* hasOverlays */);
|
||||||
return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
|
}
|
||||||
|| path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
|
|
||||||
|| path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
|
|
||||||
|| path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
|
|
||||||
|| path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
static boolean locationIsOem(String path) {
|
|
||||||
try {
|
|
||||||
return path.startsWith(Environment.getOemDirectory().getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean locationIsVendor(String path) {
|
|
||||||
try {
|
|
||||||
return path.startsWith(Environment.getVendorDirectory().getCanonicalPath() + "/")
|
|
||||||
|| path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean locationIsProduct(String path) {
|
|
||||||
try {
|
|
||||||
return path.startsWith(Environment.getProductDirectory().getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean locationIsSystemExt(String path) {
|
|
||||||
try {
|
|
||||||
return path.startsWith(
|
|
||||||
Environment.getSystemExtDirectory().getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean locationIsOdm(String path) {
|
|
||||||
try {
|
|
||||||
return path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "Unable to access code path " + path);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -18734,23 +18526,15 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
| PackageParser.PARSE_MUST_BE_APK
|
| PackageParser.PARSE_MUST_BE_APK
|
||||||
| PackageParser.PARSE_IS_SYSTEM_DIR;
|
| PackageParser.PARSE_IS_SYSTEM_DIR;
|
||||||
@ScanFlags int scanFlags = SCAN_AS_SYSTEM;
|
@ScanFlags int scanFlags = SCAN_AS_SYSTEM;
|
||||||
if (locationIsPrivileged(codePathString)) {
|
for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
|
||||||
scanFlags |= SCAN_AS_PRIVILEGED;
|
SystemPartition partition = mDirsToScanAsSystem.get(i);
|
||||||
}
|
if (partition.containsPath(codePathString)) {
|
||||||
if (locationIsOem(codePathString)) {
|
scanFlags |= partition.scanFlag;
|
||||||
scanFlags |= SCAN_AS_OEM;
|
if (partition.containsPrivPath(codePathString)) {
|
||||||
}
|
scanFlags |= SCAN_AS_PRIVILEGED;
|
||||||
if (locationIsVendor(codePathString)) {
|
}
|
||||||
scanFlags |= SCAN_AS_VENDOR;
|
break;
|
||||||
}
|
}
|
||||||
if (locationIsProduct(codePathString)) {
|
|
||||||
scanFlags |= SCAN_AS_PRODUCT;
|
|
||||||
}
|
|
||||||
if (locationIsSystemExt(codePathString)) {
|
|
||||||
scanFlags |= SCAN_AS_SYSTEM_EXT;
|
|
||||||
}
|
|
||||||
if (locationIsOdm(codePathString)) {
|
|
||||||
scanFlags |= SCAN_AS_ODM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final File codePath = new File(codePathString);
|
final File codePath = new File(codePathString);
|
||||||
@@ -22564,9 +22348,9 @@ public class PackageManagerService extends IPackageManager.Stub
|
|||||||
mSettings.writeKernelMappingLPr(ps);
|
mSettings.writeKernelMappingLPr(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
final UserManager um = mContext.getSystemService(UserManager.class);
|
final UserManagerService um = sUserManager;
|
||||||
UserManagerInternal umInternal = getUserManagerInternal();
|
UserManagerInternal umInternal = getUserManagerInternal();
|
||||||
for (UserInfo user : um.getUsers()) {
|
for (UserInfo user : um.getUsers(false /* excludeDying */)) {
|
||||||
final int flags;
|
final int flags;
|
||||||
if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
|
if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
|
||||||
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
|
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
|
||||||
|
|||||||
@@ -3506,7 +3506,7 @@ public final class Settings {
|
|||||||
int pkgFlags = 0;
|
int pkgFlags = 0;
|
||||||
int pkgPrivateFlags = 0;
|
int pkgPrivateFlags = 0;
|
||||||
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
|
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
|
||||||
if (PackageManagerService.locationIsPrivileged(codePathStr)) {
|
if (codePathStr.contains("/priv-app/")) {
|
||||||
pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
|
pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
|
||||||
}
|
}
|
||||||
PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
|
PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
|
||||||
|
|||||||
@@ -118,17 +118,20 @@ public class PackageManagerServiceTest {
|
|||||||
String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
|
String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
|
||||||
String[] appdir = { "app", "priv-app" };
|
String[] appdir = { "app", "priv-app" };
|
||||||
for (int i = 0; i < partitions.length; i++) {
|
for (int i = 0; i < partitions.length; i++) {
|
||||||
|
final PackageManagerService.SystemPartition systemPartition =
|
||||||
|
PackageManagerService.SYSTEM_PARTITIONS.get(i);
|
||||||
for (int j = 0; j < appdir.length; j++) {
|
for (int j = 0; j < appdir.length; j++) {
|
||||||
String canonical = new File("/" + partitions[i]).getCanonicalPath();
|
String canonical = new File("/" + partitions[i]).getCanonicalPath();
|
||||||
String path = String.format("%s/%s/A.apk", canonical, appdir[j]);
|
String path = String.format("%s/%s/A.apk", canonical, appdir[j]);
|
||||||
|
|
||||||
Assert.assertEquals(j == 1 && i != 3,
|
Assert.assertEquals(j == 1 && i != 3, systemPartition.containsPrivPath(path));
|
||||||
PackageManagerService.locationIsPrivileged(path));
|
|
||||||
|
|
||||||
Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
|
final int scanFlag = systemPartition.scanFlag;
|
||||||
Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
|
Assert.assertEquals(i == 1, scanFlag == PackageManagerService.SCAN_AS_VENDOR);
|
||||||
Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
|
Assert.assertEquals(i == 2, scanFlag == PackageManagerService.SCAN_AS_ODM);
|
||||||
Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
|
Assert.assertEquals(i == 3, scanFlag == PackageManagerService.SCAN_AS_OEM);
|
||||||
|
Assert.assertEquals(i == 4, scanFlag == PackageManagerService.SCAN_AS_PRODUCT);
|
||||||
|
Assert.assertEquals(i == 5, scanFlag == PackageManagerService.SCAN_AS_SYSTEM_EXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user