Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 929235fb authored by Mohammad Samiul Islam's avatar Mohammad Samiul Islam Committed by Android (Google) Code Review
Browse files

Merge "Propagate error while scanning apk-in-apex to session object" into sc-dev

parents 2578be81 dde0b336
Loading
Loading
Loading
Loading
+19 −14
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutorService;
@@ -306,17 +307,19 @@ public abstract class ApexManager {
    /**
    /**
     * Reports error raised during installation of apk-in-apex.
     * Reports error raised during installation of apk-in-apex.
     *
     *
     * @param scanDir the directory of the apex inside which apk-in-apex resides.
     * @param scanDirPath the directory of the apex inside which apk-in-apex resides.
     * @param errorMsg the actual error that occurred when scanning the path
     */
     */
    abstract void reportErrorWithApkInApex(String scanDirPath);
    abstract void reportErrorWithApkInApex(String scanDirPath, String errorMsg);


    /**
    /**
     * Returns true if there were no errors when installing apk-in-apex inside
     * Returns null if there were no errors when installing apk-in-apex inside
     * {@param apexPackageName}, otherwise false.
     * {@param apexPackageName}, otherwise returns the error as string
     *
     *
     * @param apexPackageName Package name of the apk container of apex
     * @param apexPackageName Package name of the apk container of apex
     */
     */
    abstract boolean isApkInApexInstallSuccess(String apexPackageName);
    @Nullable
    abstract String getApkInApexInstallError(String apexPackageName);


    /**
    /**
     * Returns list of {@code packageName} of apks inside the given apex.
     * Returns list of {@code packageName} of apks inside the given apex.
@@ -438,7 +441,7 @@ public abstract class ApexManager {
         * inside {@code apexModuleName}.
         * inside {@code apexModuleName}.
         */
         */
        @GuardedBy("mLock")
        @GuardedBy("mLock")
        private Set<String> mErrorWithApkInApex = new ArraySet<>();
        private Map<String, String> mErrorWithApkInApex = new ArrayMap<>();


        @GuardedBy("mLock")
        @GuardedBy("mLock")
        private List<PackageInfo> mAllPackagesCache;
        private List<PackageInfo> mAllPackagesCache;
@@ -841,26 +844,27 @@ public abstract class ApexManager {
        }
        }


        @Override
        @Override
        void reportErrorWithApkInApex(String scanDirPath) {
        void reportErrorWithApkInApex(String scanDirPath, String errorMsg) {
            synchronized (mLock) {
            synchronized (mLock) {
                for (ActiveApexInfo aai : mActiveApexInfosCache) {
                for (ActiveApexInfo aai : mActiveApexInfosCache) {
                    if (scanDirPath.startsWith(aai.apexDirectory.getAbsolutePath())) {
                    if (scanDirPath.startsWith(aai.apexDirectory.getAbsolutePath())) {
                        mErrorWithApkInApex.add(aai.apexModuleName);
                        mErrorWithApkInApex.put(aai.apexModuleName, errorMsg);
                    }
                    }
                }
                }
            }
            }
        }
        }


        @Override
        @Override
        boolean isApkInApexInstallSuccess(String apexPackageName) {
        @Nullable
        String getApkInApexInstallError(String apexPackageName) {
            synchronized (mLock) {
            synchronized (mLock) {
                Preconditions.checkState(mPackageNameToApexModuleName != null,
                Preconditions.checkState(mPackageNameToApexModuleName != null,
                        "APEX packages have not been scanned");
                        "APEX packages have not been scanned");
                String moduleName = mPackageNameToApexModuleName.get(apexPackageName);
                String moduleName = mPackageNameToApexModuleName.get(apexPackageName);
                if (moduleName == null) {
                if (moduleName == null) {
                    return false;
                    return null;
                }
                }
                return !mErrorWithApkInApex.contains(moduleName);
                return mErrorWithApkInApex.get(moduleName);
            }
            }
        }
        }


@@ -1273,13 +1277,14 @@ public abstract class ApexManager {
        }
        }


        @Override
        @Override
        void reportErrorWithApkInApex(String scanDirPath) {
        void reportErrorWithApkInApex(String scanDirPath, String errorMsg) {
            // No-op
            // No-op
        }
        }


        @Override
        @Override
        boolean isApkInApexInstallSuccess(String apexPackageName) {
        @Nullable
            return true;
        String getApkInApexInstallError(String apexPackageName) {
            return null;
        }
        }


        @Override
        @Override
