Merge "Populate error message in case APK part of staged install fails" am: d489721715
Change-Id: Iba18cfa0f48be57f32b38ffaa05d23c18e91d651
This commit is contained in:
@@ -247,11 +247,11 @@ public class StagingManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sessionContainsApk(session)) {
|
if (sessionContainsApk(session)) {
|
||||||
if (!installApksInSession(session, /* preReboot */ true)) {
|
try {
|
||||||
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
|
installApksInSession(session, /* preReboot */ true);
|
||||||
"APK verification failed. Check logcat messages for "
|
|
||||||
+ "more information.");
|
|
||||||
// TODO(b/118865310): abort the session on apexd.
|
// TODO(b/118865310): abort the session on apexd.
|
||||||
|
} catch (PackageManagerException e) {
|
||||||
|
session.setStagedSessionFailed(e.error, e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,7 @@ public class StagingManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resumeSession(@NonNull PackageInstallerSession session) {
|
private void resumeSession(@NonNull PackageInstallerSession session) {
|
||||||
boolean hasApex = sessionContainsApex(session);
|
final boolean hasApex = sessionContainsApex(session);
|
||||||
if (hasApex) {
|
if (hasApex) {
|
||||||
// Check with apexservice whether the apex packages have been activated.
|
// Check with apexservice whether the apex packages have been activated.
|
||||||
ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId);
|
ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId);
|
||||||
@@ -355,10 +355,10 @@ public class StagingManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The APEX part of the session is activated, proceed with the installation of APKs.
|
// The APEX part of the session is activated, proceed with the installation of APKs.
|
||||||
if (!installApksInSession(session, /* preReboot */ false)) {
|
try {
|
||||||
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
|
installApksInSession(session, /* preReboot */ false);
|
||||||
"Staged installation of APKs failed. Check logcat messages for"
|
} catch (PackageManagerException e) {
|
||||||
+ "more information.");
|
session.setStagedSessionFailed(e.error, e.getMessage());
|
||||||
|
|
||||||
if (!hasApex) {
|
if (!hasApex) {
|
||||||
return;
|
return;
|
||||||
@@ -393,16 +393,22 @@ public class StagingManager {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private PackageInstallerSession createAndWriteApkSession(
|
private PackageInstallerSession createAndWriteApkSession(
|
||||||
@NonNull PackageInstallerSession originalSession, boolean preReboot) {
|
@NonNull PackageInstallerSession originalSession, boolean preReboot)
|
||||||
|
throws PackageManagerException {
|
||||||
|
final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
|
||||||
|
: SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
|
||||||
if (originalSession.stageDir == null) {
|
if (originalSession.stageDir == null) {
|
||||||
Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
|
Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
|
||||||
return null;
|
throw new PackageManagerException(errorCode,
|
||||||
|
"Attempting to install a staged APK session with no staging dir");
|
||||||
}
|
}
|
||||||
List<String> apkFilePaths = findAPKsInDir(originalSession.stageDir);
|
List<String> apkFilePaths = findAPKsInDir(originalSession.stageDir);
|
||||||
if (apkFilePaths.isEmpty()) {
|
if (apkFilePaths.isEmpty()) {
|
||||||
Slog.w(TAG, "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
|
Slog.w(TAG, "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
|
||||||
return null;
|
throw new PackageManagerException(errorCode,
|
||||||
|
"Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInstaller.SessionParams params = originalSession.params.copy();
|
PackageInstaller.SessionParams params = originalSession.params.copy();
|
||||||
@@ -428,20 +434,22 @@ public class StagingManager {
|
|||||||
long sizeBytes = (pfd == null) ? -1 : pfd.getStatSize();
|
long sizeBytes = (pfd == null) ? -1 : pfd.getStatSize();
|
||||||
if (sizeBytes < 0) {
|
if (sizeBytes < 0) {
|
||||||
Slog.e(TAG, "Unable to get size of: " + apkFilePath);
|
Slog.e(TAG, "Unable to get size of: " + apkFilePath);
|
||||||
return null;
|
throw new PackageManagerException(errorCode,
|
||||||
|
"Unable to get size of: " + apkFilePath);
|
||||||
}
|
}
|
||||||
apkSession.write(apkFile.getName(), 0, sizeBytes, pfd);
|
apkSession.write(apkFile.getName(), 0, sizeBytes, pfd);
|
||||||
}
|
}
|
||||||
return apkSession;
|
return apkSession;
|
||||||
} catch (IOException | ParcelableException e) {
|
} catch (IOException | ParcelableException e) {
|
||||||
Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e);
|
Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e);
|
||||||
return null;
|
throw new PackageManagerException(errorCode, "Failed to write APK session", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
|
private void commitApkSession(@NonNull PackageInstallerSession apkSession,
|
||||||
int originalSessionId, boolean preReboot) {
|
int originalSessionId, boolean preReboot) throws PackageManagerException {
|
||||||
|
final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
|
||||||
|
: SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
|
||||||
if (!preReboot) {
|
if (!preReboot) {
|
||||||
if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
|
if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
|
||||||
// If rollback is available for this session, notify the rollback
|
// If rollback is available for this session, notify the rollback
|
||||||
@@ -461,23 +469,24 @@ public class StagingManager {
|
|||||||
final Intent result = receiver.getResult();
|
final Intent result = receiver.getResult();
|
||||||
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
|
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
|
||||||
PackageInstaller.STATUS_FAILURE);
|
PackageInstaller.STATUS_FAILURE);
|
||||||
if (status == PackageInstaller.STATUS_SUCCESS) {
|
if (status != PackageInstaller.STATUS_SUCCESS) {
|
||||||
return true;
|
|
||||||
}
|
final String errorMessage = result.getStringExtra(
|
||||||
|
PackageInstaller.EXTRA_STATUS_MESSAGE);
|
||||||
Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
|
Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
|
||||||
+ result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
|
+ errorMessage + "]");
|
||||||
return false;
|
throw new PackageManagerException(errorCode, errorMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean installApksInSession(@NonNull PackageInstallerSession session,
|
private void installApksInSession(@NonNull PackageInstallerSession session,
|
||||||
boolean preReboot) {
|
boolean preReboot) throws PackageManagerException {
|
||||||
|
final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
|
||||||
|
: SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
|
||||||
if (!session.isMultiPackage() && !isApexSession(session)) {
|
if (!session.isMultiPackage() && !isApexSession(session)) {
|
||||||
// APK single-packaged staged session. Do a regular install.
|
// APK single-packaged staged session. Do a regular install.
|
||||||
PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
|
PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
|
||||||
if (apkSession == null) {
|
commitApkSession(apkSession, session.sessionId, preReboot);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return commitApkSession(apkSession, session.sessionId, preReboot);
|
|
||||||
} else if (session.isMultiPackage()) {
|
} else if (session.isMultiPackage()) {
|
||||||
// For multi-package staged sessions containing APKs, we identify which child sessions
|
// For multi-package staged sessions containing APKs, we identify which child sessions
|
||||||
// contain an APK, and with those then create a new multi-package group of sessions,
|
// contain an APK, and with those then create a new multi-package group of sessions,
|
||||||
@@ -495,7 +504,7 @@ public class StagingManager {
|
|||||||
}
|
}
|
||||||
if (childSessions.isEmpty()) {
|
if (childSessions.isEmpty()) {
|
||||||
// APEX-only multi-package staged session, nothing to do.
|
// APEX-only multi-package staged session, nothing to do.
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
PackageInstaller.SessionParams params = session.params.copy();
|
PackageInstaller.SessionParams params = session.params.copy();
|
||||||
params.isStaged = false;
|
params.isStaged = false;
|
||||||
@@ -512,26 +521,24 @@ public class StagingManager {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "Unable to prepare multi-package session for staged session "
|
Slog.e(TAG, "Unable to prepare multi-package session for staged session "
|
||||||
+ session.sessionId);
|
+ session.sessionId);
|
||||||
return false;
|
throw new PackageManagerException(errorCode,
|
||||||
|
"Unable to prepare multi-package session for staged session");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PackageInstallerSession sessionToClone : childSessions) {
|
for (PackageInstallerSession sessionToClone : childSessions) {
|
||||||
PackageInstallerSession apkChildSession =
|
PackageInstallerSession apkChildSession =
|
||||||
createAndWriteApkSession(sessionToClone, preReboot);
|
createAndWriteApkSession(sessionToClone, preReboot);
|
||||||
if (apkChildSession == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
apkParentSession.addChildSessionId(apkChildSession.sessionId);
|
apkParentSession.addChildSessionId(apkChildSession.sessionId);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
Slog.e(TAG, "Failed to add a child session for installing the APK files", e);
|
Slog.e(TAG, "Failed to add a child session for installing the APK files", e);
|
||||||
return false;
|
throw new PackageManagerException(errorCode,
|
||||||
|
"Failed to add a child session " + apkChildSession.sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return commitApkSession(apkParentSession, session.sessionId, preReboot);
|
commitApkSession(apkParentSession, session.sessionId, preReboot);
|
||||||
}
|
}
|
||||||
// APEX single-package staged session, nothing to do.
|
// APEX single-package staged session, nothing to do.
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void commitSession(@NonNull PackageInstallerSession session) {
|
void commitSession(@NonNull PackageInstallerSession session) {
|
||||||
|
|||||||
Reference in New Issue
Block a user