Merge "PermissionMonitor: Limit preinstalled apps network permissions"
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index e471c7d..7b8571c 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -24,6 +24,7 @@
import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -34,6 +35,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -155,9 +157,8 @@
}
@VisibleForTesting
- boolean isPreinstalledSystemApp(PackageInfo app) {
- int flags = app.applicationInfo != null ? app.applicationInfo.flags : 0;
- return (flags & (FLAG_SYSTEM | FLAG_UPDATED_SYSTEM_APP)) != 0;
+ static boolean isVendorApp(@NonNull ApplicationInfo appInfo) {
+ return appInfo.isVendor() || appInfo.isOem() || appInfo.isProduct();
}
@VisibleForTesting
@@ -177,7 +178,13 @@
}
private boolean hasRestrictedNetworkPermission(PackageInfo app) {
- if (isPreinstalledSystemApp(app)) return true;
+ // TODO : remove this check in the future(b/31479477). All apps should just
+ // request the appropriate permission for their use case since android Q.
+ if (app.applicationInfo != null
+ && app.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q
+ && isVendorApp(app.applicationInfo)) {
+ return true;
+ }
return hasPermission(app, CONNECTIVITY_INTERNAL)
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
}
@@ -186,13 +193,8 @@
// This function defines what it means to hold the permission to use
// background networks.
return hasPermission(app, CHANGE_NETWORK_STATE)
- || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)
- || hasPermission(app, CONNECTIVITY_INTERNAL)
|| hasPermission(app, NETWORK_STACK)
- // TODO : remove this check (b/31479477). Not all preinstalled apps should
- // have access to background networks, they should just request the appropriate
- // permission for their use case from the list above.
- || isPreinstalledSystemApp(app);
+ || hasRestrictedNetworkPermission(app);
}
public boolean hasUseBackgroundNetworksPermission(int uid) {
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index f025f41..4dc63f2 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -21,7 +21,9 @@
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static org.junit.Assert.assertFalse;
@@ -34,6 +36,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -48,6 +51,10 @@
public class PermissionMonitorTest {
private static final int MOCK_UID = 10001;
private static final String[] MOCK_PACKAGE_NAMES = new String[] { "com.foo.bar" };
+ private static final String PARTITION_SYSTEM = "system";
+ private static final String PARTITION_OEM = "oem";
+ private static final String PARTITION_PRODUCT = "product";
+ private static final String PARTITION_VENDOR = "vendor";
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@@ -62,39 +69,53 @@
mPermissionMonitor = new PermissionMonitor(mContext, null);
}
- private void expectPermission(String[] permissions, boolean preinstalled) throws Exception {
- final PackageInfo packageInfo = packageInfoWithPermissions(permissions, preinstalled);
+ private void expectPermission(String[] permissions, String partition,
+ int targetSdkVersion) throws Exception {
+ final PackageInfo packageInfo = packageInfoWithPermissions(permissions, partition);
+ packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
when(mPackageManager.getPackageInfoAsUser(
eq(MOCK_PACKAGE_NAMES[0]), eq(GET_PERMISSIONS), anyInt())).thenReturn(packageInfo);
}
- private PackageInfo packageInfoWithPermissions(String[] permissions, boolean preinstalled) {
+ private PackageInfo packageInfoWithPermissions(String[] permissions, String partition) {
final PackageInfo packageInfo = new PackageInfo();
packageInfo.requestedPermissions = permissions;
packageInfo.applicationInfo = new ApplicationInfo();
- packageInfo.applicationInfo.flags = preinstalled ? FLAG_SYSTEM : 0;
+ int privateFlags = 0;
+ switch (partition) {
+ case PARTITION_OEM:
+ privateFlags = PRIVATE_FLAG_OEM;
+ break;
+ case PARTITION_PRODUCT:
+ privateFlags = PRIVATE_FLAG_PRODUCT;
+ break;
+ case PARTITION_VENDOR:
+ privateFlags = PRIVATE_FLAG_VENDOR;
+ break;
+ }
+ packageInfo.applicationInfo.privateFlags = privateFlags;
return packageInfo;
}
@Test
public void testHasPermission() {
- PackageInfo app = packageInfoWithPermissions(new String[] {}, false);
+ PackageInfo app = packageInfoWithPermissions(new String[] {}, PARTITION_SYSTEM);
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
app = packageInfoWithPermissions(new String[] {
- CHANGE_NETWORK_STATE, NETWORK_STACK
- }, false);
+ CHANGE_NETWORK_STATE, NETWORK_STACK
+ }, PARTITION_SYSTEM);
assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
app = packageInfoWithPermissions(new String[] {
- CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL
- }, false);
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL
+ }, PARTITION_SYSTEM);
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
@@ -102,35 +123,64 @@
}
@Test
- public void testIsPreinstalledSystemApp() {
- PackageInfo app = packageInfoWithPermissions(new String[] {}, false);
- assertFalse(mPermissionMonitor.isPreinstalledSystemApp(app));
-
- app = packageInfoWithPermissions(new String[] {}, true);
- assertTrue(mPermissionMonitor.isPreinstalledSystemApp(app));
+ public void testIsVendorApp() {
+ PackageInfo app = packageInfoWithPermissions(new String[] {}, PARTITION_SYSTEM);
+ assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_OEM);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_PRODUCT);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_VENDOR);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
}
@Test
public void testHasUseBackgroundNetworksPermission() throws Exception {
- expectPermission(new String[] { CHANGE_NETWORK_STATE }, false);
+ expectPermission(new String[] { CHANGE_NETWORK_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { NETWORK_STACK }, PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_INTERNAL },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_USE_RESTRICTED_NETWORKS },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { NETWORK_STACK, CONNECTIVITY_INTERNAL }, false);
+ expectPermission(new String[] { CHANGE_NETWORK_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { NETWORK_STACK },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_INTERNAL },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_USE_RESTRICTED_NETWORKS },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- // TODO : make this false when b/31479477 is fixed
- expectPermission(new String[] {}, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { CHANGE_WIFI_STATE }, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
-
- expectPermission(new String[] { NETWORK_STACK, CONNECTIVITY_INTERNAL }, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
-
- expectPermission(new String[] {}, false);
+ expectPermission(new String[] {}, PARTITION_SYSTEM, Build.VERSION_CODES.P);
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] {}, PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { CHANGE_WIFI_STATE }, false);
+ expectPermission(new String[] {}, PARTITION_SYSTEM, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] {}, PARTITION_VENDOR, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.Q);
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
}
}