Merge "Handles child failure on session validate" into rvc-dev am: eb29d9ac77
Change-Id: I7f41b4d16a423c100fdc3d184d79f188ffdd09bc
This commit is contained in:
@@ -1122,21 +1122,52 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleStreamValidateAndCommit() {
|
private void handleStreamValidateAndCommit() {
|
||||||
boolean success = streamValidateAndCommit();
|
PackageManagerException unrecoverableFailure = null;
|
||||||
|
// This will track whether the session and any children were validated and are ready to
|
||||||
|
// progress to the next phase of install
|
||||||
|
boolean allSessionsReady = false;
|
||||||
|
try {
|
||||||
|
allSessionsReady = streamValidateAndCommit();
|
||||||
|
} catch (PackageManagerException e) {
|
||||||
|
unrecoverableFailure = e;
|
||||||
|
}
|
||||||
|
|
||||||
if (isMultiPackage()) {
|
if (isMultiPackage()) {
|
||||||
for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
|
int childCount = mChildSessionIds.size();
|
||||||
|
|
||||||
|
// This will contain all child sessions that do not encounter an unrecoverable failure
|
||||||
|
ArrayList<PackageInstallerSession> nonFailingSessions = new ArrayList<>(childCount);
|
||||||
|
|
||||||
|
for (int i = childCount - 1; i >= 0; --i) {
|
||||||
final int childSessionId = mChildSessionIds.keyAt(i);
|
final int childSessionId = mChildSessionIds.keyAt(i);
|
||||||
// commit all children, regardless if any of them fail; we'll throw/return
|
// commit all children, regardless if any of them fail; we'll throw/return
|
||||||
// as appropriate once all children have been processed
|
// as appropriate once all children have been processed
|
||||||
if (!mSessionProvider.getSession(childSessionId)
|
try {
|
||||||
.streamValidateAndCommit()) {
|
PackageInstallerSession session = mSessionProvider.getSession(childSessionId);
|
||||||
success = false;
|
if (!session.streamValidateAndCommit()) {
|
||||||
|
allSessionsReady = false;
|
||||||
|
}
|
||||||
|
nonFailingSessions.add(session);
|
||||||
|
} catch (PackageManagerException e) {
|
||||||
|
allSessionsReady = false;
|
||||||
|
if (unrecoverableFailure == null) {
|
||||||
|
unrecoverableFailure = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we encountered any unrecoverable failures, destroy all
|
||||||
|
// other impacted sessions besides the parent; that will be cleaned up by the
|
||||||
|
// ChildStatusIntentReceiver.
|
||||||
|
if (unrecoverableFailure != null) {
|
||||||
|
// fail other child sessions that did not already fail
|
||||||
|
for (int i = nonFailingSessions.size() - 1; i >= 0; --i) {
|
||||||
|
PackageInstallerSession session = nonFailingSessions.get(i);
|
||||||
|
session.onSessionVerificationFailure(unrecoverableFailure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!allSessionsReady) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,14 +1247,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
|
mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
|
||||||
} catch (IntentSender.SendIntentException ignore) {
|
} catch (IntentSender.SendIntentException ignore) {
|
||||||
}
|
}
|
||||||
} else {
|
} else { // failure, let's forward and clean up this session.
|
||||||
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID,
|
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID,
|
||||||
PackageInstallerSession.this.sessionId);
|
PackageInstallerSession.this.sessionId);
|
||||||
mChildSessionsRemaining.clear(); // we're done. Don't send any more.
|
mChildSessionsRemaining.clear(); // we're done. Don't send any more.
|
||||||
try {
|
onSessionVerificationFailure(status,
|
||||||
mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
|
intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE));
|
||||||
} catch (IntentSender.SendIntentException ignore) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1329,7 +1358,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean streamValidateAndCommit() {
|
/**
|
||||||
|
* Returns true if the session is successfully validated and committed. Returns false if the
|
||||||
|
* dataloader could not be prepared. This can be called multiple times so long as no
|
||||||
|
* exception is thrown.
|
||||||
|
* @throws PackageManagerException on an unrecoverable error.
|
||||||
|
*/
|
||||||
|
private boolean streamValidateAndCommit() throws PackageManagerException {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mCommitted) {
|
if (mCommitted) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1349,7 +1384,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
|
|
||||||
mCommitted = true;
|
mCommitted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1449,10 +1483,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
* Prepare DataLoader and stream content for DataLoader sessions.
|
* Prepare DataLoader and stream content for DataLoader sessions.
|
||||||
* Validate the contents of all session.
|
* Validate the contents of all session.
|
||||||
*
|
*
|
||||||
* @return false if validation failed.
|
* @return false if the data loader could not be prepared.
|
||||||
|
* @throws PackageManagerException when an unrecoverable exception is encountered
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private boolean streamAndValidateLocked() {
|
private boolean streamAndValidateLocked() throws PackageManagerException {
|
||||||
try {
|
try {
|
||||||
// Read transfers from the original owner stay open, but as the session's data cannot
|
// Read transfers from the original owner stay open, but as the session's data cannot
|
||||||
// be modified anymore, there is no leak of information. For staged sessions, further
|
// be modified anymore, there is no leak of information. For staged sessions, further
|
||||||
@@ -1472,16 +1507,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
if (params.isStaged) {
|
if (params.isStaged) {
|
||||||
mStagingManager.checkNonOverlappingWithStagedSessions(this);
|
mStagingManager.checkNonOverlappingWithStagedSessions(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (PackageManagerException e) {
|
} catch (PackageManagerException e) {
|
||||||
onSessionVerificationFailure(e);
|
throw onSessionVerificationFailure(e);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Convert all exceptions into package manager exceptions as only those are handled
|
// Convert all exceptions into package manager exceptions as only those are handled
|
||||||
// in the code above.
|
// in the code above.
|
||||||
onSessionVerificationFailure(new PackageManagerException(e));
|
throw onSessionVerificationFailure(new PackageManagerException(e));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PackageManagerException onSessionVerificationFailure(PackageManagerException e) {
|
private PackageManagerException onSessionVerificationFailure(PackageManagerException e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user