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

Commit c96c83ea authored by Songchun Fan's avatar Songchun Fan
Browse files

[pm/metrics][6/n] log install failures

snapshot is no longer needed because the installerPackageUid is now part
of InstallSource, which we can log for both succeeded and failed
installs.

Notice that we still need to track verification errors.

BUG: 249294752
Test: manual
Change-Id: I9a39888d7bb1b200ac9e77c596b0560cf96a36b5
parent f052ba7e
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ final class InstallRequest {
    /** Package Installed Info */
    @Nullable
    private String mName;
    private int mUid = -1;
    private int mUid = INVALID_UID;
    // The set of users that originally had this package installed.
    @Nullable
    private int[] mOrigUsers;
@@ -317,6 +317,11 @@ final class InstallRequest {
                ? mInstallArgs.mInstallSource.mInstallerPackageName : null;
    }

    public int getInstallerPackageUid() {
        return (mInstallArgs != null && mInstallArgs.mInstallSource != null)
                ? mInstallArgs.mInstallSource.mInstallerPackageUid : INVALID_UID;
    }

    public int getDataLoaderType() {
        return mInstallArgs == null ? DataLoaderType.NONE : mInstallArgs.mDataLoaderType;
    }
@@ -608,12 +613,18 @@ final class InstallRequest {
        setReturnCode(code);
        setReturnMessage(msg);
        Slog.w(TAG, msg);
        if (mPackageMetrics != null) {
            mPackageMetrics.onInstallFailed();
        }
    }

    public void setError(String msg, PackageManagerException e) {
        mReturnCode = e.error;
        setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
        Slog.w(TAG, msg, e);
        if (mPackageMetrics != null) {
            mPackageMetrics.onInstallFailed();
        }
    }

    public void setReturnCode(int returnCode) {
@@ -757,10 +768,10 @@ final class InstallRequest {
        }
    }

    public void onInstallCompleted(Computer snapshot) {
    public void onInstallCompleted() {
        if (getReturnCode() == INSTALL_SUCCEEDED) {
            if (mPackageMetrics != null) {
                mPackageMetrics.onInstallSucceed(snapshot);
                mPackageMetrics.onInstallSucceed();
            }
        }
    }
+42 −20
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ class InstallingSession {
     * policy if needed and then create install arguments based
     * on the install location.
     */
    private void handleStartCopy() {
    private void handleStartCopy(InstallRequest request) {
        if ((mInstallFlags & PackageManager.INSTALL_APEX) != 0) {
            mRet = INSTALL_SUCCEEDED;
            return;
@@ -239,6 +239,7 @@ class InstallingSession {
                    pkgLite, mRequiredInstalledVersionCode, mInstallFlags);
            mRet = ret.first;
            if (mRet != INSTALL_SUCCEEDED) {
                request.setError(mRet, "Failed to verify version code");
                return;
            }
        }
@@ -258,14 +259,16 @@ class InstallingSession {
        }
        mRet = overrideInstallLocation(pkgLite.packageName, pkgLite.recommendedInstallLocation,
                pkgLite.installLocation);
        if (mRet != INSTALL_SUCCEEDED) {
            request.setError(mRet, "Failed to override installation location");
        }
    }

    private void handleReturnCode() {
        processPendingInstall();
    private void handleReturnCode(InstallRequest installRequest) {
        processPendingInstall(installRequest);
    }

    private void processPendingInstall() {
        InstallRequest installRequest = new InstallRequest(this);
    private void processPendingInstall(InstallRequest installRequest) {
        if (mRet == PackageManager.INSTALL_SUCCEEDED) {
            mRet = copyApk(installRequest);
        }
@@ -302,21 +305,26 @@ class InstallingSession {
                request.setCodeFile(mOriginInfo.mFile);
                return PackageManager.INSTALL_SUCCEEDED;
            }

            int ret;
            try {
                final boolean isEphemeral =
                        (mInstallFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
                request.setCodeFile(
                        mPm.mInstallerService.allocateStageDirLegacy(mVolumeUuid, isEphemeral));
            } catch (IOException e) {
                Slog.w(TAG, "Failed to create copy file: " + e);
                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                final String errorMessage = "Failed to create copy file";
                Slog.w(TAG, errorMessage + ": " + e);
                ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                request.setError(ret, errorMessage);
                return ret;
            }

            int ret = PackageManagerServiceUtils.copyPackage(
            ret = PackageManagerServiceUtils.copyPackage(
                    mOriginInfo.mFile.getAbsolutePath(), request.getCodeFile());
            if (ret != PackageManager.INSTALL_SUCCEEDED) {
                Slog.e(TAG, "Failed to copy package");
                final String errorMessage = "Failed to copy package";
                Slog.e(TAG, errorMessage);
                request.setError(ret, errorMessage);
                return ret;
            }

@@ -329,8 +337,10 @@ class InstallingSession {
                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                        request.getAbiOverride(), isIncremental);
            } catch (IOException e) {
                Slog.e(TAG, "Copying native libraries failed", e);
                final String errorMessage = "Copying native libraries failed";
                Slog.e(TAG, errorMessage, e);
                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                request.setError(ret, errorMessage);
            } finally {
                IoUtils.closeQuietly(handle);
            }
@@ -352,8 +362,11 @@ class InstallingSession {
                        mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
                        mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
            } catch (Installer.InstallerException e) {
                Slog.w(TAG, "Failed to move app", e);
                return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                final String errorMessage = "Failed to move app";
                final int ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                request.setError(ret, errorMessage);
                Slog.w(TAG, errorMessage, e);
                return ret;
            }
        }

@@ -456,8 +469,9 @@ class InstallingSession {
        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(this));
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startInstall");
        handleStartCopy();
        handleReturnCode();
        InstallRequest installRequest = new InstallRequest(this);
        handleStartCopy(installRequest);
        handleReturnCode(installRequest);
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

@@ -518,7 +532,7 @@ class InstallingSession {
            mInstallPackageHelper.installPackagesTraced(installRequests);

            for (InstallRequest request : installRequests) {
                request.onInstallCompleted(mPm.snapshotComputer());
                request.onInstallCompleted();
                doPostInstall(request);
            }
        }
@@ -635,11 +649,18 @@ class InstallingSession {
            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                    System.identityHashCode(this));
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "start");
            for (InstallingSession childInstallingSession : mChildInstallingSessions) {
                childInstallingSession.handleStartCopy();

            final int numChildSessions = mChildInstallingSessions.size();
            final ArrayList<InstallRequest> installRequests = new ArrayList<>(numChildSessions);

            for (int i = 0; i < numChildSessions; i++) {
                final InstallingSession childSession = mChildInstallingSessions.get(i);
                final InstallRequest installRequest = new InstallRequest(childSession);
                installRequests.add(installRequest);
                childSession.handleStartCopy(installRequest);
            }
            for (InstallingSession childInstallingSession : mChildInstallingSessions) {
                childInstallingSession.handleReturnCode();
            for (int i = 0; i < numChildSessions; i++) {
                mChildInstallingSessions.get(i).handleReturnCode(installRequests.get(i));
            }
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
@@ -647,6 +668,7 @@ class InstallingSession {
        public void tryProcessInstallRequest(InstallRequest request) {
            mCurrentInstallRequests.add(request);
            if (mCurrentInstallRequests.size() != mChildInstallingSessions.size()) {
                // Wait until all the installRequests have finished copying
                return;
            }
            int completeStatus = PackageManager.INSTALL_SUCCEEDED;
+27 −16
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.server.pm;

import static android.os.Process.INVALID_UID;

import android.annotation.IntDef;
import android.content.pm.PackageManager;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -26,7 +24,6 @@ import android.util.SparseArray;

import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.pm.pkg.PackageStateInternal;

import java.io.File;
import java.io.IOException;
@@ -68,32 +65,46 @@ final class PackageMetrics {
        mInstallRequest = installRequest;
    }

    public void onInstallSucceed(Computer snapshot) {
    public void onInstallSucceed() {
        // TODO(b/239722919): report to SecurityLog if on work profile or managed device
        reportInstallationStats(snapshot, true /* success */);
        reportInstallationStats(true /* success */);
    }

    public void onInstallFailed() {
        reportInstallationStats(false /* success */);
    }

    private void reportInstallationStats(Computer snapshot, boolean success) {
    private void reportInstallationStats(boolean success) {
        UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        // TODO(b/249294752): do not log if adb
        final long installDurationMillis =
                System.currentTimeMillis() - mInstallStartTimestampMillis;
        // write to stats
        final Pair<int[], long[]> stepDurations = getInstallStepDurations();
        final int[] newUsers = mInstallRequest.getNewUsers();
        final int[] originalUsers = mInstallRequest.getOriginUsers();
        final String packageName = mInstallRequest.getName();
        final String installerPackageName = mInstallRequest.getInstallerPackageName();
        final int installerUid = installerPackageName == null ? INVALID_UID
                : snapshot.getPackageUid(installerPackageName, 0, 0);
        final PackageStateInternal ps = snapshot.getPackageStateInternal(packageName);
        final long versionCode = success ? 0 : ps.getVersionCode();
        final long apksSize = getApksSize(ps.getPath());
        final String packageName;
        // only reporting package name for failed non-adb installations
        if (success || mInstallRequest.isInstallFromAdb()) {
            packageName = null;
        } else {
            packageName = mInstallRequest.getName();
        }

        final int installerPackageUid = mInstallRequest.getInstallerPackageUid();

        long versionCode = 0, apksSize = 0;
        if (success) {
            final PackageSetting ps = mInstallRequest.getScannedPackageSetting();
            if (ps != null) {
                versionCode = ps.getVersionCode();
                apksSize = getApksSize(ps.getPath());
            }
        }

        FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLATION_SESSION_REPORTED,
                mInstallRequest.getSessionId() /* session_id */,
                success ? null : packageName /* not report package_name on success */,
                packageName /* package_name */,
                mInstallRequest.getUid() /* uid */,
                newUsers /* user_ids */,
                userManagerInternal.getUserTypesForStatsd(newUsers) /* user_types */,
@@ -107,7 +118,7 @@ final class PackageMetrics {
                stepDurations.second /* step_duration_millis */,
                installDurationMillis /* total_duration_millis */,
                mInstallRequest.getInstallFlags() /* install_flags */,
                installerUid /* installer_package_uid */,
                installerPackageUid /* installer_package_uid */,
                -1 /* original_installer_package_uid */,
                mInstallRequest.getDataLoaderType() /* data_loader_type */,
                mInstallRequest.getRequireUserAction() /* user_action_required_type */,