+6 −3
Original line number Original line Diff line number Diff line
@@ -11824,6 +11824,7 @@ public class PackageManagerService extends IPackageManager.Stub
            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
            Throwable throwable = parseResult.throwable;
            Throwable throwable = parseResult.throwable;
            int errorCode = PackageManager.INSTALL_SUCCEEDED;
            int errorCode = PackageManager.INSTALL_SUCCEEDED;
            String errorMsg = null;
            if (throwable == null) {
            if (throwable == null) {
                // TODO(toddke): move lower in the scan chain
                // TODO(toddke): move lower in the scan chain
@@ -11836,20 +11837,22 @@ public class PackageManagerService extends IPackageManager.Stub
                            currentTime, null);
                            currentTime, null);
                } catch (PackageManagerException e) {
                } catch (PackageManagerException e) {
                    errorCode = e.error;
                    errorCode = e.error;
                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
                    errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
                    Slog.w(TAG, errorMsg);
                }
                }
            } else if (throwable instanceof PackageParserException) {
            } else if (throwable instanceof PackageParserException) {
                PackageParserException e = (PackageParserException)
                PackageParserException e = (PackageParserException)
                        throwable;
                        throwable;
                errorCode = e.error;
                errorCode = e.error;
                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
                errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage();
                Slog.w(TAG, errorMsg);
            } else {
            } else {
                throw new IllegalStateException("Unexpected exception occurred while parsing "
                throw new IllegalStateException("Unexpected exception occurred while parsing "
                        + parseResult.scanFile, throwable);
                        + parseResult.scanFile, throwable);
            }
            }
            if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
            if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
                mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath());
                mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg);
            }
            }
            // Delete invalid userdata apps
            // Delete invalid userdata apps
+11 −5
Original line number Original line Diff line number Diff line
@@ -425,9 +425,10 @@ public class StagingManager {


        for (StagedSession apexSession : apexSessions) {
        for (StagedSession apexSession : apexSessions) {
            String packageName = apexSession.getPackageName();
            String packageName = apexSession.getPackageName();
            if (!mApexManager.isApkInApexInstallSuccess(packageName)) {
            String errorMsg = mApexManager.getApkInApexInstallError(packageName);
            if (errorMsg != null) {
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                        "Failed to install apk-in-apex of " + packageName);
                        "Failed to install apk-in-apex of " + packageName + " : " + errorMsg);
            }
            }
        }
        }
    }
    }
@@ -955,12 +956,17 @@ public class StagingManager {
                continue;
                continue;
            } else if (isApexSessionFailed(apexSession)) {
            } else if (isApexSessionFailed(apexSession)) {
                hasFailedApexSession = true;
                hasFailedApexSession = true;
                String errorMsg = "APEX activation failed. " + apexSession.errorMessage;
                if (!TextUtils.isEmpty(apexSession.crashingNativeProcess)) {
                if (!TextUtils.isEmpty(apexSession.crashingNativeProcess)) {
                    prepareForLoggingApexdRevert(session, apexSession.crashingNativeProcess);
                    prepareForLoggingApexdRevert(session, apexSession.crashingNativeProcess);
                    errorMsg = "Session reverted due to crashing native process: "
                            + apexSession.crashingNativeProcess;
                }
                }
                String errorMsg = "APEX activation failed.";
                final String reasonForRevert = getReasonForRevert();
                if (!TextUtils.isEmpty(reasonForRevert)) {
                    errorMsg += " Reason: " + reasonForRevert;
                } else if (!TextUtils.isEmpty(apexSession.errorMessage)) {
                    errorMsg += " Error: " + apexSession.errorMessage;
                }
                Slog.d(TAG, errorMsg);
                session.setSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg);
                session.setSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMsg);
                continue;
                continue;
            } else if (apexSession.isActivated || apexSession.isSuccess) {
            } else if (apexSession.isActivated || apexSession.isSuccess) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -311,7 +311,7 @@ public class StagingManagerTest {
        assertThat(apexSession1.getErrorCode())
        assertThat(apexSession1.getErrorCode())
                .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
                .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
        assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. "
        assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. "
                + "Failed for test");
                + "Error: Failed for test");


        assertThat(apexSession2.getErrorCode())
        assertThat(apexSession2.getErrorCode())
                .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
                .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED);
+5 −3
Original line number Original line Diff line number Diff line
@@ -286,9 +286,11 @@ public class ApexManagerTest {
        mApexManager.scanApexPackagesTraced(mPackageParser2,
        mApexManager.scanApexPackagesTraced(mPackageParser2,
                ParallelPackageParser.makeExecutorService());
                ParallelPackageParser.makeExecutorService());


        assertThat(mApexManager.isApkInApexInstallSuccess(activeApex.apexModuleName)).isTrue();
        assertThat(mApexManager.getApkInApexInstallError(activeApex.apexModuleName)).isNull();
        mApexManager.reportErrorWithApkInApex(activeApex.apexDirectory.getAbsolutePath());
        mApexManager.reportErrorWithApkInApex(activeApex.apexDirectory.getAbsolutePath(),
        assertThat(mApexManager.isApkInApexInstallSuccess(activeApex.apexModuleName)).isFalse();
                "Some random error");
        assertThat(mApexManager.getApkInApexInstallError(activeApex.apexModuleName))
            .isEqualTo("Some random error");
    }
    }


    /**
    /**