Merge "Install system app in greatest priority partition" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d32418a72a
@@ -93,15 +93,23 @@ public class PackagePartitions {
|
||||
return out;
|
||||
}
|
||||
|
||||
private static File canonicalize(File path) {
|
||||
try {
|
||||
return path.getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a partition that contains application packages. */
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
|
||||
public static class SystemPartition {
|
||||
@NonNull
|
||||
public final File folder;
|
||||
|
||||
@PartitionType
|
||||
public final int type;
|
||||
|
||||
@NonNull
|
||||
private final DeferredCanonicalFile mFolder;
|
||||
|
||||
@Nullable
|
||||
private final DeferredCanonicalFile mAppFolder;
|
||||
|
||||
@@ -113,18 +121,18 @@ public class PackagePartitions {
|
||||
|
||||
private SystemPartition(@NonNull File folder, @PartitionType int type,
|
||||
boolean containsPrivApp, boolean containsOverlay) {
|
||||
this.folder = folder;
|
||||
this.type = type;
|
||||
this.mFolder = new DeferredCanonicalFile(folder);
|
||||
this.mAppFolder = new DeferredCanonicalFile(folder, "app");
|
||||
this.mPrivAppFolder = containsPrivApp ?
|
||||
new DeferredCanonicalFile(folder, "priv-app") : null;
|
||||
this.mOverlayFolder = containsOverlay ?
|
||||
new DeferredCanonicalFile(folder, "overlay") : null;
|
||||
this.mPrivAppFolder = containsPrivApp ? new DeferredCanonicalFile(folder, "priv-app")
|
||||
: null;
|
||||
this.mOverlayFolder = containsOverlay ? new DeferredCanonicalFile(folder, "overlay")
|
||||
: null;
|
||||
}
|
||||
|
||||
public SystemPartition(@NonNull SystemPartition original) {
|
||||
this.folder = original.folder;
|
||||
this.type = original.type;
|
||||
this.mFolder = new DeferredCanonicalFile(original.mFolder.getFile());
|
||||
this.mAppFolder = original.mAppFolder;
|
||||
this.mPrivAppFolder = original.mPrivAppFolder;
|
||||
this.mOverlayFolder = original.mOverlayFolder;
|
||||
@@ -139,6 +147,12 @@ public class PackagePartitions {
|
||||
partition.mOverlayFolder != null);
|
||||
}
|
||||
|
||||
/** Returns the canonical folder of the partition. */
|
||||
@NonNull
|
||||
public File getFolder() {
|
||||
return mFolder.getFile();
|
||||
}
|
||||
|
||||
/** Returns the canonical app folder of the partition. */
|
||||
@Nullable
|
||||
public File getAppFolder() {
|
||||
@@ -157,30 +171,29 @@ public class PackagePartitions {
|
||||
return mOverlayFolder == null ? null : mOverlayFolder.getFile();
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file. */
|
||||
public boolean containsPath(@NonNull String path) {
|
||||
return containsFile(new File(path));
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file. */
|
||||
public boolean containsFile(@NonNull File file) {
|
||||
return FileUtils.contains(mFolder.getFile(), canonicalize(file));
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file in its priv-app folder. */
|
||||
public boolean containsPrivApp(@NonNull File scanFile) {
|
||||
return FileUtils.contains(mPrivAppFolder.getFile(), scanFile);
|
||||
return FileUtils.contains(mPrivAppFolder.getFile(), canonicalize(scanFile));
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file in its app folder. */
|
||||
public boolean containsApp(@NonNull File scanFile) {
|
||||
return FileUtils.contains(mAppFolder.getFile(), scanFile);
|
||||
return FileUtils.contains(mAppFolder.getFile(), canonicalize(scanFile));
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file in its overlay folder. */
|
||||
public boolean containsOverlay(@NonNull File scanFile) {
|
||||
return FileUtils.contains(mOverlayFolder.getFile(), scanFile);
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file. */
|
||||
public boolean containsPath(@NonNull String path) {
|
||||
return path.startsWith(folder.getPath() + "/");
|
||||
}
|
||||
|
||||
/** Returns whether the partition contains the specified file in its priv-app folder. */
|
||||
public boolean containsPrivPath(@NonNull String path) {
|
||||
return mPrivAppFolder != null
|
||||
&& path.startsWith(mPrivAppFolder.getFile().getPath() + "/");
|
||||
return FileUtils.contains(mOverlayFolder.getFile(), canonicalize(scanFile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,22 +203,24 @@ public class PackagePartitions {
|
||||
* have the correct selinux policies.
|
||||
*/
|
||||
private static class DeferredCanonicalFile {
|
||||
private boolean mIsCanonical;
|
||||
private boolean mIsCanonical = false;
|
||||
|
||||
@NonNull
|
||||
private File mFile;
|
||||
private DeferredCanonicalFile(File dir, String fileName) {
|
||||
mFile = new File(dir, fileName);
|
||||
mIsCanonical = false;
|
||||
|
||||
private DeferredCanonicalFile(@NonNull File dir) {
|
||||
mFile = dir;
|
||||
}
|
||||
|
||||
private DeferredCanonicalFile(@NonNull File dir, @NonNull String fileName) {
|
||||
mFile = new File(dir, fileName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private File getFile() {
|
||||
if (mIsCanonical) {
|
||||
return mFile;
|
||||
}
|
||||
mIsCanonical = true;
|
||||
try {
|
||||
mFile = mFile.getCanonicalFile();
|
||||
} catch (IOException ignore) {
|
||||
// failed to look up canonical path, continue with original one
|
||||
if (!mIsCanonical) {
|
||||
mFile = canonicalize(mFile);
|
||||
mIsCanonical = true;
|
||||
}
|
||||
return mFile;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,9 @@ public class OverlayConfig {
|
||||
} else {
|
||||
// Rebase the system partitions and settings file on the specified root directory.
|
||||
partitions = new ArrayList<>(PackagePartitions.getOrderedPartitions(
|
||||
p -> new OverlayPartition(new File(rootDirectory, p.folder.getPath()), p)));
|
||||
p -> new OverlayPartition(
|
||||
new File(rootDirectory, p.getFolder().getPath()),
|
||||
p)));
|
||||
}
|
||||
|
||||
boolean foundConfigFile = false;
|
||||
@@ -143,7 +145,7 @@ public class OverlayConfig {
|
||||
// Filter out overlays not present in the partition.
|
||||
partitionOverlayInfos = new ArrayList<>(packageManagerOverlayInfos);
|
||||
for (int j = partitionOverlayInfos.size() - 1; j >= 0; j--) {
|
||||
if (!partition.containsPath(partitionOverlayInfos.get(j).path.getPath())) {
|
||||
if (!partition.containsFile(partitionOverlayInfos.get(j).path)) {
|
||||
partitionOverlayInfos.remove(j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
@@ -154,7 +154,7 @@ final class OverlayConfigParser {
|
||||
return POLICY_PRODUCT;
|
||||
default:
|
||||
throw new IllegalStateException("Unable to determine policy for "
|
||||
+ partition.folder);
|
||||
+ partition.getFolder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2711,13 +2711,13 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return SCAN_AS_SYSTEM_EXT;
|
||||
default:
|
||||
throw new IllegalStateException("Unable to determine scan flag for "
|
||||
+ partition.folder);
|
||||
+ partition.getFolder());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return folder.getAbsolutePath() + ":" + scanFlag;
|
||||
return getFolder().getAbsolutePath() + ":" + scanFlag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3283,7 +3283,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
|
||||
@ParseFlags int reparseFlags = 0;
|
||||
@ScanFlags int rescanFlags = 0;
|
||||
for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
|
||||
for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) {
|
||||
final ScanPartition partition = mDirsToScanAsSystem.get(i1);
|
||||
if (partition.containsPrivApp(scanFile)) {
|
||||
reparseFlags = systemParseFlags;
|
||||
@@ -18681,7 +18681,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
|
||||
ScanPartition sp = SYSTEM_PARTITIONS.get(i);
|
||||
if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
|
||||
sp.folder.getAbsolutePath())) {
|
||||
sp.getFolder().getAbsolutePath())) {
|
||||
return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
|
||||
}
|
||||
}
|
||||
@@ -18777,23 +18777,23 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
|
||||
@Nullable PermissionsState origPermissionState, boolean writeSettings)
|
||||
throws PackageManagerException {
|
||||
final File codePath = new File(codePathString);
|
||||
@ParseFlags int parseFlags =
|
||||
mDefParseFlags
|
||||
| PackageParser.PARSE_MUST_BE_APK
|
||||
| PackageParser.PARSE_IS_SYSTEM_DIR;
|
||||
@ScanFlags int scanFlags = SCAN_AS_SYSTEM;
|
||||
for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
|
||||
for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
|
||||
ScanPartition partition = mDirsToScanAsSystem.get(i);
|
||||
if (partition.containsPath(codePathString)) {
|
||||
if (partition.containsFile(codePath)) {
|
||||
scanFlags |= partition.scanFlag;
|
||||
if (partition.containsPrivPath(codePathString)) {
|
||||
if (partition.containsPrivApp(codePath)) {
|
||||
scanFlags |= SCAN_AS_PRIVILEGED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final File codePath = new File(codePathString);
|
||||
final AndroidPackage pkg =
|
||||
scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
|
||||
|
||||
|
||||
@@ -3235,7 +3235,7 @@ public final class Settings {
|
||||
PackageManagerService.ScanPartition partition =
|
||||
PackageManagerService.SYSTEM_PARTITIONS.get(index);
|
||||
|
||||
File preferredDir = new File(partition.folder, "etc/preferred-apps");
|
||||
File preferredDir = new File(partition.getFolder(), "etc/preferred-apps");
|
||||
if (!preferredDir.exists() || !preferredDir.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -122,10 +122,8 @@ public class PackageManagerServiceTest {
|
||||
final PackageManagerService.ScanPartition scanPartition =
|
||||
PackageManagerService.SYSTEM_PARTITIONS.get(i);
|
||||
for (int j = 0; j < appdir.length; j++) {
|
||||
String canonical = new File("/" + partitions[i]).getCanonicalPath();
|
||||
String path = String.format("%s/%s/A.apk", canonical, appdir[j]);
|
||||
|
||||
Assert.assertEquals(j == 1 && i != 3, scanPartition.containsPrivPath(path));
|
||||
File path = new File(String.format("%s/%s/A.apk", partitions[i], appdir[j]));
|
||||
Assert.assertEquals(j == 1 && i != 3, scanPartition.containsPrivApp(path));
|
||||
|
||||
final int scanFlag = scanPartition.scanFlag;
|
||||
Assert.assertEquals(i == 1, scanFlag == PackageManagerService.SCAN_AS_VENDOR);
|
||||
|
||||
Reference in New Issue
Block a user