diff options
author | Billy Lau <billylau@google.com> | 2015-08-07 22:16:03 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-08-07 22:16:03 +0000 |
commit | 70f998e57df2b3ed79331669a93a0ba314f25e7d (patch) | |
tree | 1cf8aecb11bdf22074bf7e0bb1c0d4637858e2f0 /core | |
parent | f0e5501e093c688cd293308e0aafc2b55326c255 (diff) | |
parent | a7238a397d5c3431eeb19b5b77e8c7c2bf0e608f (diff) | |
download | frameworks_base-70f998e57df2b3ed79331669a93a0ba314f25e7d.zip frameworks_base-70f998e57df2b3ed79331669a93a0ba314f25e7d.tar.gz frameworks_base-70f998e57df2b3ed79331669a93a0ba314f25e7d.tar.bz2 |
Merge "Bug: 21588539 Move CHANGE_NETWORK_STATE to be in SYSTEM_SETTINGS" into mnc-dev
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/net/ConnectivityManager.java | 5 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 109 | ||||
-rw-r--r-- | core/res/AndroidManifest.xml | 2 |
3 files changed, 101 insertions, 15 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 605acb0..ff6dd32 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -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); } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bb09b05..6e178a4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1408,6 +1408,25 @@ 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. @@ -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 @@ -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. @@ -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); } /** @@ -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); } /** @@ -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); } /** @@ -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; } @@ -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 - .PERMISSION_GRANTED) { - return true; + // 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()); } /** diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 699e113..425f39f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -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. |