Loading core/java/android/net/MobileDataStateTracker.java +22 −157 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.IntentFilter; import android.os.RemoteException; import android.os.Handler; import android.os.ServiceManager; import android.os.SystemProperties; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TelephonyIntents; Loading @@ -48,9 +47,6 @@ public class MobileDataStateTracker extends NetworkStateTracker { private ITelephony mPhoneService; private String mApnType; private String mApnTypeToWatchFor; private String mApnName; private boolean mEnabled; private BroadcastReceiver mStateReceiver; /** Loading @@ -66,18 +62,8 @@ public class MobileDataStateTracker extends NetworkStateTracker { TelephonyManager.getDefault().getNetworkType(), tag, TelephonyManager.getDefault().getNetworkTypeName()); mApnType = networkTypeToApnType(netType); if (TextUtils.equals(mApnType, Phone.APN_TYPE_HIPRI)) { mApnTypeToWatchFor = Phone.APN_TYPE_DEFAULT; } else { mApnTypeToWatchFor = mApnType; } mPhoneService = null; if(netType == ConnectivityManager.TYPE_MOBILE) { mEnabled = true; } else { mEnabled = false; } mDnsPropNames = new String[] { "net.rmnet0.dns1", Loading @@ -103,89 +89,38 @@ public class MobileDataStateTracker extends NetworkStateTracker { filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); mStateReceiver = new MobileDataStateReceiver(); Intent intent = mContext.registerReceiver(mStateReceiver, filter); if (intent != null) mMobileDataState = getMobileDataState(intent); else mContext.registerReceiver(mStateReceiver, filter); mMobileDataState = Phone.DataState.DISCONNECTED; } private Phone.DataState getMobileDataState(Intent intent) { String str = intent.getStringExtra(Phone.STATE_KEY); if (str != null) { String apnTypeList = intent.getStringExtra(Phone.DATA_APN_TYPES_KEY); if (isApnTypeIncluded(apnTypeList)) { return Enum.valueOf(Phone.DataState.class, str); } } return Phone.DataState.DISCONNECTED; } private boolean isApnTypeIncluded(String typeList) { /* comma seperated list - split and check */ if (typeList == null) return false; String[] list = typeList.split(","); for(int i=0; i< list.length; i++) { if (TextUtils.equals(list[i], mApnTypeToWatchFor) || TextUtils.equals(list[i], Phone.APN_TYPE_ALL)) { return true; } } return false; } private class MobileDataStateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { synchronized(this) { if (intent.getAction().equals(TelephonyIntents. ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { Phone.DataState state = getMobileDataState(intent); String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); if (!TextUtils.equals(apnType, mApnType)) { return; } Phone.DataState state = Enum.valueOf(Phone.DataState.class, intent.getStringExtra(Phone.STATE_KEY)); String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); String apnTypeList = intent.getStringExtra(Phone.DATA_APN_TYPES_KEY); mApnName = apnName; boolean unavailable = intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY, false); // set this regardless of the apnTypeList. It's all the same radio/network // underneath mNetworkInfo.setIsAvailable(!unavailable); if (isApnTypeIncluded(apnTypeList)) { if (mEnabled == false) { // if we're not enabled but the APN Type is supported by this connection // we should record the interface name if one's provided. If the user // turns on this network we will need the interfacename but won't get // a fresh connected message - TODO fix this when we get per-APN // notifications if (state == Phone.DataState.CONNECTED) { if (DBG) Log.d(TAG, "replacing old mInterfaceName (" + mInterfaceName + ") with " + intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY) + " for " + mApnType); mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY); } return; } } else { return; } if (DBG) Log.d(TAG, mApnType + " Received state= " + state + ", old= " + mMobileDataState + ", reason= " + (reason == null ? "(unspecified)" : reason) + ", apnTypeList= " + apnTypeList); (reason == null ? "(unspecified)" : reason)); if (mMobileDataState != state) { mMobileDataState = state; switch (state) { case DISCONNECTED: if(isTeardownRequested()) { mEnabled = false; setTeardownRequested(false); } Loading Loading @@ -218,11 +153,14 @@ public class MobileDataStateTracker extends NetworkStateTracker { } } else if (intent.getAction(). equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) { mEnabled = false; String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); if (!TextUtils.equals(apnType, mApnType)) { return; } String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY); String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); if (DBG) Log.d(TAG, "Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); if (DBG) Log.d(TAG, mApnType + "Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); setDetailedState(DetailedState.FAILED, reason, apnName); } TelephonyManager tm = TelephonyManager.getDefault(); Loading Loading @@ -320,70 +258,38 @@ public class MobileDataStateTracker extends NetworkStateTracker { /** * Tear down mobile data connectivity, i.e., disable the ability to create * mobile data connections. * TODO - make async and return nothing? */ @Override public boolean teardown() { // since we won't get a notification currently (TODO - per APN notifications) // we won't get a disconnect message until all APN's on the current connection's // APN list are disabled. That means privateRoutes for DNS and such will remain on - // not a problem since that's all shared with whatever other APN is still on, but // ugly. setTeardownRequested(true); return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED); } /** * Re-enable mobile data connectivity after a {@link #teardown()}. * TODO - make async and always get a notification? */ public boolean reconnect() { boolean retValue = false; //connected or expect to be? setTeardownRequested(false); switch (setEnableApn(mApnType, true)) { case Phone.APN_ALREADY_ACTIVE: // TODO - remove this when we get per-apn notifications mEnabled = true; // need to set self to CONNECTING so the below message is handled. mMobileDataState = Phone.DataState.CONNECTING; setDetailedState(DetailedState.CONNECTING, Phone.REASON_APN_CHANGED, null); //send out a connected message Intent intent = new Intent(TelephonyIntents. ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); intent.putExtra(Phone.STATE_KEY, Phone.DataState.CONNECTED.toString()); intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, Phone.REASON_APN_CHANGED); intent.putExtra(Phone.DATA_APN_TYPES_KEY, mApnTypeToWatchFor); intent.putExtra(Phone.DATA_APN_KEY, mApnName); intent.putExtra(Phone.DATA_IFACE_NAME_KEY, mInterfaceName); intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, false); if (mStateReceiver != null) mStateReceiver.onReceive(mContext, intent); retValue = true; break; case Phone.APN_REQUEST_STARTED: mEnabled = true; // no need to do anything - we're already due some status update intents retValue = true; break; case Phone.APN_REQUEST_FAILED: if (mPhoneService == null && mApnType == Phone.APN_TYPE_DEFAULT) { // on startup we may try to talk to the phone before it's ready // since the phone will come up enabled, go with that. // TODO - this also comes up on telephony crash: if we think mobile data is // off and the telephony stuff crashes and has to restart it will come up // enabled (making a data connection). We will then be out of sync. // A possible solution is a broadcast when telephony restarts. mEnabled = true; return false; } // else fall through case Phone.APN_TYPE_NOT_AVAILABLE: // Default is always available, but may be off due to // AirplaneMode or E-Call or whatever.. if (mApnType != Phone.APN_TYPE_DEFAULT) { mEnabled = false; } break; default: Log.e(TAG, "Error in reconnect - unexpected response."); mEnabled = false; break; } return mEnabled; return retValue; } /** Loading Loading @@ -415,47 +321,6 @@ public class MobileDataStateTracker extends NetworkStateTracker { return false; } /** * Tells the phone sub-system that the caller wants to * begin using the named feature. The only supported features at * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application * to specify that it wants to send and/or receive MMS data, and * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS. * @param feature the name of the feature to be used * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is feature-specific. * specific, except that the value {@code -1} * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS}, * the other possible return values are * <ul> * <li>{@code Phone.APN_ALREADY_ACTIVE}</li> * <li>{@code Phone.APN_REQUEST_STARTED}</li> * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li> * <li>{@code Phone.APN_REQUEST_FAILED}</li> * </ul> */ public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) { return -1; } /** * Tells the phone sub-system that the caller is finished * using the named feature. The only supported feature at * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application * to specify that it wants to send and/or receive MMS data. * @param feature the name of the feature that is no longer needed * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is feature-specific, except that * the value {@code -1} always indicates failure. */ public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) { return -1; } /** * Ensure that a network route exists to deliver traffic to the specified * host via the mobile data network. Loading core/java/android/net/NetworkStateTracker.java +1 −28 Original line number Diff line number Diff line Loading @@ -348,6 +348,7 @@ public abstract class NetworkStateTracker extends Handler { /** * Reenable connectivity to a network after a {@link #teardown()}. * @return {@code true} if we're connected or expect to be connected */ public abstract boolean reconnect(); Loading @@ -364,34 +365,6 @@ public abstract class NetworkStateTracker extends Handler { */ public abstract boolean isAvailable(); /** * 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. * @param feature the name of the feature to be used * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is specific to each networking * implementation+feature combination, except that the value {@code -1} * always indicates failure. */ public abstract int startUsingNetworkFeature(String feature, int callingPid, int callingUid); /** * 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. * @param feature the name of the feature that is no longer needed. * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is specific to each networking * implementation+feature combination, except that the value {@code -1} * always indicates failure. */ public abstract int stopUsingNetworkFeature(String feature, int callingPid, int callingUid); /** * Ensure that a network route exists to deliver traffic to the specified * host via this network interface. Loading services/java/com/android/server/ConnectivityService.java +2 −11 Original line number Diff line number Diff line Loading @@ -597,15 +597,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { network.reconnect(); return Phone.APN_REQUEST_STARTED; } else { synchronized(this) { mFeatureUsers.add(f); } mHandler.sendMessageDelayed(mHandler.obtainMessage( NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, f), getRestoreDefaultNetworkDelay()); return network.startUsingNetworkFeature(feature, getCallingPid(), getCallingUid()); return -1; } } return Phone.APN_TYPE_NOT_AVAILABLE; Loading Loading @@ -724,8 +716,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { tracker.teardown(); return 1; } else { // do it the old fashioned way return tracker.stopUsingNetworkFeature(feature, pid, uid); return -1; } } Loading services/java/com/android/server/TelephonyRegistry.java +51 −43 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private String mDataConnectionApn = ""; private String[] mDataConnectionApnTypes = null; private ArrayList<String> mConnectedApns; private String mDataConnectionInterfaceName = ""; Loading Loading @@ -120,6 +120,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } mContext = context; mBatteryStats = BatteryStatsService.getService(); mConnectedApns = new ArrayList<String>(); } public void listen(String pkgForDebug, IPhoneStateListener callback, int events, Loading Loading @@ -235,8 +236,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { mCallState = state; mCallIncomingNumber = incomingNumber; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { try { r.callback.onCallStateChanged(state, incomingNumber); Loading @@ -255,8 +255,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mServiceState = state; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { sendServiceState(r, state); } Loading @@ -271,8 +270,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mSignalStrength = signalStrength; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { sendSignalStrength(r, signalStrength); } Loading @@ -296,8 +294,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mMessageWaiting = mwi; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { try { r.callback.onMessageWaitingIndicatorChanged(mwi); Loading @@ -315,8 +312,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mCallForwarding = cfi; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { try { r.callback.onCallForwardingIndicatorChanged(cfi); Loading @@ -334,8 +330,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mDataActivity = state; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { try { r.callback.onDataActivity(state); Loading @@ -348,20 +343,40 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String[] apnTypes, String interfaceName, int networkType) { String reason, String apn, String apnType, String interfaceName, int networkType) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } synchronized (mRecords) { boolean modified = false; if (state == TelephonyManager.DATA_CONNECTED) { if (!mConnectedApns.contains(apnType)) { mConnectedApns.add(apnType); if (mDataConnectionState != state) { mDataConnectionState = state; modified = true; } } } else { mConnectedApns.remove(apnType); if (mConnectedApns.isEmpty()) { mDataConnectionState = state; modified = true; } else { // we're still connected, so send that out if we send anything. state = mDataConnectionState; } } mDataConnectionPossible = isDataConnectivityPossible; mDataConnectionReason = reason; mDataConnectionApn = apn; mDataConnectionApnTypes = apnTypes; mDataConnectionInterfaceName = interfaceName; if (mDataConnectionNetworkType != networkType) { mDataConnectionNetworkType = networkType; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); modified = true; } if (modified) { for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { try { r.callback.onDataConnectionStateChanged(state, networkType); Loading @@ -371,17 +386,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } } broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, apnTypes, interfaceName); apnType, interfaceName); } public void notifyDataConnectionFailed(String reason) { public void notifyDataConnectionFailed(String reason, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; } /* * This is commented out because there is on onDataConnectionFailed callback * on PhoneStateListener. There should be * This is commented out because there is no onDataConnectionFailed callback * in PhoneStateListener. There should be. synchronized (mRecords) { mDataConnectionFailedReason = reason; final int N = mRecords.size(); Loading @@ -393,7 +409,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } */ broadcastDataConnectionFailed(reason); broadcastDataConnectionFailed(reason, apnType); } public void notifyCellLocation(Bundle cellLocation) { Loading @@ -402,8 +418,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mCellLocation = cellLocation; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { sendCellLocation(r, cellLocation); } Loading Loading @@ -463,8 +478,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName); pw.println(" mCellLocation=" + mCellLocation); pw.println("registrations: count=" + recordCount); for (int i = 0; i < recordCount; i++) { Record r = mRecords.get(i); for (Record r : mRecords) { pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events)); } } Loading Loading @@ -535,7 +549,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible, String reason, String apn, String[] apnTypes, String interfaceName) { String reason, String apn, String apnType, String interfaceName) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. Loading @@ -549,22 +563,16 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason); } intent.putExtra(Phone.DATA_APN_KEY, apn); String types = new String(""); if (apnTypes.length > 0) { types = apnTypes[0]; for (int i = 1; i < apnTypes.length; i++) { types = types+","+apnTypes[i]; } } intent.putExtra(Phone.DATA_APN_TYPES_KEY, types); intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName); mContext.sendStickyBroadcast(intent); } private void broadcastDataConnectionFailed(String reason) { private void broadcastDataConnectionFailed(String reason, String apnType) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.FAILURE_REASON_KEY, reason); intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); mContext.sendStickyBroadcast(intent); } Loading telephony/java/android/telephony/PhoneStateListener.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.telephony.CellLocation; import android.util.Log; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.Phone; /** * A listener class for monitoring changes in specific telephony states Loading Loading @@ -284,7 +285,7 @@ public class PhoneStateListener { } public void onDataConnectionStateChanged(int state, int networkType) { Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType, null). Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType). sendToTarget(); } Loading Loading
core/java/android/net/MobileDataStateTracker.java +22 −157 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.IntentFilter; import android.os.RemoteException; import android.os.Handler; import android.os.ServiceManager; import android.os.SystemProperties; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TelephonyIntents; Loading @@ -48,9 +47,6 @@ public class MobileDataStateTracker extends NetworkStateTracker { private ITelephony mPhoneService; private String mApnType; private String mApnTypeToWatchFor; private String mApnName; private boolean mEnabled; private BroadcastReceiver mStateReceiver; /** Loading @@ -66,18 +62,8 @@ public class MobileDataStateTracker extends NetworkStateTracker { TelephonyManager.getDefault().getNetworkType(), tag, TelephonyManager.getDefault().getNetworkTypeName()); mApnType = networkTypeToApnType(netType); if (TextUtils.equals(mApnType, Phone.APN_TYPE_HIPRI)) { mApnTypeToWatchFor = Phone.APN_TYPE_DEFAULT; } else { mApnTypeToWatchFor = mApnType; } mPhoneService = null; if(netType == ConnectivityManager.TYPE_MOBILE) { mEnabled = true; } else { mEnabled = false; } mDnsPropNames = new String[] { "net.rmnet0.dns1", Loading @@ -103,89 +89,38 @@ public class MobileDataStateTracker extends NetworkStateTracker { filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); mStateReceiver = new MobileDataStateReceiver(); Intent intent = mContext.registerReceiver(mStateReceiver, filter); if (intent != null) mMobileDataState = getMobileDataState(intent); else mContext.registerReceiver(mStateReceiver, filter); mMobileDataState = Phone.DataState.DISCONNECTED; } private Phone.DataState getMobileDataState(Intent intent) { String str = intent.getStringExtra(Phone.STATE_KEY); if (str != null) { String apnTypeList = intent.getStringExtra(Phone.DATA_APN_TYPES_KEY); if (isApnTypeIncluded(apnTypeList)) { return Enum.valueOf(Phone.DataState.class, str); } } return Phone.DataState.DISCONNECTED; } private boolean isApnTypeIncluded(String typeList) { /* comma seperated list - split and check */ if (typeList == null) return false; String[] list = typeList.split(","); for(int i=0; i< list.length; i++) { if (TextUtils.equals(list[i], mApnTypeToWatchFor) || TextUtils.equals(list[i], Phone.APN_TYPE_ALL)) { return true; } } return false; } private class MobileDataStateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { synchronized(this) { if (intent.getAction().equals(TelephonyIntents. ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { Phone.DataState state = getMobileDataState(intent); String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); if (!TextUtils.equals(apnType, mApnType)) { return; } Phone.DataState state = Enum.valueOf(Phone.DataState.class, intent.getStringExtra(Phone.STATE_KEY)); String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); String apnTypeList = intent.getStringExtra(Phone.DATA_APN_TYPES_KEY); mApnName = apnName; boolean unavailable = intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY, false); // set this regardless of the apnTypeList. It's all the same radio/network // underneath mNetworkInfo.setIsAvailable(!unavailable); if (isApnTypeIncluded(apnTypeList)) { if (mEnabled == false) { // if we're not enabled but the APN Type is supported by this connection // we should record the interface name if one's provided. If the user // turns on this network we will need the interfacename but won't get // a fresh connected message - TODO fix this when we get per-APN // notifications if (state == Phone.DataState.CONNECTED) { if (DBG) Log.d(TAG, "replacing old mInterfaceName (" + mInterfaceName + ") with " + intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY) + " for " + mApnType); mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY); } return; } } else { return; } if (DBG) Log.d(TAG, mApnType + " Received state= " + state + ", old= " + mMobileDataState + ", reason= " + (reason == null ? "(unspecified)" : reason) + ", apnTypeList= " + apnTypeList); (reason == null ? "(unspecified)" : reason)); if (mMobileDataState != state) { mMobileDataState = state; switch (state) { case DISCONNECTED: if(isTeardownRequested()) { mEnabled = false; setTeardownRequested(false); } Loading Loading @@ -218,11 +153,14 @@ public class MobileDataStateTracker extends NetworkStateTracker { } } else if (intent.getAction(). equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) { mEnabled = false; String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY); if (!TextUtils.equals(apnType, mApnType)) { return; } String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY); String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); if (DBG) Log.d(TAG, "Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); if (DBG) Log.d(TAG, mApnType + "Received " + intent.getAction() + " broadcast" + reason == null ? "" : "(" + reason + ")"); setDetailedState(DetailedState.FAILED, reason, apnName); } TelephonyManager tm = TelephonyManager.getDefault(); Loading Loading @@ -320,70 +258,38 @@ public class MobileDataStateTracker extends NetworkStateTracker { /** * Tear down mobile data connectivity, i.e., disable the ability to create * mobile data connections. * TODO - make async and return nothing? */ @Override public boolean teardown() { // since we won't get a notification currently (TODO - per APN notifications) // we won't get a disconnect message until all APN's on the current connection's // APN list are disabled. That means privateRoutes for DNS and such will remain on - // not a problem since that's all shared with whatever other APN is still on, but // ugly. setTeardownRequested(true); return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED); } /** * Re-enable mobile data connectivity after a {@link #teardown()}. * TODO - make async and always get a notification? */ public boolean reconnect() { boolean retValue = false; //connected or expect to be? setTeardownRequested(false); switch (setEnableApn(mApnType, true)) { case Phone.APN_ALREADY_ACTIVE: // TODO - remove this when we get per-apn notifications mEnabled = true; // need to set self to CONNECTING so the below message is handled. mMobileDataState = Phone.DataState.CONNECTING; setDetailedState(DetailedState.CONNECTING, Phone.REASON_APN_CHANGED, null); //send out a connected message Intent intent = new Intent(TelephonyIntents. ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); intent.putExtra(Phone.STATE_KEY, Phone.DataState.CONNECTED.toString()); intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, Phone.REASON_APN_CHANGED); intent.putExtra(Phone.DATA_APN_TYPES_KEY, mApnTypeToWatchFor); intent.putExtra(Phone.DATA_APN_KEY, mApnName); intent.putExtra(Phone.DATA_IFACE_NAME_KEY, mInterfaceName); intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, false); if (mStateReceiver != null) mStateReceiver.onReceive(mContext, intent); retValue = true; break; case Phone.APN_REQUEST_STARTED: mEnabled = true; // no need to do anything - we're already due some status update intents retValue = true; break; case Phone.APN_REQUEST_FAILED: if (mPhoneService == null && mApnType == Phone.APN_TYPE_DEFAULT) { // on startup we may try to talk to the phone before it's ready // since the phone will come up enabled, go with that. // TODO - this also comes up on telephony crash: if we think mobile data is // off and the telephony stuff crashes and has to restart it will come up // enabled (making a data connection). We will then be out of sync. // A possible solution is a broadcast when telephony restarts. mEnabled = true; return false; } // else fall through case Phone.APN_TYPE_NOT_AVAILABLE: // Default is always available, but may be off due to // AirplaneMode or E-Call or whatever.. if (mApnType != Phone.APN_TYPE_DEFAULT) { mEnabled = false; } break; default: Log.e(TAG, "Error in reconnect - unexpected response."); mEnabled = false; break; } return mEnabled; return retValue; } /** Loading Loading @@ -415,47 +321,6 @@ public class MobileDataStateTracker extends NetworkStateTracker { return false; } /** * Tells the phone sub-system that the caller wants to * begin using the named feature. The only supported features at * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application * to specify that it wants to send and/or receive MMS data, and * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS. * @param feature the name of the feature to be used * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is feature-specific. * specific, except that the value {@code -1} * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS}, * the other possible return values are * <ul> * <li>{@code Phone.APN_ALREADY_ACTIVE}</li> * <li>{@code Phone.APN_REQUEST_STARTED}</li> * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li> * <li>{@code Phone.APN_REQUEST_FAILED}</li> * </ul> */ public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) { return -1; } /** * Tells the phone sub-system that the caller is finished * using the named feature. The only supported feature at * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application * to specify that it wants to send and/or receive MMS data. * @param feature the name of the feature that is no longer needed * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is feature-specific, except that * the value {@code -1} always indicates failure. */ public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) { return -1; } /** * Ensure that a network route exists to deliver traffic to the specified * host via the mobile data network. Loading
core/java/android/net/NetworkStateTracker.java +1 −28 Original line number Diff line number Diff line Loading @@ -348,6 +348,7 @@ public abstract class NetworkStateTracker extends Handler { /** * Reenable connectivity to a network after a {@link #teardown()}. * @return {@code true} if we're connected or expect to be connected */ public abstract boolean reconnect(); Loading @@ -364,34 +365,6 @@ public abstract class NetworkStateTracker extends Handler { */ public abstract boolean isAvailable(); /** * 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. * @param feature the name of the feature to be used * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is specific to each networking * implementation+feature combination, except that the value {@code -1} * always indicates failure. */ public abstract int startUsingNetworkFeature(String feature, int callingPid, int callingUid); /** * 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. * @param feature the name of the feature that is no longer needed. * @param callingPid the process ID of the process that is issuing this request * @param callingUid the user ID of the process that is issuing this request * @return an integer value representing the outcome of the request. * The interpretation of this value is specific to each networking * implementation+feature combination, except that the value {@code -1} * always indicates failure. */ public abstract int stopUsingNetworkFeature(String feature, int callingPid, int callingUid); /** * Ensure that a network route exists to deliver traffic to the specified * host via this network interface. Loading
services/java/com/android/server/ConnectivityService.java +2 −11 Original line number Diff line number Diff line Loading @@ -597,15 +597,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { network.reconnect(); return Phone.APN_REQUEST_STARTED; } else { synchronized(this) { mFeatureUsers.add(f); } mHandler.sendMessageDelayed(mHandler.obtainMessage( NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, f), getRestoreDefaultNetworkDelay()); return network.startUsingNetworkFeature(feature, getCallingPid(), getCallingUid()); return -1; } } return Phone.APN_TYPE_NOT_AVAILABLE; Loading Loading @@ -724,8 +716,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { tracker.teardown(); return 1; } else { // do it the old fashioned way return tracker.stopUsingNetworkFeature(feature, pid, uid); return -1; } } Loading
services/java/com/android/server/TelephonyRegistry.java +51 −43 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private String mDataConnectionApn = ""; private String[] mDataConnectionApnTypes = null; private ArrayList<String> mConnectedApns; private String mDataConnectionInterfaceName = ""; Loading Loading @@ -120,6 +120,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } mContext = context; mBatteryStats = BatteryStatsService.getService(); mConnectedApns = new ArrayList<String>(); } public void listen(String pkgForDebug, IPhoneStateListener callback, int events, Loading Loading @@ -235,8 +236,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { mCallState = state; mCallIncomingNumber = incomingNumber; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { try { r.callback.onCallStateChanged(state, incomingNumber); Loading @@ -255,8 +255,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mServiceState = state; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { sendServiceState(r, state); } Loading @@ -271,8 +270,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mSignalStrength = signalStrength; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { sendSignalStrength(r, signalStrength); } Loading @@ -296,8 +294,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mMessageWaiting = mwi; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { try { r.callback.onMessageWaitingIndicatorChanged(mwi); Loading @@ -315,8 +312,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mCallForwarding = cfi; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { try { r.callback.onCallForwardingIndicatorChanged(cfi); Loading @@ -334,8 +330,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mDataActivity = state; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { try { r.callback.onDataActivity(state); Loading @@ -348,20 +343,40 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String[] apnTypes, String interfaceName, int networkType) { String reason, String apn, String apnType, String interfaceName, int networkType) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } synchronized (mRecords) { boolean modified = false; if (state == TelephonyManager.DATA_CONNECTED) { if (!mConnectedApns.contains(apnType)) { mConnectedApns.add(apnType); if (mDataConnectionState != state) { mDataConnectionState = state; modified = true; } } } else { mConnectedApns.remove(apnType); if (mConnectedApns.isEmpty()) { mDataConnectionState = state; modified = true; } else { // we're still connected, so send that out if we send anything. state = mDataConnectionState; } } mDataConnectionPossible = isDataConnectivityPossible; mDataConnectionReason = reason; mDataConnectionApn = apn; mDataConnectionApnTypes = apnTypes; mDataConnectionInterfaceName = interfaceName; if (mDataConnectionNetworkType != networkType) { mDataConnectionNetworkType = networkType; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); modified = true; } if (modified) { for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { try { r.callback.onDataConnectionStateChanged(state, networkType); Loading @@ -371,17 +386,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } } broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, apnTypes, interfaceName); apnType, interfaceName); } public void notifyDataConnectionFailed(String reason) { public void notifyDataConnectionFailed(String reason, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; } /* * This is commented out because there is on onDataConnectionFailed callback * on PhoneStateListener. There should be * This is commented out because there is no onDataConnectionFailed callback * in PhoneStateListener. There should be. synchronized (mRecords) { mDataConnectionFailedReason = reason; final int N = mRecords.size(); Loading @@ -393,7 +409,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } */ broadcastDataConnectionFailed(reason); broadcastDataConnectionFailed(reason, apnType); } public void notifyCellLocation(Bundle cellLocation) { Loading @@ -402,8 +418,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } synchronized (mRecords) { mCellLocation = cellLocation; for (int i = mRecords.size() - 1; i >= 0; i--) { Record r = mRecords.get(i); for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { sendCellLocation(r, cellLocation); } Loading Loading @@ -463,8 +478,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName); pw.println(" mCellLocation=" + mCellLocation); pw.println("registrations: count=" + recordCount); for (int i = 0; i < recordCount; i++) { Record r = mRecords.get(i); for (Record r : mRecords) { pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events)); } } Loading Loading @@ -535,7 +549,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible, String reason, String apn, String[] apnTypes, String interfaceName) { String reason, String apn, String apnType, String interfaceName) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. Loading @@ -549,22 +563,16 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason); } intent.putExtra(Phone.DATA_APN_KEY, apn); String types = new String(""); if (apnTypes.length > 0) { types = apnTypes[0]; for (int i = 1; i < apnTypes.length; i++) { types = types+","+apnTypes[i]; } } intent.putExtra(Phone.DATA_APN_TYPES_KEY, types); intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName); mContext.sendStickyBroadcast(intent); } private void broadcastDataConnectionFailed(String reason) { private void broadcastDataConnectionFailed(String reason, String apnType) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.FAILURE_REASON_KEY, reason); intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); mContext.sendStickyBroadcast(intent); } Loading
telephony/java/android/telephony/PhoneStateListener.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.telephony.CellLocation; import android.util.Log; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.Phone; /** * A listener class for monitoring changes in specific telephony states Loading Loading @@ -284,7 +285,7 @@ public class PhoneStateListener { } public void onDataConnectionStateChanged(int state, int networkType) { Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType, null). Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType). sendToTarget(); } Loading