Fix PackageManager query API's related to rebootless APEX updates
There were two bugs: 1. In case of the first update, ApexManager removed information about pre-installed version of the APEX. 2. After an update, getPackageInfo cache wasn't invalidated, which resulted in getPackageInfo returning stale information. Bug: 193085724 Test: atest ApexManagerTest Test: atest StagedInstallInternalTest Change-Id: I6df7b296cd5d83c93524178f1546855747ea6b07
This commit is contained in:
@@ -1051,13 +1051,18 @@ public abstract class ApexManager {
|
||||
final ParsedPackage parsedPackage2 = packageParser.parsePackage(
|
||||
new File(apexInfo.modulePath), flags, /* useCaches= */ false);
|
||||
final PackageInfo finalApexPkg = PackageInfoWithoutStateUtils.generate(
|
||||
parsedPackage, apexInfo, flags);
|
||||
parsedPackage2, apexInfo, flags);
|
||||
// Installation was successful, time to update mAllPackagesCache
|
||||
synchronized (mLock) {
|
||||
for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
|
||||
if (mAllPackagesCache.get(i).equals(existingApexPkg)) {
|
||||
mAllPackagesCache.set(i, finalApexPkg);
|
||||
break;
|
||||
if (isFactory(existingApexPkg)) {
|
||||
existingApexPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
|
||||
mAllPackagesCache.add(finalApexPkg);
|
||||
} else {
|
||||
for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
|
||||
if (mAllPackagesCache.get(i).equals(existingApexPkg)) {
|
||||
mAllPackagesCache.set(i, finalApexPkg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17362,6 +17362,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
} catch (PackageManagerException e) {
|
||||
request.installResult.setError("APEX installation failed", e);
|
||||
}
|
||||
invalidatePackageInfoCache();
|
||||
notifyInstallObserver(request.installResult, request.args.observer);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.apex.ApexSessionInfo;
|
||||
import android.apex.ApexSessionParams;
|
||||
import android.apex.IApexService;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -349,9 +350,9 @@ public class ApexManagerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstallPackage() throws Exception {
|
||||
public void testInstallPackage_activeOnSystem() throws Exception {
|
||||
ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true,
|
||||
/* isFactory= */ false, extractResource("test.apex_rebootless_v1",
|
||||
/* isFactory= */ true, extractResource("test.apex_rebootless_v1",
|
||||
"test.rebootless_apex_v1.apex"));
|
||||
when(mApexService.getAllPackages()).thenReturn(new ApexInfo[]{activeApexInfo});
|
||||
mApexManager.scanApexPackagesTraced(mPackageParser2,
|
||||
@@ -369,6 +370,55 @@ public class ApexManagerTest {
|
||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
|
||||
assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
|
||||
assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
|
||||
assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
|
||||
.isEqualTo(ApplicationInfo.FLAG_INSTALLED);
|
||||
|
||||
PackageInfo factoryInfo = mApexManager.getPackageInfo("test.apex.rebootless",
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(activeApexInfo.modulePath);
|
||||
assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
|
||||
assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
|
||||
.isEqualTo(ApplicationInfo.FLAG_SYSTEM);
|
||||
assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstallPackage_activeOnData() throws Exception {
|
||||
ApexInfo factoryApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ false,
|
||||
/* isFactory= */ true, extractResource("test.apex_rebootless_v1",
|
||||
"test.rebootless_apex_v1.apex"));
|
||||
ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true,
|
||||
/* isFactory= */ false, extractResource("test.apex.rebootless@1",
|
||||
"test.rebootless_apex_v1.apex"));
|
||||
when(mApexService.getAllPackages())
|
||||
.thenReturn(new ApexInfo[]{factoryApexInfo, activeApexInfo});
|
||||
mApexManager.scanApexPackagesTraced(mPackageParser2,
|
||||
ParallelPackageParser.makeExecutorService());
|
||||
|
||||
File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex");
|
||||
ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true,
|
||||
/* isFactory= */ false, finalApex);
|
||||
when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo);
|
||||
|
||||
File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex");
|
||||
mApexManager.installPackage(installedApex, mPackageParser2);
|
||||
|
||||
PackageInfo newInfo = mApexManager.getPackageInfo("test.apex.rebootless",
|
||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
|
||||
assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
|
||||
assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
|
||||
assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
|
||||
.isEqualTo(ApplicationInfo.FLAG_INSTALLED);
|
||||
|
||||
PackageInfo factoryInfo = mApexManager.getPackageInfo("test.apex.rebootless",
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
assertThat(factoryInfo.applicationInfo.sourceDir).isEqualTo(factoryApexInfo.modulePath);
|
||||
assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
|
||||
assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
|
||||
.isEqualTo(ApplicationInfo.FLAG_SYSTEM);
|
||||
assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -212,6 +212,28 @@ public class StagedInstallInternalTest {
|
||||
assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
|
||||
}
|
||||
|
||||
TestApp apex1 = new TestApp("TestRebootlessApexV1", "test.apex.rebootless", 1,
|
||||
/* isApex= */ true, "test.rebootless_apex_v1.apex");
|
||||
Install.single(apex1).commit();
|
||||
|
||||
{
|
||||
PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
|
||||
assertThat(apex.getLongVersionCode()).isEqualTo(1);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
|
||||
.isEqualTo(ApplicationInfo.FLAG_INSTALLED);
|
||||
assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
|
||||
}
|
||||
{
|
||||
PackageInfo apex = pm.getPackageInfo("test.apex.rebootless",
|
||||
PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
|
||||
assertThat(apex.getLongVersionCode()).isEqualTo(1);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
|
||||
.isEqualTo(ApplicationInfo.FLAG_SYSTEM);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
|
||||
assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
|
||||
}
|
||||
|
||||
TestApp apex2 = new TestApp("TestRebootlessApexV1", "test.apex.rebootless", 2,
|
||||
/* isApex= */ true, "test.rebootless_apex_v2.apex");
|
||||
Install.single(apex2).commit();
|
||||
@@ -224,6 +246,15 @@ public class StagedInstallInternalTest {
|
||||
.isEqualTo(ApplicationInfo.FLAG_INSTALLED);
|
||||
assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
|
||||
}
|
||||
{
|
||||
PackageInfo apex = pm.getPackageInfo("test.apex.rebootless",
|
||||
PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
|
||||
assertThat(apex.getLongVersionCode()).isEqualTo(1);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
|
||||
.isEqualTo(ApplicationInfo.FLAG_SYSTEM);
|
||||
assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
|
||||
assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertSessionFailedWithMessage(int sessionId, String msg) {
|
||||
|
||||
Reference in New Issue
Block a user