diff --git a/core/api/current.txt b/core/api/current.txt index 84b635ae78c09..c1c4c92237dbb 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -8013,6 +8013,9 @@ package android.app.admin { field public static final int TAG_MEDIA_UNMOUNT = 210014; // 0x3345e field public static final int TAG_OS_SHUTDOWN = 210010; // 0x3345a field public static final int TAG_OS_STARTUP = 210009; // 0x33459 + field public static final int TAG_PACKAGE_INSTALLED = 210041; // 0x33479 + field public static final int TAG_PACKAGE_UNINSTALLED = 210043; // 0x3347b + field public static final int TAG_PACKAGE_UPDATED = 210042; // 0x3347a field public static final int TAG_PASSWORD_CHANGED = 210036; // 0x33474 field public static final int TAG_PASSWORD_COMPLEXITY_REQUIRED = 210035; // 0x33473 field public static final int TAG_PASSWORD_COMPLEXITY_SET = 210017; // 0x33461 diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 904db5f86c029..ca2e97edc4322 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -96,6 +96,9 @@ public class SecurityLog { TAG_WIFI_DISCONNECTION, TAG_BLUETOOTH_CONNECTION, TAG_BLUETOOTH_DISCONNECTION, + TAG_PACKAGE_INSTALLED, + TAG_PACKAGE_UPDATED, + TAG_PACKAGE_UNINSTALLED, }) public @interface SecurityLogTag {} @@ -562,6 +565,39 @@ public class SecurityLog { public static final int TAG_BLUETOOTH_DISCONNECTION = SecurityLogTags.SECURITY_BLUETOOTH_DISCONNECTION; + /** + * Indicates that a package is installed. + * The log entry contains the following information about the + * event, encapsulated in an {@link Object} array and accessible via + * {@link SecurityEvent#getData()}: + *
  • [0] Name of the package being installed ({@code String}) + *
  • [1] Package version code ({@code Long}) + *
  • [2] UserId of the user that installed this package ({@code Integer}) + */ + public static final int TAG_PACKAGE_INSTALLED = SecurityLogTags.SECURITY_PACKAGE_INSTALLED; + + /** + * Indicates that a package is updated. + * The log entry contains the following information about the + * event, encapsulated in an {@link Object} array and accessible via + * {@link SecurityEvent#getData()}: + *
  • [0] Name of the package being updated ({@code String}) + *
  • [1] Package version code ({@code Long}) + *
  • [2] UserId of the user that updated this package ({@code Integer}) + */ + public static final int TAG_PACKAGE_UPDATED = SecurityLogTags.SECURITY_PACKAGE_UPDATED; + + /** + * Indicates that a package is uninstalled. + * The log entry contains the following information about the + * event, encapsulated in an {@link Object} array and accessible via + * {@link SecurityEvent#getData()}: + *
  • [0] Name of the package being uninstalled ({@code String}) + *
  • [1] Package version code ({@code Long}) + *
  • [2] UserId of the user that uninstalled this package ({@code Integer}) + */ + public static final int TAG_PACKAGE_UNINSTALLED = SecurityLogTags.SECURITY_PACKAGE_UNINSTALLED; + /** * Event severity level indicating that the event corresponds to normal workflow. */ @@ -772,6 +808,9 @@ public class SecurityLog { break; case SecurityLog.TAG_CERT_AUTHORITY_INSTALLED: case SecurityLog.TAG_CERT_AUTHORITY_REMOVED: + case SecurityLog.TAG_PACKAGE_INSTALLED: + case SecurityLog.TAG_PACKAGE_UPDATED: + case SecurityLog.TAG_PACKAGE_UNINSTALLED: try { userId = getIntegerData(2); } catch (Exception e) { diff --git a/core/java/android/app/admin/SecurityLogTags.logtags b/core/java/android/app/admin/SecurityLogTags.logtags index b06e5a5849fdb..e4af8dd915836 100644 --- a/core/java/android/app/admin/SecurityLogTags.logtags +++ b/core/java/android/app/admin/SecurityLogTags.logtags @@ -44,4 +44,7 @@ option java_package android.app.admin 210037 security_wifi_connection (bssid|3),(event_type|3),(reason|3) 210038 security_wifi_disconnection (bssid|3),(reason|3) 210039 security_bluetooth_connection (addr|3),(success|1),(reason|3) -210040 security_bluetooth_disconnection (addr|3),(reason|3) \ No newline at end of file +210040 security_bluetooth_disconnection (addr|3),(reason|3) +210041 security_package_installed (package_name|3),(version_code|1),(user_id|1) +210042 security_package_updated (package_name|3),(version_code|1),(user_id|1) +210043 security_package_uninstalled (package_name|3),(version_code|1),(user_id|1) \ No newline at end of file diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index 6998db76e338f..a6def7d616378 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -261,7 +261,7 @@ final class DeletePackageHelper { final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; info.sendPackageRemovedBroadcasts(killApp, removedBySystem); info.sendSystemPackageUpdatedBroadcasts(); - PackageMetrics.onUninstallSucceeded(info, deleteFlags, mUserManagerInternal); + PackageMetrics.onUninstallSucceeded(info, deleteFlags, userId); } // Force a gc to clear up things. @@ -550,6 +550,7 @@ final class DeletePackageHelper { outInfo.mRemovedUsers = userIds; outInfo.mBroadcastUsers = userIds; outInfo.mIsExternal = ps.isExternalStorage(); + outInfo.mRemovedPackageVersionCode = ps.getVersionCode(); } } diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 7553370bf4c62..61052f59c93bc 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -1608,6 +1608,7 @@ final class InstallPackageHelper { ps.getUninstallReason(userId)); } removedInfo.mIsExternal = oldPackage.isExternalStorage(); + removedInfo.mRemovedPackageVersionCode = oldPackage.getLongVersionCode(); request.setRemovedInfo(removedInfo); sysPkg = oldPackage.isSystem(); diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java index 5974a9cbab676..c6cdc4cd350d2 100644 --- a/services/core/java/com/android/server/pm/InstallRequest.java +++ b/services/core/java/com/android/server/pm/InstallRequest.java @@ -773,10 +773,10 @@ final class InstallRequest { } } - public void onInstallCompleted() { + public void onInstallCompleted(int userId) { if (getReturnCode() == INSTALL_SUCCEEDED) { if (mPackageMetrics != null) { - mPackageMetrics.onInstallSucceed(); + mPackageMetrics.onInstallSucceed(userId); } } } diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java index 2b6398af348e7..b600aa80b3882 100644 --- a/services/core/java/com/android/server/pm/InstallingSession.java +++ b/services/core/java/com/android/server/pm/InstallingSession.java @@ -535,7 +535,7 @@ class InstallingSession { mInstallPackageHelper.installPackagesTraced(installRequests); for (InstallRequest request : installRequests) { - request.onInstallCompleted(); + request.onInstallCompleted(mUser.getIdentifier()); doPostInstall(request); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cf59a1e248e04..91f7011c90c71 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3078,6 +3078,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService info.mRemovedUsers = new int[] {userId}; info.mBroadcastUsers = new int[] {userId}; info.mUid = UserHandle.getUid(userId, packageState.getAppId()); + info.mRemovedPackageVersionCode = packageState.getVersionCode(); info.sendPackageRemovedBroadcasts(true /*killApp*/, false /*removedBySystem*/); } diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java index 81f1a987c0a4f..8252a9fa65c5f 100644 --- a/services/core/java/com/android/server/pm/PackageMetrics.java +++ b/services/core/java/com/android/server/pm/PackageMetrics.java @@ -19,6 +19,7 @@ package com.android.server.pm; import static android.os.Process.INVALID_UID; import android.annotation.IntDef; +import android.app.admin.SecurityLog; import android.content.pm.PackageManager; import android.content.pm.parsing.ApkLiteParseUtils; import android.util.Pair; @@ -67,8 +68,8 @@ final class PackageMetrics { mInstallRequest = installRequest; } - public void onInstallSucceed() { - // TODO(b/239722919): report to SecurityLog if on work profile or managed device + public void onInstallSucceed(int userId) { + reportInstallationToSecurityLog(userId); reportInstallationStats(true /* success */); } @@ -77,8 +78,13 @@ final class PackageMetrics { } private void reportInstallationStats(boolean success) { - UserManagerInternal userManagerInternal = + final UserManagerInternal userManagerInternal = LocalServices.getService(UserManagerInternal.class); + if (userManagerInternal == null) { + // UserManagerService is not available. Skip metrics reporting. + return; + } + final long installDurationMillis = System.currentTimeMillis() - mInstallStartTimestampMillis; // write to stats @@ -196,12 +202,17 @@ final class PackageMetrics { } } - public static void onUninstallSucceeded(PackageRemovedInfo info, int deleteFlags, - UserManagerInternal userManagerInternal) { + public static void onUninstallSucceeded(PackageRemovedInfo info, int deleteFlags, int userId) { if (info.mIsUpdate) { // Not logging uninstalls caused by app updates return; } + final UserManagerInternal userManagerInternal = + LocalServices.getService(UserManagerInternal.class); + if (userManagerInternal == null) { + // UserManagerService is not available. Skip metrics reporting. + return; + } final int[] removedUsers = info.mRemovedUsers; final int[] removedUserTypes = userManagerInternal.getUserTypesForStatsd(removedUsers); final int[] originalUsers = info.mOrigUsers; @@ -210,6 +221,9 @@ final class PackageMetrics { info.mUid, removedUsers, removedUserTypes, originalUsers, originalUserTypes, deleteFlags, PackageManager.DELETE_SUCCEEDED, info.mIsRemovedPackageSystemUpdate, !info.mRemovedForAllUsers); + final String packageName = info.mRemovedPackage; + final long versionCode = info.mRemovedPackageVersionCode; + reportUninstallationToSecurityLog(packageName, versionCode, userId); } public static void onVerificationFailed(VerifyingSession verifyingSession) { @@ -242,4 +256,32 @@ final class PackageMetrics { verifyingSession.isStaged() /* is_staged */ ); } + + private void reportInstallationToSecurityLog(int userId) { + if (!SecurityLog.isLoggingEnabled()) { + return; + } + final PackageSetting ps = mInstallRequest.getScannedPackageSetting(); + if (ps == null) { + return; + } + final String packageName = ps.getPackageName(); + final long versionCode = ps.getVersionCode(); + if (!mInstallRequest.isInstallReplace()) { + SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_INSTALLED, packageName, versionCode, + userId); + } else { + SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UPDATED, packageName, versionCode, + userId); + } + } + + private static void reportUninstallationToSecurityLog(String packageName, long versionCode, + int userId) { + if (!SecurityLog.isLoggingEnabled()) { + return; + } + SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UNINSTALLED, packageName, versionCode, + userId); + } } diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java index dd580a5e43aac..c762fd3f9648b 100644 --- a/services/core/java/com/android/server/pm/PackageRemovedInfo.java +++ b/services/core/java/com/android/server/pm/PackageRemovedInfo.java @@ -51,6 +51,7 @@ final class PackageRemovedInfo { boolean mRemovedForAllUsers; boolean mIsStaticSharedLib; boolean mIsExternal; + long mRemovedPackageVersionCode; // a two dimensional array mapping userId to the set of appIds that can receive notice // of package changes SparseArray mBroadcastAllowList; diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java index 8c58397fb1a1a..41985e3890feb 100644 --- a/services/core/java/com/android/server/pm/RemovePackageHelper.java +++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java @@ -275,6 +275,7 @@ final class RemovePackageHelper { outInfo.populateUsers(deletedPs.queryInstalledUsers( mUserManagerInternal.getUserIds(), true), deletedPs); outInfo.mIsExternal = deletedPs.isExternalStorage(); + outInfo.mRemovedPackageVersionCode = deletedPs.getVersionCode(); } removePackageLI(deletedPs.getPackageName(), (flags & PackageManager.DELETE_CHATTY) != 0);