Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +13 −7 Original line number Diff line number Diff line Loading @@ -427,7 +427,7 @@ final class InstallPackageHelper { mPm.snapshotComputer().checkPackageFrozen(pkgName); } final boolean isReplace = request.isReplace(); final boolean isReplace = request.isInstallReplace(); // Also need to kill any apps that are dependent on the library, except the case of // installation of new version static shared library. if (clientLibPkgs != null) { Loading Loading @@ -814,6 +814,7 @@ final class InstallPackageHelper { for (InstallRequest request : requests) { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); request.onPrepareStarted(); preparePackageLI(request); } catch (PrepareFailure prepareFailure) { request.setError(prepareFailure.error, Loading @@ -822,6 +823,7 @@ final class InstallPackageHelper { request.setOriginPermission(prepareFailure.mConflictingPermission); return; } finally { request.onPrepareFinished(); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading @@ -834,11 +836,13 @@ final class InstallPackageHelper { request.setReturnCode(PackageManager.INSTALL_SUCCEEDED); final String packageName = packageToScan.getPackageName(); try { request.onScanStarted(); final ScanResult scanResult = scanPackageTracedLI(request.getParsedPackage(), request.getParseFlags(), request.getScanFlags(), System.currentTimeMillis(), request.getUser(), request.getAbiOverride()); request.setScanResult(scanResult); request.onScanFinished(); if (!scannedPackages.add(packageName)) { request.setError( PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, Loading Loading @@ -966,7 +970,7 @@ final class InstallPackageHelper { final boolean isRollback = request.getInstallReason() == PackageManager.INSTALL_REASON_ROLLBACK; @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; if (request.isMoveInstall()) { if (request.isInstallMove()) { // moving a complete application; perform an initial scan on the new install location scanFlags |= SCAN_INITIAL; } Loading Loading @@ -1349,7 +1353,7 @@ final class InstallPackageHelper { } } if (request.isMoveInstall()) { if (request.isInstallMove()) { // We did an in-place move, so dex is ready to roll scanFlags |= SCAN_NO_DEX; scanFlags |= SCAN_MOVE; Loading Loading @@ -1668,7 +1672,7 @@ final class InstallPackageHelper { ParsedPackage parsedPackage) throws PrepareFailure { final int status = request.getReturnCode(); final String statusMsg = request.getReturnMsg(); if (request.isMoveInstall()) { if (request.isInstallMove()) { if (status != PackageManager.INSTALL_SUCCEEDED) { mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(), request.getMovePackageName(), request.getMoveFromCodePath()); Loading Loading @@ -1888,7 +1892,8 @@ final class InstallPackageHelper { final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm); final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm); if (installRequest.isReplace()) { installRequest.onCommitStarted(); if (installRequest.isInstallReplace()) { AndroidPackage oldPackage = mPm.mPackages.get(packageName); // Set the update and install times Loading @@ -1905,7 +1910,7 @@ final class InstallPackageHelper { mPm.mAppsFilter.getVisibilityAllowList(mPm.snapshotComputer(), installRequest.getScannedPackageSetting(), allUsers, mPm.mSettings.getPackagesLocked()); if (installRequest.isSystem()) { if (installRequest.isInstallSystem()) { // Remove existing system package removePackageHelper.removePackage(oldPackage, true); if (!disableSystemPackageLPw(oldPackage)) { Loading Loading @@ -1973,6 +1978,7 @@ final class InstallPackageHelper { mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers()); mPm.updateInstantAppInstallerLocked(packageName); } installRequest.onCommitFinished(); } ApplicationPackageManager.invalidateGetPackagesForUidCache(); } Loading Loading @@ -2223,7 +2229,7 @@ final class InstallPackageHelper { FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } if (installRequest.isReplace()) { if (installRequest.isInstallReplace()) { mDexManager.notifyPackageUpdated(pkg.getPackageName(), pkg.getBaseApkPath(), pkg.getSplitCodePaths()); } Loading services/core/java/com/android/server/pm/InstallRequest.java +85 −5 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.server.pm; import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN; import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; import android.annotation.NonNull; Loading Loading @@ -105,6 +107,12 @@ final class InstallRequest { @Nullable private ScanResult mScanResult; private boolean mIsInstallInherit; private boolean mIsInstallForUsers; @Nullable private final PackageMetrics mPackageMetrics; // New install InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); Loading @@ -116,6 +124,8 @@ final class InstallRequest { params.mTraceMethod, params.mTraceCookie, params.mSigningDetails, params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride, params.mDataLoaderType, params.mPackageSource); mPackageMetrics = new PackageMetrics(this); mIsInstallInherit = params.mIsInherit; } // Install existing package as user Loading @@ -127,6 +137,8 @@ final class InstallRequest { mPkg = pkg; mNewUsers = newUsers; mPostInstallRunnable = runnable; mPackageMetrics = new PackageMetrics(this); mIsInstallForUsers = true; } // addForInit Loading @@ -143,6 +155,7 @@ final class InstallRequest { mParseFlags = parseFlags; mScanFlags = scanFlags; mScanResult = scanResult; mPackageMetrics = null; // No real logging from this code path } @Nullable Loading Loading @@ -200,7 +213,7 @@ final class InstallRequest { return mInstallArgs == null ? null : mInstallArgs.mObserver; } public boolean isMoveInstall() { public boolean isInstallMove() { return mInstallArgs != null && mInstallArgs.mMoveInfo != null; } Loading Loading @@ -278,7 +291,7 @@ final class InstallRequest { return mRemovedInfo != null ? mRemovedInfo.mRemovedPackage : null; } public boolean isInstallForExistingUser() { public boolean isInstallExistingForUser() { return mInstallArgs == null; } Loading Loading @@ -406,14 +419,22 @@ final class InstallRequest { return mClearCodeCache; } public boolean isReplace() { public boolean isInstallReplace() { return mReplace; } public boolean isSystem() { public boolean isInstallSystem() { return mSystem; } public boolean isInstallInherit() { return mIsInstallInherit; } public boolean isInstallForUsers() { return mIsInstallForUsers; } @Nullable public PackageSetting getOriginalPackageSetting() { return mOriginalPs; Loading Loading @@ -520,6 +541,10 @@ final class InstallRequest { return mScanResult.mRequest.mIsPlatformPackage; } public boolean isInstantInstall() { return (mScanFlags & SCAN_AS_INSTANT_APP) != 0; } public void assertScanResultExists() { if (mScanResult == null) { // Should not happen. This indicates a bug in the installation code flow Loading @@ -529,7 +554,6 @@ final class InstallRequest { Slog.e(TAG, "ScanResult is null and it should not happen"); } } } public void setScanFlags(int scanFlags) { Loading Loading @@ -658,4 +682,60 @@ final class InstallRequest { mRemovedInfo.mRemovedAppId = appId; } } public void onPrepareStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); } } public void onPrepareFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_PREPARE); } } public void onScanStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_SCAN); } } public void onScanFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_SCAN); } } public void onReconcileStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_RECONCILE); } } public void onReconcileFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_RECONCILE); } } public void onCommitStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_COMMIT); } } public void onCommitFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_COMMIT); } } public void onInstallCompleted() { if (getReturnCode() == INSTALL_SUCCEEDED) { if (mPackageMetrics != null) { mPackageMetrics.onInstallSucceed(); } } } } services/core/java/com/android/server/pm/InstallingSession.java +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.content.pm.PackageInstaller.SessionParams.MODE_INHERIT_EXISTING; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_STAGED; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; Loading Loading @@ -93,6 +94,7 @@ class InstallingSession { final PackageManagerService mPm; final InstallPackageHelper mInstallPackageHelper; final RemovePackageHelper mRemovePackageHelper; final boolean mIsInherit; InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, Loading Loading @@ -121,6 +123,7 @@ class InstallingSession { mRequiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST; mPackageSource = packageSource; mPackageLite = packageLite; mIsInherit = false; } InstallingSession(File stagedDir, IPackageInstallObserver2 observer, Loading Loading @@ -151,6 +154,7 @@ class InstallingSession { mRequiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode; mPackageSource = sessionParams.packageSource; mPackageLite = packageLite; mIsInherit = sessionParams.mode == MODE_INHERIT_EXISTING; } @Override Loading Loading @@ -506,6 +510,7 @@ class InstallingSession { mInstallPackageHelper.installPackagesTraced(installRequests); for (InstallRequest request : installRequests) { request.onInstallCompleted(); doPostInstall(request); } } Loading @@ -531,7 +536,7 @@ class InstallingSession { } private void cleanUpForFailedInstall(InstallRequest request) { if (request.isMoveInstall()) { if (request.isInstallMove()) { mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(), request.getMovePackageName(), request.getMoveFromCodePath()); } else { Loading services/core/java/com/android/server/pm/PackageHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ final class PackageHandler extends Handler { request.closeFreezer(); request.runPostInstallRunnable(); if (!request.isInstallForExistingUser()) { if (!request.isInstallExistingForUser()) { mInstallPackageHelper.handlePackagePostInstall(request, didRestore); } else if (DEBUG_INSTALL) { // No post-install when we run restore from installExistingPackageForUser Loading services/core/java/com/android/server/pm/PackageMetrics.java 0 → 100644 +153 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.annotation.IntDef; import android.os.UserManager; import android.util.Pair; import android.util.SparseArray; import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** * Metrics class for reporting stats to logging infrastructures like Westworld */ final class PackageMetrics { public static final int STEP_PREPARE = 1; public static final int STEP_SCAN = 2; public static final int STEP_RECONCILE = 3; public static final int STEP_COMMIT = 4; @IntDef(prefix = {"STEP_"}, value = { STEP_PREPARE, STEP_SCAN, STEP_RECONCILE, STEP_COMMIT, }) @Retention(RetentionPolicy.SOURCE) public @interface StepInt {} private final long mInstallStartTimestampMillis; private final SparseArray<InstallStep> mInstallSteps = new SparseArray<>(); private final InstallRequest mInstallRequest; PackageMetrics(InstallRequest installRequest) { // New instance is used for tracking installation metrics only. // Other metrics should use static methods of this class. mInstallStartTimestampMillis = System.currentTimeMillis(); mInstallRequest = installRequest; } public void onInstallSucceed() { 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(); FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLATION_SESSION_REPORTED, 0 /* session_id */, null /* package_name */, mInstallRequest.getUid() /* uid */, newUsers /* user_ids */, getUserTypes(newUsers) /* user_types */, originalUsers /* original_user_ids */, getUserTypes(originalUsers) /* original_user_types */, mInstallRequest.getReturnCode() /* public_return_code */, 0 /* internal_error_code */, 0 /* apks_size_bytes */, 0 /* version_code */, stepDurations.first /* install_steps */, stepDurations.second /* step_duration_millis */, installDurationMillis /* total_duration_millis */, mInstallRequest.getInstallFlags() /* install_flags */, -1 /* installer_package_uid */, -1 /* original_installer_package_uid */, mInstallRequest.getDataLoaderType() /* data_loader_type */, 0 /* user_action_required_type */, mInstallRequest.isInstantInstall() /* is_instant */, mInstallRequest.isInstallReplace() /* is_replace */, mInstallRequest.isInstallSystem() /* is_system */, mInstallRequest.isInstallInherit() /* is_inherit */, mInstallRequest.isInstallForUsers() /* is_installing_existing_as_user */, mInstallRequest.isInstallMove() /* is_move_install */, false /* is_staged */ ); } public void onStepStarted(@StepInt int step) { mInstallSteps.put(step, new InstallStep()); } public void onStepFinished(@StepInt int step) { final InstallStep installStep = mInstallSteps.get(step); if (installStep != null) { // Only valid if the start timestamp is set; otherwise no-op installStep.finish(); } } // List of steps (e.g., 1, 2, 3) and corresponding list of durations (e.g., 200ms, 100ms, 150ms) private Pair<int[], long[]> getInstallStepDurations() { ArrayList<Integer> steps = new ArrayList<>(); ArrayList<Long> durations = new ArrayList<>(); for (int i = 0; i < mInstallSteps.size(); i++) { final long duration = mInstallSteps.valueAt(i).getDurationMillis(); if (duration >= 0) { steps.add(mInstallSteps.keyAt(i)); durations.add(mInstallSteps.valueAt(i).getDurationMillis()); } } int[] stepsArray = new int[steps.size()]; long[] durationsArray = new long[durations.size()]; for (int i = 0; i < stepsArray.length; i++) { stepsArray[i] = steps.get(i); durationsArray[i] = durations.get(i); } return new Pair<>(stepsArray, durationsArray); } private static int[] getUserTypes(int[] userIds) { if (userIds == null) { return null; } final int[] userTypes = new int[userIds.length]; for (int i = 0; i < userTypes.length; i++) { String userType = UserManagerService.getInstance().getUserInfo(userIds[i]).userType; userTypes[i] = UserManager.getUserTypeForStatsd(userType); } return userTypes; } private static class InstallStep { private final long mStartTimestampMillis; private long mDurationMillis = -1; InstallStep() { mStartTimestampMillis = System.currentTimeMillis(); } void finish() { mDurationMillis = System.currentTimeMillis() - mStartTimestampMillis; } long getDurationMillis() { return mDurationMillis; } } } Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +13 −7 Original line number Diff line number Diff line Loading @@ -427,7 +427,7 @@ final class InstallPackageHelper { mPm.snapshotComputer().checkPackageFrozen(pkgName); } final boolean isReplace = request.isReplace(); final boolean isReplace = request.isInstallReplace(); // Also need to kill any apps that are dependent on the library, except the case of // installation of new version static shared library. if (clientLibPkgs != null) { Loading Loading @@ -814,6 +814,7 @@ final class InstallPackageHelper { for (InstallRequest request : requests) { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); request.onPrepareStarted(); preparePackageLI(request); } catch (PrepareFailure prepareFailure) { request.setError(prepareFailure.error, Loading @@ -822,6 +823,7 @@ final class InstallPackageHelper { request.setOriginPermission(prepareFailure.mConflictingPermission); return; } finally { request.onPrepareFinished(); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading @@ -834,11 +836,13 @@ final class InstallPackageHelper { request.setReturnCode(PackageManager.INSTALL_SUCCEEDED); final String packageName = packageToScan.getPackageName(); try { request.onScanStarted(); final ScanResult scanResult = scanPackageTracedLI(request.getParsedPackage(), request.getParseFlags(), request.getScanFlags(), System.currentTimeMillis(), request.getUser(), request.getAbiOverride()); request.setScanResult(scanResult); request.onScanFinished(); if (!scannedPackages.add(packageName)) { request.setError( PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, Loading Loading @@ -966,7 +970,7 @@ final class InstallPackageHelper { final boolean isRollback = request.getInstallReason() == PackageManager.INSTALL_REASON_ROLLBACK; @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; if (request.isMoveInstall()) { if (request.isInstallMove()) { // moving a complete application; perform an initial scan on the new install location scanFlags |= SCAN_INITIAL; } Loading Loading @@ -1349,7 +1353,7 @@ final class InstallPackageHelper { } } if (request.isMoveInstall()) { if (request.isInstallMove()) { // We did an in-place move, so dex is ready to roll scanFlags |= SCAN_NO_DEX; scanFlags |= SCAN_MOVE; Loading Loading @@ -1668,7 +1672,7 @@ final class InstallPackageHelper { ParsedPackage parsedPackage) throws PrepareFailure { final int status = request.getReturnCode(); final String statusMsg = request.getReturnMsg(); if (request.isMoveInstall()) { if (request.isInstallMove()) { if (status != PackageManager.INSTALL_SUCCEEDED) { mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(), request.getMovePackageName(), request.getMoveFromCodePath()); Loading Loading @@ -1888,7 +1892,8 @@ final class InstallPackageHelper { final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm); final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm); if (installRequest.isReplace()) { installRequest.onCommitStarted(); if (installRequest.isInstallReplace()) { AndroidPackage oldPackage = mPm.mPackages.get(packageName); // Set the update and install times Loading @@ -1905,7 +1910,7 @@ final class InstallPackageHelper { mPm.mAppsFilter.getVisibilityAllowList(mPm.snapshotComputer(), installRequest.getScannedPackageSetting(), allUsers, mPm.mSettings.getPackagesLocked()); if (installRequest.isSystem()) { if (installRequest.isInstallSystem()) { // Remove existing system package removePackageHelper.removePackage(oldPackage, true); if (!disableSystemPackageLPw(oldPackage)) { Loading Loading @@ -1973,6 +1978,7 @@ final class InstallPackageHelper { mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers()); mPm.updateInstantAppInstallerLocked(packageName); } installRequest.onCommitFinished(); } ApplicationPackageManager.invalidateGetPackagesForUidCache(); } Loading Loading @@ -2223,7 +2229,7 @@ final class InstallPackageHelper { FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); } if (installRequest.isReplace()) { if (installRequest.isInstallReplace()) { mDexManager.notifyPackageUpdated(pkg.getPackageName(), pkg.getBaseApkPath(), pkg.getSplitCodePaths()); } Loading
services/core/java/com/android/server/pm/InstallRequest.java +85 −5 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.server.pm; import static android.content.pm.PackageManager.INSTALL_REASON_UNKNOWN; import static android.content.pm.PackageManager.INSTALL_SCENARIO_DEFAULT; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.os.Process.INVALID_UID; import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; import static com.android.server.pm.PackageManagerService.TAG; import android.annotation.NonNull; Loading Loading @@ -105,6 +107,12 @@ final class InstallRequest { @Nullable private ScanResult mScanResult; private boolean mIsInstallInherit; private boolean mIsInstallForUsers; @Nullable private final PackageMetrics mPackageMetrics; // New install InstallRequest(InstallingSession params) { mUserId = params.getUser().getIdentifier(); Loading @@ -116,6 +124,8 @@ final class InstallRequest { params.mTraceMethod, params.mTraceCookie, params.mSigningDetails, params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride, params.mDataLoaderType, params.mPackageSource); mPackageMetrics = new PackageMetrics(this); mIsInstallInherit = params.mIsInherit; } // Install existing package as user Loading @@ -127,6 +137,8 @@ final class InstallRequest { mPkg = pkg; mNewUsers = newUsers; mPostInstallRunnable = runnable; mPackageMetrics = new PackageMetrics(this); mIsInstallForUsers = true; } // addForInit Loading @@ -143,6 +155,7 @@ final class InstallRequest { mParseFlags = parseFlags; mScanFlags = scanFlags; mScanResult = scanResult; mPackageMetrics = null; // No real logging from this code path } @Nullable Loading Loading @@ -200,7 +213,7 @@ final class InstallRequest { return mInstallArgs == null ? null : mInstallArgs.mObserver; } public boolean isMoveInstall() { public boolean isInstallMove() { return mInstallArgs != null && mInstallArgs.mMoveInfo != null; } Loading Loading @@ -278,7 +291,7 @@ final class InstallRequest { return mRemovedInfo != null ? mRemovedInfo.mRemovedPackage : null; } public boolean isInstallForExistingUser() { public boolean isInstallExistingForUser() { return mInstallArgs == null; } Loading Loading @@ -406,14 +419,22 @@ final class InstallRequest { return mClearCodeCache; } public boolean isReplace() { public boolean isInstallReplace() { return mReplace; } public boolean isSystem() { public boolean isInstallSystem() { return mSystem; } public boolean isInstallInherit() { return mIsInstallInherit; } public boolean isInstallForUsers() { return mIsInstallForUsers; } @Nullable public PackageSetting getOriginalPackageSetting() { return mOriginalPs; Loading Loading @@ -520,6 +541,10 @@ final class InstallRequest { return mScanResult.mRequest.mIsPlatformPackage; } public boolean isInstantInstall() { return (mScanFlags & SCAN_AS_INSTANT_APP) != 0; } public void assertScanResultExists() { if (mScanResult == null) { // Should not happen. This indicates a bug in the installation code flow Loading @@ -529,7 +554,6 @@ final class InstallRequest { Slog.e(TAG, "ScanResult is null and it should not happen"); } } } public void setScanFlags(int scanFlags) { Loading Loading @@ -658,4 +682,60 @@ final class InstallRequest { mRemovedInfo.mRemovedAppId = appId; } } public void onPrepareStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_PREPARE); } } public void onPrepareFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_PREPARE); } } public void onScanStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_SCAN); } } public void onScanFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_SCAN); } } public void onReconcileStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_RECONCILE); } } public void onReconcileFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_RECONCILE); } } public void onCommitStarted() { if (mPackageMetrics != null) { mPackageMetrics.onStepStarted(PackageMetrics.STEP_COMMIT); } } public void onCommitFinished() { if (mPackageMetrics != null) { mPackageMetrics.onStepFinished(PackageMetrics.STEP_COMMIT); } } public void onInstallCompleted() { if (getReturnCode() == INSTALL_SUCCEEDED) { if (mPackageMetrics != null) { mPackageMetrics.onInstallSucceed(); } } } }
services/core/java/com/android/server/pm/InstallingSession.java +6 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.content.pm.PackageInstaller.SessionParams.MODE_INHERIT_EXISTING; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_STAGED; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; Loading Loading @@ -93,6 +94,7 @@ class InstallingSession { final PackageManagerService mPm; final InstallPackageHelper mInstallPackageHelper; final RemovePackageHelper mRemovePackageHelper; final boolean mIsInherit; InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer, int installFlags, InstallSource installSource, String volumeUuid, Loading Loading @@ -121,6 +123,7 @@ class InstallingSession { mRequiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST; mPackageSource = packageSource; mPackageLite = packageLite; mIsInherit = false; } InstallingSession(File stagedDir, IPackageInstallObserver2 observer, Loading Loading @@ -151,6 +154,7 @@ class InstallingSession { mRequiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode; mPackageSource = sessionParams.packageSource; mPackageLite = packageLite; mIsInherit = sessionParams.mode == MODE_INHERIT_EXISTING; } @Override Loading Loading @@ -506,6 +510,7 @@ class InstallingSession { mInstallPackageHelper.installPackagesTraced(installRequests); for (InstallRequest request : installRequests) { request.onInstallCompleted(); doPostInstall(request); } } Loading @@ -531,7 +536,7 @@ class InstallingSession { } private void cleanUpForFailedInstall(InstallRequest request) { if (request.isMoveInstall()) { if (request.isInstallMove()) { mRemovePackageHelper.cleanUpForMoveInstall(request.getMoveToUuid(), request.getMovePackageName(), request.getMoveFromCodePath()); } else { Loading
services/core/java/com/android/server/pm/PackageHandler.java +1 −1 Original line number Diff line number Diff line Loading @@ -95,7 +95,7 @@ final class PackageHandler extends Handler { request.closeFreezer(); request.runPostInstallRunnable(); if (!request.isInstallForExistingUser()) { if (!request.isInstallExistingForUser()) { mInstallPackageHelper.handlePackagePostInstall(request, didRestore); } else if (DEBUG_INSTALL) { // No post-install when we run restore from installExistingPackageForUser Loading
services/core/java/com/android/server/pm/PackageMetrics.java 0 → 100644 +153 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.annotation.IntDef; import android.os.UserManager; import android.util.Pair; import android.util.SparseArray; import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** * Metrics class for reporting stats to logging infrastructures like Westworld */ final class PackageMetrics { public static final int STEP_PREPARE = 1; public static final int STEP_SCAN = 2; public static final int STEP_RECONCILE = 3; public static final int STEP_COMMIT = 4; @IntDef(prefix = {"STEP_"}, value = { STEP_PREPARE, STEP_SCAN, STEP_RECONCILE, STEP_COMMIT, }) @Retention(RetentionPolicy.SOURCE) public @interface StepInt {} private final long mInstallStartTimestampMillis; private final SparseArray<InstallStep> mInstallSteps = new SparseArray<>(); private final InstallRequest mInstallRequest; PackageMetrics(InstallRequest installRequest) { // New instance is used for tracking installation metrics only. // Other metrics should use static methods of this class. mInstallStartTimestampMillis = System.currentTimeMillis(); mInstallRequest = installRequest; } public void onInstallSucceed() { 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(); FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLATION_SESSION_REPORTED, 0 /* session_id */, null /* package_name */, mInstallRequest.getUid() /* uid */, newUsers /* user_ids */, getUserTypes(newUsers) /* user_types */, originalUsers /* original_user_ids */, getUserTypes(originalUsers) /* original_user_types */, mInstallRequest.getReturnCode() /* public_return_code */, 0 /* internal_error_code */, 0 /* apks_size_bytes */, 0 /* version_code */, stepDurations.first /* install_steps */, stepDurations.second /* step_duration_millis */, installDurationMillis /* total_duration_millis */, mInstallRequest.getInstallFlags() /* install_flags */, -1 /* installer_package_uid */, -1 /* original_installer_package_uid */, mInstallRequest.getDataLoaderType() /* data_loader_type */, 0 /* user_action_required_type */, mInstallRequest.isInstantInstall() /* is_instant */, mInstallRequest.isInstallReplace() /* is_replace */, mInstallRequest.isInstallSystem() /* is_system */, mInstallRequest.isInstallInherit() /* is_inherit */, mInstallRequest.isInstallForUsers() /* is_installing_existing_as_user */, mInstallRequest.isInstallMove() /* is_move_install */, false /* is_staged */ ); } public void onStepStarted(@StepInt int step) { mInstallSteps.put(step, new InstallStep()); } public void onStepFinished(@StepInt int step) { final InstallStep installStep = mInstallSteps.get(step); if (installStep != null) { // Only valid if the start timestamp is set; otherwise no-op installStep.finish(); } } // List of steps (e.g., 1, 2, 3) and corresponding list of durations (e.g., 200ms, 100ms, 150ms) private Pair<int[], long[]> getInstallStepDurations() { ArrayList<Integer> steps = new ArrayList<>(); ArrayList<Long> durations = new ArrayList<>(); for (int i = 0; i < mInstallSteps.size(); i++) { final long duration = mInstallSteps.valueAt(i).getDurationMillis(); if (duration >= 0) { steps.add(mInstallSteps.keyAt(i)); durations.add(mInstallSteps.valueAt(i).getDurationMillis()); } } int[] stepsArray = new int[steps.size()]; long[] durationsArray = new long[durations.size()]; for (int i = 0; i < stepsArray.length; i++) { stepsArray[i] = steps.get(i); durationsArray[i] = durations.get(i); } return new Pair<>(stepsArray, durationsArray); } private static int[] getUserTypes(int[] userIds) { if (userIds == null) { return null; } final int[] userTypes = new int[userIds.length]; for (int i = 0; i < userTypes.length; i++) { String userType = UserManagerService.getInstance().getUserInfo(userIds[i]).userType; userTypes[i] = UserManager.getUserTypeForStatsd(userType); } return userTypes; } private static class InstallStep { private final long mStartTimestampMillis; private long mDurationMillis = -1; InstallStep() { mStartTimestampMillis = System.currentTimeMillis(); } void finish() { mDurationMillis = System.currentTimeMillis() - mStartTimestampMillis; } long getDurationMillis() { return mDurationMillis; } } }