Loading core/java/android/net/ConnectivityManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -1414,8 +1414,9 @@ public class ConnectivityManager { context.enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService"); } else { context.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); int uid = Binder.getCallingUid(); Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings .getPackageNameForUid(context, uid), true); } } Loading core/java/android/provider/Settings.java +97 −12 Original line number Diff line number Diff line Loading @@ -1407,6 +1407,25 @@ public final class Settings { .getPackageNameForUid(context, uid), false); } /** * An app can use this method to check if it is currently allowed to change the network * state. In order to be allowed to do so, an app must first declare either the * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} or * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it * is currently disallowed, it can prompt the user to grant it this capability through a * management UI by sending an Intent with action * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. * * @param context A context * @return true if the calling app can change the state of network, false otherwise. * @hide */ public static boolean canChangeNetworkState(Context context) { int uid = Binder.getCallingUid(); return Settings.isCallingPackageAllowedToChangeNetworkState(context, uid, Settings .getPackageNameForUid(context, uid), false); } /** * System settings, containing miscellaneous system preferences. This * table holds simple name/value pairs. There are convenience Loading Loading @@ -8252,6 +8271,17 @@ public final class Settings { return "android-" + Long.toHexString(androidId); } private static final String[] PM_WRITE_SETTINGS = { android.Manifest.permission.WRITE_SETTINGS }; private static final String[] PM_CHANGE_NETWORK_STATE = { android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.WRITE_SETTINGS }; private static final String[] PM_SYSTEM_ALERT_WINDOW = { android.Manifest.permission.SYSTEM_ALERT_WINDOW }; /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and Loading @@ -8263,14 +8293,15 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, android.Manifest.permission.WRITE_SETTINGS, false); PM_WRITE_SETTINGS, false); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. * callingPackage, a negative result will be returned. The caller is expected to have * either WRITE_SETTINGS or CHANGE_NETWORK_STATE permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. Loading @@ -8280,7 +8311,40 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, android.Manifest.permission.WRITE_SETTINGS, true); PM_WRITE_SETTINGS, true); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * change the state of network, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. The caller is expected to have * either of CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. * @hide */ public static boolean isCallingPackageAllowedToChangeNetworkState(Context context, int uid, String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, false); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * change the state of network, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. The caller is expected to have * either CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. * @hide */ public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid, String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, true); } /** Loading @@ -8294,7 +8358,7 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, android.Manifest.permission.SYSTEM_ALERT_WINDOW, false); PM_SYSTEM_ALERT_WINDOW, false); } /** Loading @@ -8311,7 +8375,7 @@ public final class Settings { callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, android.Manifest.permission.SYSTEM_ALERT_WINDOW, true); PM_SYSTEM_ALERT_WINDOW, true); } /** Loading @@ -8321,8 +8385,8 @@ public final class Settings { * @hide */ public static boolean isCallingPackageAllowedToPerformAppOpsProtectedOperation(Context context, int uid, String callingPackage, boolean throwException, int appOpsOpCode, String permissionName, boolean makeNote) { int uid, String callingPackage, boolean throwException, int appOpsOpCode, String[] permissions, boolean makeNote) { if (callingPackage == null) { return false; } Loading @@ -8338,20 +8402,41 @@ public final class Settings { switch (mode) { case AppOpsManager.MODE_ALLOWED: return true; case AppOpsManager.MODE_DEFAULT: // this is the default operating mode after an app's installation if(context.checkCallingOrSelfPermission(permissionName) == PackageManager // In this case we will check all associated static permission to see // if it is granted during install time. for (String permission : permissions) { if (context.checkCallingOrSelfPermission(permission) == PackageManager .PERMISSION_GRANTED) { // if either of the permissions are granted, we will allow it return true; } } default: // this is for all other cases trickled down here... if (!throwException) { return false; } } throw new SecurityException(callingPackage + " was not granted " + permissionName + " permission"); // prepare string to throw SecurityException StringBuilder exceptionMessage = new StringBuilder(); exceptionMessage.append(callingPackage); exceptionMessage.append(" was not granted "); if (permissions.length > 1) { exceptionMessage.append(" either of these permissions: "); } else { exceptionMessage.append(" this permission: "); } for (int i = 0; i < permissions.length; i++) { exceptionMessage.append(permissions[i]); exceptionMessage.append((i == permissions.length - 1) ? "." : ", "); } throw new SecurityException(exceptionMessage.toString()); } /** Loading core/res/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -1660,7 +1660,7 @@ <permission android:name="android.permission.CHANGE_NETWORK_STATE" android:description="@string/permdesc_changeNetworkState" android:label="@string/permlab_changeNetworkState" android:protectionLevel="normal" /> android:protectionLevel="signature|preinstalled|appop|pre23" /> <!-- Allows an application to clear the caches of all installed applications on the device. Loading services/core/java/com/android/server/ConnectivityService.java +4 −3 Original line number Diff line number Diff line Loading @@ -1432,9 +1432,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void enforceChangePermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); int uid = Binder.getCallingUid(); Settings.checkAndNoteChangeNetworkStateOperation(mContext, uid, Settings .getPackageNameForUid(mContext, uid), true); } private void enforceTetherAccessPermission() { Loading Loading
core/java/android/net/ConnectivityManager.java +3 −2 Original line number Diff line number Diff line Loading @@ -1414,8 +1414,9 @@ public class ConnectivityManager { context.enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService"); } else { context.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); int uid = Binder.getCallingUid(); Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings .getPackageNameForUid(context, uid), true); } } Loading
core/java/android/provider/Settings.java +97 −12 Original line number Diff line number Diff line Loading @@ -1407,6 +1407,25 @@ public final class Settings { .getPackageNameForUid(context, uid), false); } /** * An app can use this method to check if it is currently allowed to change the network * state. In order to be allowed to do so, an app must first declare either the * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} or * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it * is currently disallowed, it can prompt the user to grant it this capability through a * management UI by sending an Intent with action * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. * * @param context A context * @return true if the calling app can change the state of network, false otherwise. * @hide */ public static boolean canChangeNetworkState(Context context) { int uid = Binder.getCallingUid(); return Settings.isCallingPackageAllowedToChangeNetworkState(context, uid, Settings .getPackageNameForUid(context, uid), false); } /** * System settings, containing miscellaneous system preferences. This * table holds simple name/value pairs. There are convenience Loading Loading @@ -8252,6 +8271,17 @@ public final class Settings { return "android-" + Long.toHexString(androidId); } private static final String[] PM_WRITE_SETTINGS = { android.Manifest.permission.WRITE_SETTINGS }; private static final String[] PM_CHANGE_NETWORK_STATE = { android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.WRITE_SETTINGS }; private static final String[] PM_SYSTEM_ALERT_WINDOW = { android.Manifest.permission.SYSTEM_ALERT_WINDOW }; /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and Loading @@ -8263,14 +8293,15 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, android.Manifest.permission.WRITE_SETTINGS, false); PM_WRITE_SETTINGS, false); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * write/modify system settings, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. * callingPackage, a negative result will be returned. The caller is expected to have * either WRITE_SETTINGS or CHANGE_NETWORK_STATE permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. Loading @@ -8280,7 +8311,40 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, android.Manifest.permission.WRITE_SETTINGS, true); PM_WRITE_SETTINGS, true); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * change the state of network, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. The caller is expected to have * either of CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. * @hide */ public static boolean isCallingPackageAllowedToChangeNetworkState(Context context, int uid, String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, false); } /** * Performs a strict and comprehensive check of whether a calling package is allowed to * change the state of network, as the condition differs for pre-M, M+, and * privileged/preinstalled apps. If the provided uid does not match the * callingPackage, a negative result will be returned. The caller is expected to have * either CHANGE_NETWORK_STATE or WRITE_SETTINGS permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. * @hide */ public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid, String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, true); } /** Loading @@ -8294,7 +8358,7 @@ public final class Settings { String callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, android.Manifest.permission.SYSTEM_ALERT_WINDOW, false); PM_SYSTEM_ALERT_WINDOW, false); } /** Loading @@ -8311,7 +8375,7 @@ public final class Settings { callingPackage, boolean throwException) { return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, android.Manifest.permission.SYSTEM_ALERT_WINDOW, true); PM_SYSTEM_ALERT_WINDOW, true); } /** Loading @@ -8321,8 +8385,8 @@ public final class Settings { * @hide */ public static boolean isCallingPackageAllowedToPerformAppOpsProtectedOperation(Context context, int uid, String callingPackage, boolean throwException, int appOpsOpCode, String permissionName, boolean makeNote) { int uid, String callingPackage, boolean throwException, int appOpsOpCode, String[] permissions, boolean makeNote) { if (callingPackage == null) { return false; } Loading @@ -8338,20 +8402,41 @@ public final class Settings { switch (mode) { case AppOpsManager.MODE_ALLOWED: return true; case AppOpsManager.MODE_DEFAULT: // this is the default operating mode after an app's installation if(context.checkCallingOrSelfPermission(permissionName) == PackageManager // In this case we will check all associated static permission to see // if it is granted during install time. for (String permission : permissions) { if (context.checkCallingOrSelfPermission(permission) == PackageManager .PERMISSION_GRANTED) { // if either of the permissions are granted, we will allow it return true; } } default: // this is for all other cases trickled down here... if (!throwException) { return false; } } throw new SecurityException(callingPackage + " was not granted " + permissionName + " permission"); // prepare string to throw SecurityException StringBuilder exceptionMessage = new StringBuilder(); exceptionMessage.append(callingPackage); exceptionMessage.append(" was not granted "); if (permissions.length > 1) { exceptionMessage.append(" either of these permissions: "); } else { exceptionMessage.append(" this permission: "); } for (int i = 0; i < permissions.length; i++) { exceptionMessage.append(permissions[i]); exceptionMessage.append((i == permissions.length - 1) ? "." : ", "); } throw new SecurityException(exceptionMessage.toString()); } /** Loading
core/res/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -1660,7 +1660,7 @@ <permission android:name="android.permission.CHANGE_NETWORK_STATE" android:description="@string/permdesc_changeNetworkState" android:label="@string/permlab_changeNetworkState" android:protectionLevel="normal" /> android:protectionLevel="signature|preinstalled|appop|pre23" /> <!-- Allows an application to clear the caches of all installed applications on the device. Loading
services/core/java/com/android/server/ConnectivityService.java +4 −3 Original line number Diff line number Diff line Loading @@ -1432,9 +1432,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void enforceChangePermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService"); int uid = Binder.getCallingUid(); Settings.checkAndNoteChangeNetworkStateOperation(mContext, uid, Settings .getPackageNameForUid(mContext, uid), true); } private void enforceTetherAccessPermission() { Loading