When the applicantion is removed, reset network permission of this uid.

Probably not a portal: exception java.net.SocketException: Binding socket to network 102 failed: EPERM (Operation not permitted)

If there are SYSTEM permissions, then the original is SYSTEM permissions,
do not update. If other app of this uid have network permissions, the same
as before do not update, or update permissions. If all app of this uid
do not have any network permission to remove permissions.

Change-Id: I304d22b37de38d8b182639c0d7d7200adfcf715d
Signed-off-by: zhangshuxiao <zhangshuxiao@xiaomi.com>
This commit is contained in:
zhangshuxiao
2016-02-03 21:28:25 +08:00
parent 017e0c060c
commit ad8499f9cd

View File

@@ -55,8 +55,8 @@ import java.util.Set;
public class PermissionMonitor { public class PermissionMonitor {
private static final String TAG = "PermissionMonitor"; private static final String TAG = "PermissionMonitor";
private static final boolean DBG = true; private static final boolean DBG = true;
private static final boolean SYSTEM = true; private static final Boolean SYSTEM = Boolean.TRUE;
private static final boolean NETWORK = false; private static final Boolean NETWORK = Boolean.FALSE;
private final Context mContext; private final Context mContext;
private final PackageManager mPackageManager; private final PackageManager mPackageManager;
@@ -226,30 +226,40 @@ public class PermissionMonitor {
update(users, mApps, false); update(users, mApps, false);
} }
private Boolean highestPermissionForUid(Boolean currentPermission, String name) {
if (currentPermission == SYSTEM) {
return currentPermission;
}
try {
final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
final boolean isNetwork = hasNetworkPermission(app);
final boolean isSystem = hasSystemPermission(app);
if (isNetwork || isSystem) {
currentPermission = isSystem;
}
} catch (NameNotFoundException e) {
// App not found.
loge("NameNotFoundException " + name);
}
return currentPermission;
}
private synchronized void onAppAdded(String appName, int appUid) { private synchronized void onAppAdded(String appName, int appUid) {
if (TextUtils.isEmpty(appName) || appUid < 0) { if (TextUtils.isEmpty(appName) || appUid < 0) {
loge("Invalid app in onAppAdded: " + appName + " | " + appUid); loge("Invalid app in onAppAdded: " + appName + " | " + appUid);
return; return;
} }
try { // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS); // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
boolean isNetwork = hasNetworkPermission(app); final Boolean permission = highestPermissionForUid(mApps.get(appUid), appName);
boolean isSystem = hasSystemPermission(app); if (permission != mApps.get(appUid)) {
if (isNetwork || isSystem) { mApps.put(appUid, permission);
Boolean permission = mApps.get(appUid);
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
if (permission == null || permission == NETWORK) {
mApps.put(appUid, isSystem);
Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>(); Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
apps.put(appUid, isSystem); apps.put(appUid, permission);
update(mUsers, apps, true); update(mUsers, apps, true);
}
}
} catch (NameNotFoundException e) {
loge("NameNotFoundException in onAppAdded: " + e);
} }
} }
@@ -258,11 +268,33 @@ public class PermissionMonitor {
loge("Invalid app in onAppRemoved: " + appUid); loge("Invalid app in onAppRemoved: " + appUid);
return; return;
} }
mApps.remove(appUid);
Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>(); Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
apps.put(appUid, NETWORK); // doesn't matter which permission we pick here
update(mUsers, apps, false); Boolean permission = null;
String[] packages = mPackageManager.getPackagesForUid(appUid);
if (packages != null && packages.length > 0) {
for (String name : packages) {
permission = highestPermissionForUid(permission, name);
if (permission == SYSTEM) {
// An app with this UID still has the SYSTEM permission.
// Therefore, this UID must already have the SYSTEM permission.
// Nothing to do.
return;
}
}
}
if (permission == mApps.get(appUid)) {
// The permissions of this UID have not changed. Nothing to do.
return;
} else if (permission != null) {
mApps.put(appUid, permission);
apps.put(appUid, permission);
update(mUsers, apps, true);
} else {
mApps.remove(appUid);
apps.put(appUid, NETWORK); // doesn't matter which permission we pick here
update(mUsers, apps, false);
}
} }
private static void log(String s) { private static void log(String s) {