Loading services/core/java/com/android/server/pm/PackageInstallerService.java +10 −3 Original line number Diff line number Diff line Loading @@ -1661,10 +1661,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } synchronized (mSessions) { // Child sessions will be removed along with its parent as a whole if (!session.hasParentSessionId() && (!session.isStaged() || session.isDestroyed())) { if (!session.hasParentSessionId()) { // Retain policy: // 1. Don't keep non-staged sessions // 2. Don't keep explicitly abandoned sessions // 3. Don't keep sessions that fail validation (isCommitted() is false) boolean shouldRemove = !session.isStaged() || session.isDestroyed() || !session.isCommitted(); if (shouldRemove) { removeActiveSession(session); } } final File appIconFile = buildAppIconFile(session.sessionId); if (appIconFile.exists()) { Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +14 −53 Original line number Diff line number Diff line Loading @@ -1734,61 +1734,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @WorkerThread private void handleStreamValidateAndCommit() { PackageManagerException unrecoverableFailure = null; try { // 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; boolean allSessionsReady = true; for (PackageInstallerSession child : getChildSessions()) { allSessionsReady &= child.streamValidateAndCommit(); } if (isMultiPackage()) { final List<PackageInstallerSession> childSessions; synchronized (mLock) { childSessions = getChildSessionsLocked(); if (allSessionsReady && streamValidateAndCommit()) { mHandler.obtainMessage(MSG_INSTALL).sendToTarget(); } int childCount = childSessions.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) { // commit all children, regardless if any of them fail; we'll throw/return // as appropriate once all children have been processed try { PackageInstallerSession session = childSessions.get(i); allSessionsReady &= session.streamValidateAndCommit(); nonFailingSessions.add(session); } catch (PackageManagerException e) { allSessionsReady = false; if (unrecoverableFailure == null) { unrecoverableFailure = e; } } } // If we encountered any unrecoverable failures, destroy all other sessions including // the parent if (unrecoverableFailure != null) { // {@link #streamValidateAndCommit()} calls // {@link #onSessionValidationFailure(PackageManagerException)}, but we don't // expect it to ever do so for parent sessions. Call that on this parent to clean // it up and notify listeners of the error. onSessionValidationFailure(unrecoverableFailure); // fail other child sessions that did not already fail for (int i = nonFailingSessions.size() - 1; i >= 0; --i) { PackageInstallerSession session = nonFailingSessions.get(i); session.onSessionValidationFailure(unrecoverableFailure); } } } if (!allSessionsReady) { return; destroy(); String msg = ExceptionUtils.getCompleteMessage(e); dispatchSessionFinished(e.error, msg, null); maybeFinishChildSessions(e.error, msg); } mHandler.obtainMessage(MSG_INSTALL).sendToTarget(); } private final class FileSystemConnector extends Loading Loading @@ -2026,11 +1987,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } return true; } catch (PackageManagerException e) { throw onSessionValidationFailure(e); throw e; } catch (Throwable e) { // Convert all exceptions into package manager exceptions as only those are handled // in the code above. throw onSessionValidationFailure(new PackageManagerException(e)); throw new PackageManagerException(e); } } Loading Loading
services/core/java/com/android/server/pm/PackageInstallerService.java +10 −3 Original line number Diff line number Diff line Loading @@ -1661,10 +1661,17 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } synchronized (mSessions) { // Child sessions will be removed along with its parent as a whole if (!session.hasParentSessionId() && (!session.isStaged() || session.isDestroyed())) { if (!session.hasParentSessionId()) { // Retain policy: // 1. Don't keep non-staged sessions // 2. Don't keep explicitly abandoned sessions // 3. Don't keep sessions that fail validation (isCommitted() is false) boolean shouldRemove = !session.isStaged() || session.isDestroyed() || !session.isCommitted(); if (shouldRemove) { removeActiveSession(session); } } final File appIconFile = buildAppIconFile(session.sessionId); if (appIconFile.exists()) { Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +14 −53 Original line number Diff line number Diff line Loading @@ -1734,61 +1734,22 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @WorkerThread private void handleStreamValidateAndCommit() { PackageManagerException unrecoverableFailure = null; try { // 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; boolean allSessionsReady = true; for (PackageInstallerSession child : getChildSessions()) { allSessionsReady &= child.streamValidateAndCommit(); } if (isMultiPackage()) { final List<PackageInstallerSession> childSessions; synchronized (mLock) { childSessions = getChildSessionsLocked(); if (allSessionsReady && streamValidateAndCommit()) { mHandler.obtainMessage(MSG_INSTALL).sendToTarget(); } int childCount = childSessions.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) { // commit all children, regardless if any of them fail; we'll throw/return // as appropriate once all children have been processed try { PackageInstallerSession session = childSessions.get(i); allSessionsReady &= session.streamValidateAndCommit(); nonFailingSessions.add(session); } catch (PackageManagerException e) { allSessionsReady = false; if (unrecoverableFailure == null) { unrecoverableFailure = e; } } } // If we encountered any unrecoverable failures, destroy all other sessions including // the parent if (unrecoverableFailure != null) { // {@link #streamValidateAndCommit()} calls // {@link #onSessionValidationFailure(PackageManagerException)}, but we don't // expect it to ever do so for parent sessions. Call that on this parent to clean // it up and notify listeners of the error. onSessionValidationFailure(unrecoverableFailure); // fail other child sessions that did not already fail for (int i = nonFailingSessions.size() - 1; i >= 0; --i) { PackageInstallerSession session = nonFailingSessions.get(i); session.onSessionValidationFailure(unrecoverableFailure); } } } if (!allSessionsReady) { return; destroy(); String msg = ExceptionUtils.getCompleteMessage(e); dispatchSessionFinished(e.error, msg, null); maybeFinishChildSessions(e.error, msg); } mHandler.obtainMessage(MSG_INSTALL).sendToTarget(); } private final class FileSystemConnector extends Loading Loading @@ -2026,11 +1987,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } return true; } catch (PackageManagerException e) { throw onSessionValidationFailure(e); throw e; } catch (Throwable e) { // Convert all exceptions into package manager exceptions as only those are handled // in the code above. throw onSessionValidationFailure(new PackageManagerException(e)); throw new PackageManagerException(e); } } Loading