Add uid information in PackageListObserver

The uid information of a removed package cannot be retrieved by the
packageName anymore once it is removed. So it would be useful to provide
the uid of removed package in the onPackageAdded and onPackageRemoved
method of the PackageListObserver. This modification helps simplify the
design in PermissionMonitor.

Bug: 125396053
Test: dumpsys netd trafficcontroller

Change-Id: I2bd4bdf924687960a4fa3a47235bae68d885e445
This commit is contained in:
Chenbo Feng
2019-02-21 14:24:24 -08:00
parent d79cbf03a6
commit 9d4479a4f4

View File

@@ -46,13 +46,11 @@ import android.util.Log;
import android.util.Slog; import android.util.Slog;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices; import com.android.server.LocalServices;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -84,20 +82,14 @@ public class PermissionMonitor {
// Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission. // Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission.
private final Map<Integer, Boolean> mApps = new HashMap<>(); private final Map<Integer, Boolean> mApps = new HashMap<>();
// Keys are App packageNames, Values are app uids. . We need to keep track of this information
// because PackageListObserver#onPackageRemoved does not pass the UID.
@GuardedBy("mPackageNameUidMap")
private final Map<String, Integer> mPackageNameUidMap = new HashMap<>();
private class PackageListObserver implements PackageManagerInternal.PackageListObserver { private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
@Override @Override
public void onPackageAdded(String packageName) { public void onPackageAdded(String packageName, int uid) {
final PackageInfo app = getPackageInfo(packageName); final PackageInfo app = getPackageInfo(packageName);
if (app == null) { if (app == null) {
Slog.wtf(TAG, "Failed to get information of installed package: " + packageName); Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
return; return;
} }
int uid = (app.applicationInfo != null) ? app.applicationInfo.uid : INVALID_UID;
if (uid == INVALID_UID) { if (uid == INVALID_UID) {
Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
+ "uid: " + uid); + "uid: " + uid);
@@ -107,29 +99,21 @@ public class PermissionMonitor {
return; return;
} }
sendPackagePermissionsForUid(uid, sendPackagePermissionsForUid(uid,
filterPermission(Arrays.asList(app.requestedPermissions))); getNetdPermissionMask(app.requestedPermissions));
synchronized (mPackageNameUidMap) {
mPackageNameUidMap.put(packageName, uid);
}
} }
@Override @Override
public void onPackageRemoved(String packageName) { public void onPackageRemoved(String packageName, int uid) {
int uid;
synchronized (mPackageNameUidMap) {
if (!mPackageNameUidMap.containsKey(packageName)) {
return;
}
uid = mPackageNameUidMap.get(packageName);
mPackageNameUidMap.remove(packageName);
}
int permission = 0; int permission = 0;
// If there are still packages remain under the same uid, check the permission of the
// remaining packages. We only remove the permission for a given uid when all packages
// for that uid no longer have that permission.
String[] packages = mPackageManager.getPackagesForUid(uid); String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages != null && packages.length > 0) { if (packages != null && packages.length > 0) {
for (String name : packages) { for (String name : packages) {
final PackageInfo app = getPackageInfo(name); final PackageInfo app = getPackageInfo(name);
if (app != null && app.requestedPermissions != null) { if (app != null && app.requestedPermissions != null) {
permission |= filterPermission(Arrays.asList(app.requestedPermissions)); permission |= getNetdPermissionMask(app.requestedPermissions);
} }
} }
} }
@@ -184,12 +168,9 @@ public class PermissionMonitor {
//TODO: unify the management of the permissions into one codepath. //TODO: unify the management of the permissions into one codepath.
if (app.requestedPermissions != null) { if (app.requestedPermissions != null) {
int otherNetdPerms = filterPermission(Arrays.asList(app.requestedPermissions)); int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
if (otherNetdPerms != 0) { if (otherNetdPerms != 0) {
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms); netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
synchronized (mPackageNameUidMap) {
mPackageNameUidMap.put(app.applicationInfo.packageName, uid);
}
} }
} }
} }
@@ -422,13 +403,15 @@ public class PermissionMonitor {
} }
} }
private static int filterPermission(List<String> requestedPermissions) { private static int getNetdPermissionMask(String[] requestedPermissions) {
int permissions = 0; int permissions = 0;
if (requestedPermissions.contains(INTERNET)) { for (String permissionName : requestedPermissions) {
permissions |= INetd.PERMISSION_INTERNET; if (permissionName.equals(INTERNET)) {
} permissions |= INetd.PERMISSION_INTERNET;
if (requestedPermissions.contains(UPDATE_DEVICE_STATS)) { }
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS; if (permissionName.equals(UPDATE_DEVICE_STATS)) {
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
}
} }
return permissions; return permissions;
} }
@@ -439,8 +422,6 @@ public class PermissionMonitor {
| MATCH_ANY_USER); | MATCH_ANY_USER);
return app; return app;
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
// App not found.
loge("NameNotFoundException " + packageName);
return null; return null;
} }
} }