diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 213813a814..1429bc1aff 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -16,6 +16,8 @@ package android.net; +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; import android.os.RemoteException; /** @@ -100,6 +102,18 @@ public class ConnectivityManager */ public static final String EXTRA_EXTRA_INFO = "extraInfo"; + /** + * Broadcast Action: The setting for background data usage has changed + * values. Use {@link #getBackgroundDataSetting()} to get the current value. + *
+ * If an application uses the network in the background, it should listen + * for this broadcast and stop using the background data if the value is + * false. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = + "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; + public static final int TYPE_MOBILE = 0; public static final int TYPE_WIFI = 1; @@ -223,6 +237,43 @@ public class ConnectivityManager } } + /** + * Returns the value of the setting for background data usage. If false, + * applications should not use the network if the application is not in the + * foreground. Developers should respect this setting, and check the value + * of this before performing any background data operations. + *
+ * All applications that have background services that use the network + * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}. + * + * @return Whether background data usage is allowed. + */ + public boolean getBackgroundDataSetting() { + try { + return mService.getBackgroundDataSetting(); + } catch (RemoteException e) { + // Err on the side of safety + return false; + } + } + + /** + * Sets the value of the setting for background data usage. + * + * @param allowBackgroundData Whether an application should use data while + * it is in the background. + * + * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING + * @see #getBackgroundDataSetting() + * @hide + */ + public void setBackgroundDataSetting(boolean allowBackgroundData) { + try { + mService.setBackgroundDataSetting(allowBackgroundData); + } catch (RemoteException e) { + } + } + /** * Don't allow use of default constructor. */ diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index e1d921f4d9..de6859809d 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -44,4 +44,8 @@ interface IConnectivityManager int stopUsingNetworkFeature(int networkType, in String feature); boolean requestRouteToHost(int networkType, int hostAddress); + + boolean getBackgroundDataSetting(); + + void setBackgroundDataSetting(boolean allowBackgroundData); } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 65e36509a9..760988d9f3 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -35,6 +35,7 @@ import android.os.Message; import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; +import android.provider.Sync; import android.util.EventLog; import android.util.Log; @@ -333,6 +334,32 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + /** + * @see ConnectivityManager#getBackgroundDataSetting() + */ + public boolean getBackgroundDataSetting() { + return Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.BACKGROUND_DATA, 1) == 1; + } + + /** + * @see ConnectivityManager#setBackgroundDataSetting(boolean) + */ + public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING, + "ConnectivityService"); + + if (getBackgroundDataSetting() == allowBackgroundDataUsage) return; + + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.BACKGROUND_DATA, allowBackgroundDataUsage ? 1 : 0); + + Intent broadcast = new Intent( + ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); + mContext.sendBroadcast(broadcast); + } + private int getNumConnectedNetworks() { int numConnectedNets = 0; @@ -632,7 +659,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingPermission(android.Manifest.permission.DUMP) + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println("Permission Denial: can't dump ConnectivityService from from pid=" + Binder.getCallingPid()