Loading services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java +32 −18 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class WatchlistLoggingHandler extends Handler { private final WatchlistReportDbHelper mDbHelper; private final WatchlistConfig mConfig; private final WatchlistSettings mSettings; private int mPrimaryUserId = -1; // A cache for uid and apk digest mapping. // As uid won't be reused until reboot, it's safe to assume uid is unique per signature and app. // TODO: Use more efficient data structure. Loading @@ -97,6 +98,7 @@ class WatchlistLoggingHandler extends Handler { mConfig = WatchlistConfig.getInstance(); mSettings = WatchlistSettings.getInstance(); mDropBoxManager = mContext.getSystemService(DropBoxManager.class); mPrimaryUserId = getPrimaryUserId(); } @Override Loading Loading @@ -130,6 +132,19 @@ class WatchlistLoggingHandler extends Handler { } } /** * Get primary user id. * @return Primary user id. -1 if primary user not found. */ private int getPrimaryUserId() { final UserInfo primaryUserInfo = ((UserManager) mContext.getSystemService( Context.USER_SERVICE)).getPrimaryUser(); if (primaryUserInfo != null) { return primaryUserInfo.id; } return -1; } /** * Return if a given package has testOnly is true. */ Loading Loading @@ -182,6 +197,18 @@ class WatchlistLoggingHandler extends Handler { if (DEBUG) { Slog.i(TAG, "handleNetworkEvent with host: " + hostname + ", uid: " + uid); } // Update primary user id if necessary if (mPrimaryUserId == -1) { mPrimaryUserId = getPrimaryUserId(); } // Only process primary user data if (UserHandle.getUserId(uid) != mPrimaryUserId) { if (DEBUG) { Slog.i(TAG, "Do not log non-system user records"); } return; } final String cncDomain = searchAllSubDomainsInWatchlist(hostname); if (cncDomain != null) { insertRecord(uid, cncDomain, timestamp); Loading Loading @@ -272,28 +299,15 @@ class WatchlistLoggingHandler extends Handler { @VisibleForTesting List<String> getAllDigestsForReport(WatchlistReportDbHelper.AggregatedResult record) { // Step 1: Get all installed application digests. final List<UserInfo> users = ((UserManager) mContext.getSystemService( Context.USER_SERVICE)).getUsers(); final int totalUsers = users.size(); final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); PackageManager.MATCH_ALL); final HashSet<String> result = new HashSet<>(apps.size() + record.appDigestCNCList.size()); final int size = apps.size(); for (int i = 0; i < size; i++) { final int appUid = apps.get(i).uid; boolean added = false; // As the uid returned by getInstalledApplications() is for primary user only, it // may exist in secondary users but not primary user, so we need to loop and see if // that user has the app enabled. for (int j = 0; j < totalUsers && !added; j++) { int uid = UserHandle.getUid(users.get(j).id, appUid); byte[] digest = getDigestFromUid(uid); byte[] digest = getDigestFromUid(apps.get(i).uid); if (digest != null) { result.add(HexDump.toHexString(digest)); added = true; } } if (!added) { } else { Slog.e(TAG, "Cannot get digest from uid: " + apps.get(i).uid + ",pkg: " + apps.get(i).packageName); } Loading services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistLoggingHandlerTests.java +10 −3 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ public class WatchlistLoggingHandlerTests { private static final String APK_A = "A.apk"; private static final String APK_B = "B.apk"; private static final String APK_C = "C.apk"; private static final String APK_A_CONTENT = "AAA"; private static final String APK_B_CONTENT = "BBB"; private static final String APK_C_CONTENT = "CCC"; // Sha256 of "AAA" private static final String APK_A_CONTENT_HASH = "CB1AD2119D8FAFB69566510EE712661F9F14B83385006EF92AEC47F523A38358"; Loading Loading @@ -120,8 +122,9 @@ public class WatchlistLoggingHandlerTests { return result; }).when(mockPackageManager).getInstalledApplications(anyInt()); // Uid 1 app with is installed in primary user and package name is "A" // Uid 2 app is installed in secondary user and package name is "B" // Uid 1 app is installed in primary user only and package name is "A" // Uid 2 app is installed in both primary user and secondary user, package name is "B" // Uid 3 app is installed in secondary user and package name is "C" doAnswer((InvocationOnMock invocation) -> { int uid = (int) invocation.getArguments()[0]; if (uid == 1) { Loading @@ -129,9 +132,13 @@ public class WatchlistLoggingHandlerTests { } else if (uid == 1000001) { return null; } else if (uid == 2) { return null; return new String[]{"B"}; } else if (uid == 1000002) { return new String[]{"B"}; } else if (uid == 3) { return null; } else if (uid == 1000002) { return new String[]{"C"}; } return null; }).when(mockPackageManager).getPackagesForUid(anyInt()); Loading Loading
services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java +32 −18 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ class WatchlistLoggingHandler extends Handler { private final WatchlistReportDbHelper mDbHelper; private final WatchlistConfig mConfig; private final WatchlistSettings mSettings; private int mPrimaryUserId = -1; // A cache for uid and apk digest mapping. // As uid won't be reused until reboot, it's safe to assume uid is unique per signature and app. // TODO: Use more efficient data structure. Loading @@ -97,6 +98,7 @@ class WatchlistLoggingHandler extends Handler { mConfig = WatchlistConfig.getInstance(); mSettings = WatchlistSettings.getInstance(); mDropBoxManager = mContext.getSystemService(DropBoxManager.class); mPrimaryUserId = getPrimaryUserId(); } @Override Loading Loading @@ -130,6 +132,19 @@ class WatchlistLoggingHandler extends Handler { } } /** * Get primary user id. * @return Primary user id. -1 if primary user not found. */ private int getPrimaryUserId() { final UserInfo primaryUserInfo = ((UserManager) mContext.getSystemService( Context.USER_SERVICE)).getPrimaryUser(); if (primaryUserInfo != null) { return primaryUserInfo.id; } return -1; } /** * Return if a given package has testOnly is true. */ Loading Loading @@ -182,6 +197,18 @@ class WatchlistLoggingHandler extends Handler { if (DEBUG) { Slog.i(TAG, "handleNetworkEvent with host: " + hostname + ", uid: " + uid); } // Update primary user id if necessary if (mPrimaryUserId == -1) { mPrimaryUserId = getPrimaryUserId(); } // Only process primary user data if (UserHandle.getUserId(uid) != mPrimaryUserId) { if (DEBUG) { Slog.i(TAG, "Do not log non-system user records"); } return; } final String cncDomain = searchAllSubDomainsInWatchlist(hostname); if (cncDomain != null) { insertRecord(uid, cncDomain, timestamp); Loading Loading @@ -272,28 +299,15 @@ class WatchlistLoggingHandler extends Handler { @VisibleForTesting List<String> getAllDigestsForReport(WatchlistReportDbHelper.AggregatedResult record) { // Step 1: Get all installed application digests. final List<UserInfo> users = ((UserManager) mContext.getSystemService( Context.USER_SERVICE)).getUsers(); final int totalUsers = users.size(); final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); PackageManager.MATCH_ALL); final HashSet<String> result = new HashSet<>(apps.size() + record.appDigestCNCList.size()); final int size = apps.size(); for (int i = 0; i < size; i++) { final int appUid = apps.get(i).uid; boolean added = false; // As the uid returned by getInstalledApplications() is for primary user only, it // may exist in secondary users but not primary user, so we need to loop and see if // that user has the app enabled. for (int j = 0; j < totalUsers && !added; j++) { int uid = UserHandle.getUid(users.get(j).id, appUid); byte[] digest = getDigestFromUid(uid); byte[] digest = getDigestFromUid(apps.get(i).uid); if (digest != null) { result.add(HexDump.toHexString(digest)); added = true; } } if (!added) { } else { Slog.e(TAG, "Cannot get digest from uid: " + apps.get(i).uid + ",pkg: " + apps.get(i).packageName); } Loading
services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistLoggingHandlerTests.java +10 −3 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ public class WatchlistLoggingHandlerTests { private static final String APK_A = "A.apk"; private static final String APK_B = "B.apk"; private static final String APK_C = "C.apk"; private static final String APK_A_CONTENT = "AAA"; private static final String APK_B_CONTENT = "BBB"; private static final String APK_C_CONTENT = "CCC"; // Sha256 of "AAA" private static final String APK_A_CONTENT_HASH = "CB1AD2119D8FAFB69566510EE712661F9F14B83385006EF92AEC47F523A38358"; Loading Loading @@ -120,8 +122,9 @@ public class WatchlistLoggingHandlerTests { return result; }).when(mockPackageManager).getInstalledApplications(anyInt()); // Uid 1 app with is installed in primary user and package name is "A" // Uid 2 app is installed in secondary user and package name is "B" // Uid 1 app is installed in primary user only and package name is "A" // Uid 2 app is installed in both primary user and secondary user, package name is "B" // Uid 3 app is installed in secondary user and package name is "C" doAnswer((InvocationOnMock invocation) -> { int uid = (int) invocation.getArguments()[0]; if (uid == 1) { Loading @@ -129,9 +132,13 @@ public class WatchlistLoggingHandlerTests { } else if (uid == 1000001) { return null; } else if (uid == 2) { return null; return new String[]{"B"}; } else if (uid == 1000002) { return new String[]{"B"}; } else if (uid == 3) { return null; } else if (uid == 1000002) { return new String[]{"C"}; } return null; }).when(mockPackageManager).getPackagesForUid(anyInt()); Loading