diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2015-10-15 16:29:00 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2015-10-22 08:33:45 +0900 |
commit | d54270506669e474b5b8d1703212c77780a04ae9 (patch) | |
tree | 404247ea86ef12fe66b445b18dab7c43cef96e0f /core | |
parent | 46d50b708de20e2a26a61ba516c524841b4e11dc (diff) | |
download | frameworks_base-d54270506669e474b5b8d1703212c77780a04ae9.zip frameworks_base-d54270506669e474b5b8d1703212c77780a04ae9.tar.gz frameworks_base-d54270506669e474b5b8d1703212c77780a04ae9.tar.bz2 |
Reinstate CHANGE_NETWORK_STATE as a normal permission.
This is a partial revert of http://ag/738523 , but not a full
revert because M apps that have gone through the WRITE_SETTINGS
route to obtain permission to change network state should
continue to have permission to do so.
Specifically:
1. Change the protection level of CHANGE_NETWORK_STATE back from
"signature|preinstalled|appop|pre23" to "normal". This allows
apps that declare CHANGE_NETWORK_STATE in their manifest to
acquire it, even if they target the M SDK or above.
2. Change the ConnectivityManager permission checks so that they
first check CHANGE_NETWORK_STATE, and then ask Settings
if the app has the WRITE_SETTINGS runtime permission.
3. Slightly simplify the code in the Settings provider code that
deals specifically with the ability to change network state.
4. Make the ConnectivityService permissions checks use the
ConnectivityManager code to avoid code duplication.
5. Update the ConnectivityManager public Javadoc to list both
CHANGE_NETWORK_STATE and WRITE_SETTINGS.
Bug: 21588539
Bug: 23597341
Change-Id: Ic06a26517c95f9ad94183f6d126fd0de45de346e
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/net/ConnectivityManager.java | 87 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 52 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 4 |
3 files changed, 79 insertions, 64 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 9a2a241..4d9b759 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -895,8 +895,12 @@ public class ConnectivityManager { * Tells the underlying networking system that the caller wants to * begin using the named feature. The interpretation of {@code feature} * is completely up to each networking implementation. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param networkType specifies which network the request pertains to * @param feature the name of the feature to be used * @return an integer value representing the outcome of the request. @@ -946,8 +950,12 @@ public class ConnectivityManager { * Tells the underlying networking system that the caller is finished * using the named feature. The interpretation of {@code feature} * is completely up to each networking implementation. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param networkType specifies which network the request pertains to * @param feature the name of the feature that is no longer needed * @return an integer value representing the outcome of the request. @@ -1333,8 +1341,12 @@ public class ConnectivityManager { * Ensure that a network route exists to deliver traffic to the specified * host via the specified network interface. An attempt to add a route that * already exists is ignored, but treated as successful. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param networkType the type of the network over which traffic to the specified * host is to be routed * @param hostAddress the IP address of the host to which the route is desired @@ -1354,8 +1366,12 @@ public class ConnectivityManager { * Ensure that a network route exists to deliver traffic to the specified * host via the specified network interface. An attempt to add a route that * already exists is ignored, but treated as successful. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param networkType the type of the network over which traffic to the specified * host is to be routed * @param hostAddress the IP address of the host to which the route is desired @@ -1555,6 +1571,13 @@ public class ConnectivityManager { return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); } + /** {@hide} */ + public static final void enforceChangePermission(Context context) { + int uid = Binder.getCallingUid(); + Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings + .getPackageNameForUid(context, uid), true /* throwException */); + } + /** {@hide */ public static final void enforceTetherChangePermission(Context context) { if (context.getResources().getStringArray( @@ -1565,8 +1588,8 @@ public class ConnectivityManager { android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService"); } else { int uid = Binder.getCallingUid(); - Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings - .getPackageNameForUid(context, uid), true); + Settings.checkAndNoteWriteSettingsOperation(context, uid, Settings + .getPackageNameForUid(context, uid), true /* throwException */); } } @@ -1671,8 +1694,11 @@ public class ConnectivityManager { * allowed between the tethered devices and this device, though upstream net * access will of course fail until an upstream network interface becomes * active. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> * * @param iface the interface name to tether. * @return error a {@code TETHER_ERROR} value indicating success or failure type @@ -1689,8 +1715,11 @@ public class ConnectivityManager { /** * Stop tethering the named interface. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> * * @param iface the interface name to untether. * @return error a {@code TETHER_ERROR} value indicating success or failure type @@ -1790,8 +1819,11 @@ public class ConnectivityManager { * attempt to switch to Rndis and subsequently tether the resulting * interface on {@code true} or turn off tethering and switch off * Rndis on {@code false}. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> * * @param enable a boolean - {@code true} to enable tethering * @return error a {@code TETHER_ERROR} value indicating success or failure type @@ -2461,8 +2493,11 @@ public class ConnectivityManager { * network may never attain, and whether a network will attain these states * is unknown prior to bringing up the network so the framework does not * know how to go about satisfing a request with these capabilities. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> * * @param request {@link NetworkRequest} describing this request. * @param networkCallback The {@link NetworkCallback} to be utilized for this @@ -2484,8 +2519,12 @@ public class ConnectivityManager { * network is not found within the given time (in milliseconds) the * {@link NetworkCallback#unavailable} callback is called. The request must * still be released normally by calling {@link releaseNetworkRequest}. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param request {@link NetworkRequest} describing this request. * @param networkCallback The callbacks to be utilized for this request. Note * the callbacks must not be shared - they uniquely specify @@ -2558,8 +2597,12 @@ public class ConnectivityManager { * network may never attain, and whether a network will attain these states * is unknown prior to bringing up the network so the framework does not * know how to go about satisfing a request with these capabilities. - * <p>This method requires the caller to hold the permission - * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. + * + * <p>This method requires the caller to hold either the + * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission + * or the ability to modify system settings as determined by + * {@link android.provider.Settings.System#canWrite}.</p> + * * @param request {@link NetworkRequest} describing this request. * @param operation Action to perform when the network is available (corresponds * to the {@link NetworkCallback#onAvailable} call. Typically diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1822067..53897e0 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1434,25 +1434,6 @@ public final class Settings { } /** - * 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 * functions for accessing individual settings entries. @@ -8343,7 +8324,7 @@ public final class Settings { * 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. The caller is expected to have - * either WRITE_SETTINGS or CHANGE_NETWORK_STATE permission declared. + * the WRITE_SETTINGS permission declared. * * Note: if the check is successful, the operation of this app will be updated to the * current time. @@ -8359,31 +8340,22 @@ public final class Settings { /** * 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. + * privileged/preinstalled apps. The caller is expected to have either the + * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these + * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and + * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal + * permission and cannot be revoked. See http://b/23597341 * - * Note: if the check is successful, the operation of this app will be updated to the - * current time. + * Note: if the check succeeds because the application holds WRITE_SETTINGS, 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) { + if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE) + == PackageManager.PERMISSION_GRANTED) { + return true; + } return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, true); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index f13f821..e00689d 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1699,12 +1699,12 @@ android:protectionLevel="signature|privileged" /> <!-- Allows applications to change network connectivity state. - <p>Protection level: signature + <p>Protection level: normal --> <permission android:name="android.permission.CHANGE_NETWORK_STATE" android:description="@string/permdesc_changeNetworkState" android:label="@string/permlab_changeNetworkState" - android:protectionLevel="signature|preinstalled|appop|pre23" /> + android:protectionLevel="normal" /> <!-- Allows an application to clear the caches of all installed applications on the device. |