diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index badb7670adadd..c76aca1d5ff09 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -332,10 +332,10 @@ public class ConnectivityManager /** * 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 @@ -346,7 +346,35 @@ public class ConnectivityManager } catch (RemoteException e) { } } - + + /** + * Gets the value of the setting for enabling Mobile data. + * + * @return Whether mobile data is enabled. + * @hide + */ + public boolean getMobileDataEnabled() { + try { + return mService.getMobileDataEnabled(); + } catch (RemoteException e) { + return true; + } + } + + /** + * Sets the persisted value for enabling/disabling Mobile data. + * + * @param allowMobileData Whether the mobile data connection should be + * used or not. + * @hide + */ + public void setMobileDataEnabled(boolean enabled) { + try { + mService.setMobileDataEnabled(enabled); + } 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 508e9c3acb5d9..2514693936e75 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -51,6 +51,10 @@ interface IConnectivityManager void setBackgroundDataSetting(boolean allowBackgroundData); + boolean getMobileDataEnabled(); + + void setMobileDataEnabled(boolean enabled); + boolean tether(String iface); boolean untether(String iface); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index a020da4591e1a..b75a8ccfaa669 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2465,6 +2465,13 @@ public final class Settings { */ public static final String BACKGROUND_DATA = "background_data"; + /** + * Whether mobile data connections are allowed by the user. See + * ConnectivityManager for more info. + * @hide + */ + public static final String MOBILE_DATA = "mobile_data"; + /** * The CDMA roaming mode 0 = Home Networks, CDMA default * 1 = Roaming on Affiliated networks diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 108246daa1b91..df685abc17aeb 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -289,6 +289,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { * the number of different network types is not going * to change very often. */ + boolean noMobileData = !getMobileDataEnabled(); for (int netType : mPriorityList) { switch (mNetAttributes[netType].mRadio) { case ConnectivityManager.TYPE_WIFI: @@ -306,6 +307,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { mNetTrackers[netType] = new MobileDataStateTracker(context, mHandler, netType, mNetAttributes[netType].mName); mNetTrackers[netType].startMonitoring(); + if (noMobileData) { + if (DBG) Log.d(TAG, "tearing down Mobile networks due to setting"); + mNetTrackers[netType].teardown(); + } break; default: Log.e(TAG, "Trying to create a DataStateTracker for an unknown radio type " + @@ -530,6 +535,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { // TODO - move this into the MobileDataStateTracker int usedNetworkType = networkType; if(networkType == ConnectivityManager.TYPE_MOBILE) { + if (!getMobileDataEnabled()) { + if (DBG) Log.d(TAG, "requested special network with data disabled - rejected"); + return Phone.APN_TYPE_NOT_AVAILABLE; + } if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS; } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { @@ -767,6 +776,46 @@ public class ConnectivityService extends IConnectivityManager.Stub { mContext.sendBroadcast(broadcast); } + /** + * @see ConnectivityManager#getMobileDataEnabled() + */ + public boolean getMobileDataEnabled() { + enforceAccessPermission(); + boolean retVal = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.MOBILE_DATA, 1) == 1; + if (DBG) Log.d(TAG, "getMobileDataEnabled returning " + retVal); + return retVal; + } + + /** + * @see ConnectivityManager#setMobileDataEnabled(boolean) + */ + public synchronized void setMobileDataEnabled(boolean enabled) { + enforceChangePermission(); + if (DBG) Log.d(TAG, "setMobileDataEnabled(" + enabled + ")"); + + if (getMobileDataEnabled() == enabled) return; + + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.MOBILE_DATA, enabled ? 1 : 0); + + if (enabled) { + if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) { + if (DBG) Log.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]); + mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect(); + } + } else { + for (NetworkStateTracker nt : mNetTrackers) { + if (nt == null) continue; + int netType = nt.getNetworkInfo().getType(); + if (mNetAttributes[netType].mRadio == ConnectivityManager.TYPE_MOBILE) { + if (DBG) Log.d(TAG, "tearing down " + nt); + nt.teardown(); + } + } + } + } + private int getNumConnectedNetworks() { int numConnectedNets = 0; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index fbb3c4c47de4c..d5f18e0cf8a79 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -23,6 +23,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.IConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiManager; import android.os.AsyncResult; @@ -188,8 +190,16 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { // and 2) whether the RIL will setup the baseband to auto-PS attach. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext()); + boolean dataEnabledSetting = true; + try { + dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager. + getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled(); + } catch (Exception e) { + // nothing to do - use the old behavior and leave data on + } dataEnabled[APN_DEFAULT_ID] = - !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false); + !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false) && + dataEnabledSetting; if (dataEnabled[APN_DEFAULT_ID]) { enabledCount++; } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 1fd6be8be5852..30beaaad621c1 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -27,6 +27,8 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.ContentObserver; import android.database.Cursor; +import android.net.ConnectivityManager; +import android.net.IConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.net.wifi.WifiManager; @@ -243,7 +245,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // This preference tells us 1) initial condition for "dataEnabled", // and 2) whether the RIL will setup the baseband to auto-PS attach. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext()); - dataEnabled[APN_DEFAULT_ID] = !sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false); + boolean dataEnabledSetting = true; + try { + dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager. + getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled(); + } catch (Exception e) { + // nothing to do - use the old behavior and leave data on + } + dataEnabled[APN_DEFAULT_ID] = !sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false) && + dataEnabledSetting; if (dataEnabled[APN_DEFAULT_ID]) { enabledCount++; }