Add PackageInstallerSession#getChildSessions (1/n)

Use this method to retrieve child sessions without an additional call
to mStagedSessions.get(id).

Note now getChildSessions[Locked] returns an empty list for a
single-session. The caller should check isMultiPackage() before dealing
with child sessions.

Bug: 167946370
Test: atest StagedInstallTest StagedInstallInternalTest
Change-Id: I186a5f16fd4107994f6426ebca9b16186f7b2cb8
This commit is contained in:
JW Wang
2020-09-07 16:22:37 +08:00
parent 74cf2df463
commit 1acf5d2fe7
2 changed files with 26 additions and 43 deletions

View File

@@ -155,6 +155,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -1522,8 +1523,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
@GuardedBy("mLock")
private @Nullable List<PackageInstallerSession> getChildSessionsLocked() {
List<PackageInstallerSession> childSessions = null;
private @NonNull List<PackageInstallerSession> getChildSessionsLocked() {
List<PackageInstallerSession> childSessions = Collections.EMPTY_LIST;
if (isMultiPackage()) {
int size = mChildSessions.size();
childSessions = new ArrayList<>(size);
@@ -1534,6 +1535,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return childSessions;
}
@NonNull List<PackageInstallerSession> getChildSessions() {
synchronized (mLock) {
return getChildSessionsLocked();
}
}
/**
* Seal the session to prevent further modification.
*
@@ -3484,7 +3491,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
private void cleanStageDir(List<PackageInstallerSession> childSessions) {
if (childSessions != null) {
if (isMultiPackage()) {
for (PackageInstallerSession childSession : childSessions) {
childSession.cleanStageDir();
}

View File

@@ -240,9 +240,9 @@ public class StagingManager {
@NonNull PackageInstallerSession session) throws PackageManagerException {
final IntArray childSessionIds = new IntArray();
if (session.isMultiPackage()) {
for (int id : session.getChildSessionIds()) {
if (isApexSession(getStagedSession(id))) {
childSessionIds.add(id);
for (PackageInstallerSession s : session.getChildSessions()) {
if (isApexSession(s)) {
childSessionIds.add(s.sessionId);
}
}
}
@@ -356,18 +356,12 @@ public class StagingManager {
if (!session.isMultiPackage()) {
return filter.test(session);
}
synchronized (mStagedSessions) {
final int[] childSessionIds = session.getChildSessionIds();
for (int id : childSessionIds) {
// Retrieve cached sessions matching ids.
final PackageInstallerSession s = mStagedSessions.get(id);
// Filter only the ones containing APEX.
if (filter.test(s)) {
return true;
}
for (PackageInstallerSession s : session.getChildSessions()) {
if (filter.test(s)) {
return true;
}
return false;
}
return false;
}
private boolean sessionContainsApex(@NonNull PackageInstallerSession session) {
@@ -423,19 +417,9 @@ public class StagingManager {
private List<PackageInstallerSession> extractApexSessions(PackageInstallerSession session) {
List<PackageInstallerSession> apexSessions = new ArrayList<>();
if (session.isMultiPackage()) {
List<PackageInstallerSession> childrenSessions = new ArrayList<>();
synchronized (mStagedSessions) {
for (int childSessionId : session.getChildSessionIds()) {
PackageInstallerSession childSession = mStagedSessions.get(childSessionId);
if (childSession != null) {
childrenSessions.add(childSession);
}
}
}
for (int i = 0, size = childrenSessions.size(); i < size; i++) {
final PackageInstallerSession childSession = childrenSessions.get(i);
if (sessionContainsApex(childSession)) {
apexSessions.add(childSession);
for (PackageInstallerSession s : session.getChildSessions()) {
if (sessionContainsApex(s)) {
apexSessions.add(s);
}
}
} else {
@@ -782,13 +766,9 @@ public class StagingManager {
// carrying over all the session parameters and unmarking them as staged. On commit the
// sessions will be installed atomically.
final List<PackageInstallerSession> childSessions = new ArrayList<>();
synchronized (mStagedSessions) {
final int[] childSessionIds = session.getChildSessionIds();
for (int id : childSessionIds) {
final PackageInstallerSession s = mStagedSessions.get(id);
if (!isApexSession(s)) {
childSessions.add(s);
}
for (PackageInstallerSession s : session.getChildSessions()) {
if (!isApexSession(s)) {
childSessions.add(s);
}
}
if (childSessions.isEmpty()) {
@@ -834,14 +814,10 @@ public class StagingManager {
if (!session.isMultiPackage()) {
return;
}
final int[] childSessionIds = session.getChildSessionIds();
final Set<String> apkNames = new ArraySet<>();
synchronized (mStagedSessions) {
for (int id : childSessionIds) {
final PackageInstallerSession s = mStagedSessions.get(id);
if (!isApexSession(s)) {
apkNames.add(s.getPackageName());
}
for (PackageInstallerSession s : session.getChildSessions()) {
if (!isApexSession(s)) {
apkNames.add(s.getPackageName());
}
}
final List<PackageInstallerSession> apexSessions = extractApexSessions(session);