diff options
| author | Robert Greenwalt <robdroid@android.com> | 2010-06-09 17:11:05 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-06-09 17:11:05 -0700 |
| commit | 9396f6e0698541f6c9b71209ce9ece14cc2414a4 (patch) | |
| tree | 723c96047cd0ba466932873fd3c69796d3bf646f | |
| parent | e4031a3780ad3560d540e87e543a316b0b50a945 (diff) | |
| parent | 02648a4b8422733ed401f07edf8e426318bb2f8d (diff) | |
| download | frameworks_base-9396f6e0698541f6c9b71209ce9ece14cc2414a4.zip frameworks_base-9396f6e0698541f6c9b71209ce9ece14cc2414a4.tar.gz frameworks_base-9396f6e0698541f6c9b71209ce9ece14cc2414a4.tar.bz2 | |
Merge "Clean up APN notifications."
20 files changed, 370 insertions, 416 deletions
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 214510d..ce6d613 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -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; @@ -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; /** @@ -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", @@ -103,38 +89,8 @@ 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 - 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; + mContext.registerReceiver(mStateReceiver, filter); + mMobileDataState = Phone.DataState.DISCONNECTED; } private class MobileDataStateReceiver extends BroadcastReceiver { @@ -142,50 +98,29 @@ public class MobileDataStateTracker extends NetworkStateTracker { 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); } @@ -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(); @@ -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; } /** @@ -416,47 +322,6 @@ public class MobileDataStateTracker extends NetworkStateTracker { } /** - * 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. * @param hostAddress the IP address of the host to which the route is desired, diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java index 1fb0144..2992646 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -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(); @@ -365,34 +366,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. * @param hostAddress the IP address of the host to which the route is desired diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 81b8d40..1ec8d0a 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -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; @@ -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; } } diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java index 664dfa5..8fc4d57 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/java/com/android/server/TelephonyRegistry.java @@ -88,7 +88,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private String mDataConnectionApn = ""; - private String[] mDataConnectionApnTypes = null; + private ArrayList<String> mConnectedApns; private String mDataConnectionInterfaceName = ""; @@ -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, @@ -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); @@ -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); } @@ -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); } @@ -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); @@ -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); @@ -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); @@ -348,40 +343,61 @@ 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) { - mDataConnectionState = state; + 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; - mDataConnectionNetworkType = networkType; - for (int i = mRecords.size() - 1; i >= 0; i--) { - Record r = mRecords.get(i); - if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { - try { - r.callback.onDataConnectionStateChanged(state, networkType); - } catch (RemoteException ex) { - remove(r.binder); + if (mDataConnectionNetworkType != networkType) { + mDataConnectionNetworkType = networkType; + modified = true; + } + if (modified) { + for (Record r : mRecords) { + if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { + try { + r.callback.onDataConnectionStateChanged(state, networkType); + } catch (RemoteException ex) { + remove(r.binder); + } } } } } 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(); @@ -393,7 +409,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } */ - broadcastDataConnectionFailed(reason); + broadcastDataConnectionFailed(reason, apnType); } public void notifyCellLocation(Bundle cellLocation) { @@ -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); } @@ -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)); } } @@ -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. @@ -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); } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 830af47..38f44d8 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -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 @@ -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(); } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 3b9e6cc..e71fe2e 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -188,7 +188,10 @@ public abstract class DataConnectionTracker extends Handler { /** CID of active data connection */ protected int cidActive; - /** + /** indication of our availability (preconditions to trysetupData are met) **/ + protected boolean mAvailability = false; + + /** * Default constructor */ protected DataConnectionTracker(PhoneBase phone) { @@ -421,7 +424,84 @@ public abstract class DataConnectionTracker extends Handler { protected abstract void setState(State s); - protected synchronized boolean isEnabled(int id) { + // tell all active apns of the current condition + protected void notifyDataConnection(String reason) { + for (int id = 0; id < APN_NUM_TYPES; id++) { + if (dataEnabled[id]) { + phone.notifyDataConnection(reason, apnIdToType(id)); + } + } + notifyDataAvailability(reason); + } + + // a new APN has gone active and needs to send events to catch up with the current condition + private void notifyApnIdUpToCurrent(String reason, int apnId) { + switch (state) { + case IDLE: + case INITING: + break; + case CONNECTING: + case SCANNING: + phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); + break; + case CONNECTED: + case DISCONNECTING: + phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING); + phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED); + break; + } + } + + // since we normally don't send info to a disconnected APN, we need to do this specially + private void notifyApnIdDisconnected(String reason, int apnId) { + phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED); + } + + // disabled apn's still need avail/unavail notificiations - send them out + protected void notifyOffApnsOfAvailability(String reason, boolean availability) { + if (mAvailability == availability) return; + mAvailability = availability; + for (int id = 0; id < APN_NUM_TYPES; id++) { + if (!isApnIdEnabled(id)) { + notifyApnIdDisconnected(reason, id); + } + } + } + + // we had an availability change - tell the listeners + protected void notifyDataAvailability(String reason) { + // note that we either just turned all off because we lost availability + // or all were off and could now go on, so only have off apns to worry about + notifyOffApnsOfAvailability(reason, isDataPossible()); + } + + /** + * The only circumstances under which we report that data connectivity is not + * possible are + * <ul> + * <li>Data is disallowed (roaming, power state, voice call, etc).</li> + * <li>The current data state is {@code DISCONNECTED} for a reason other than + * having explicitly disabled connectivity. In other words, data is not available + * because the phone is out of coverage or some like reason.</li> + * </ul> + * @return {@code true} if data connectivity is possible, {@code false} otherwise. + */ + protected boolean isDataPossible() { + boolean possible = (isDataAllowed() && + !(getDataEnabled() && (state == State.FAILED || state == State.IDLE))); + if (!possible && DBG && isDataAllowed()) { + log("Data not possible. No coverage: dataState = " + state); + } + return possible; + } + + protected abstract boolean isDataAllowed(); + + public boolean isApnTypeEnabled(String apnType) { + return isApnIdEnabled(apnTypeToId(apnType)); + } + + protected synchronized boolean isApnIdEnabled(int id) { if (id != APN_INVALID_ID) { return dataEnabled[id]; } @@ -444,22 +524,21 @@ public abstract class DataConnectionTracker extends Handler { return Phone.APN_REQUEST_FAILED; } - if (DBG) Log.d(LOG_TAG, "enableApnType("+type+"), isApnTypeActive = " - + isApnTypeActive(type) + " and state = " + state); + if (DBG) { + Log.d(LOG_TAG, "enableApnType(" + type + "), isApnTypeActive = " + + isApnTypeActive(type) + ", isApnIdEnabled =" + isApnIdEnabled(id) + + " and state = " + state); + } if (!isApnTypeAvailable(type)) { if (DBG) Log.d(LOG_TAG, "type not available"); return Phone.APN_TYPE_NOT_AVAILABLE; } - // just because it's active doesn't mean we had it explicitly requested before - // (a broad default may handle many types). make sure we mark it enabled - // so if the default is disabled we keep the connection for others - setEnabled(id, true); - - if (isApnTypeActive(type)) { - if (state == State.INITING) return Phone.APN_REQUEST_STARTED; - else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE; + if (isApnIdEnabled(id)) { + return Phone.APN_ALREADY_ACTIVE; + } else { + setEnabled(id, true); } return Phone.APN_REQUEST_STARTED; } @@ -478,7 +557,7 @@ public abstract class DataConnectionTracker extends Handler { if (id == APN_INVALID_ID) { return Phone.APN_REQUEST_FAILED; } - if (isEnabled(id)) { + if (isApnIdEnabled(id)) { setEnabled(id, false); if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { if (dataEnabled[APN_DEFAULT_ID]) { @@ -495,9 +574,10 @@ public abstract class DataConnectionTracker extends Handler { } private void setEnabled(int id, boolean enable) { - if (DBG) Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = " + - dataEnabled[id] + " and enabledCount = " + enabledCount); - + if (DBG) { + Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = " + + dataEnabled[id] + " and enabledCount = " + enabledCount); + } Message msg = obtainMessage(EVENT_ENABLE_NEW_APN); msg.arg1 = id; msg.arg2 = (enable ? ENABLED : DISABLED); @@ -507,9 +587,8 @@ public abstract class DataConnectionTracker extends Handler { protected synchronized void onEnableApn(int apnId, int enabled) { if (DBG) { Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled); - Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] + - ", enabledCount = " + enabledCount + - ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId))); + Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] + ", enabledCount = " + + enabledCount + ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId))); } if (enabled == ENABLED) { if (!dataEnabled[apnId]) { @@ -520,6 +599,8 @@ public abstract class DataConnectionTracker extends Handler { if (!isApnTypeActive(type)) { mRequestedApnType = type; onEnableNewApn(); + } else { + notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnId); } } else { // disable @@ -528,8 +609,17 @@ public abstract class DataConnectionTracker extends Handler { enabledCount--; if (enabledCount == 0) { onCleanUpConnection(true, Phone.REASON_DATA_DISABLED); - } else if (dataEnabled[APN_DEFAULT_ID] == true && - !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { + } + + // send the disconnect msg manually, since the normal route wont send + // it (it's not enabled) + notifyApnIdDisconnected(Phone.REASON_DATA_DISABLED, apnId); + if (dataEnabled[APN_DEFAULT_ID] == true + && !isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { + // TODO - this is an ugly way to restore the default conn - should be done + // by a real contention manager and policy that disconnects the lower pri + // stuff as enable requests come in and pops them back on as we disable back + // down to the lower pri stuff mRequestedApnType = Phone.APN_TYPE_DEFAULT; onEnableNewApn(); } @@ -574,7 +664,7 @@ public abstract class DataConnectionTracker extends Handler { onTrySetupData(Phone.REASON_DATA_ENABLED); } else { onCleanUpConnection(true, Phone.REASON_DATA_DISABLED); - } + } } } diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java index 4da4b6a..0646101 100644 --- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java +++ b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java @@ -92,14 +92,27 @@ public class DefaultPhoneNotifier implements PhoneNotifier { } } - public void notifyDataConnection(Phone sender, String reason) { + public void notifyDataConnection(Phone sender, String reason, String apnType) { + doNotifyDataConnection(sender, reason, apnType, sender.getDataConnectionState(apnType)); + } + + public void notifyDataConnection(Phone sender, String reason, String apnType, + Phone.DataState state) { + doNotifyDataConnection(sender, reason, apnType, state); + } + + private void doNotifyDataConnection(Phone sender, String reason, String apnType, + Phone.DataState state) { + // TODO + // use apnType as the key to which connection we're talking about. + // pass apnType back up to fetch particular for this one. TelephonyManager telephony = TelephonyManager.getDefault(); try { mRegistry.notifyDataConnection( - convertDataState(sender.getDataConnectionState()), + convertDataState(state), sender.isDataConnectivityPossible(), reason, sender.getActiveApn(), - sender.getActiveApnTypes(), + apnType, sender.getInterfaceName(null), ((telephony!=null) ? telephony.getNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN)); @@ -108,9 +121,9 @@ public class DefaultPhoneNotifier implements PhoneNotifier { } } - public void notifyDataConnectionFailed(Phone sender, String reason) { + public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { try { - mRegistry.notifyDataConnectionFailed(reason); + mRegistry.notifyDataConnectionFailed(reason, apnType); } catch (RemoteException ex) { // system process is dead } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5bf8e58..79c2b40 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -32,7 +32,7 @@ interface ITelephonyRegistry { void notifyCallForwardingChanged(boolean cfi); void notifyDataActivity(int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String reason, String apn, in String[] apnTypes, String interfaceName, int networkType); - void notifyDataConnectionFailed(String reason); + String reason, String apn, String apnType, String interfaceName, int networkType); + void notifyDataConnectionFailed(String reason, String apnType); void notifyCellLocation(in Bundle cellLocation); } diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index 8ff38d9..7029031 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -99,7 +99,7 @@ public interface Phone { static final String PHONE_NAME_KEY = "phoneName"; static final String FAILURE_REASON_KEY = "reason"; static final String STATE_CHANGE_REASON_KEY = "reason"; - static final String DATA_APN_TYPES_KEY = "apnType"; + static final String DATA_APN_TYPE_KEY = "apnType"; static final String DATA_APN_KEY = "apn"; static final String DATA_IFACE_NAME_KEY = "iface"; @@ -241,11 +241,19 @@ public interface Phone { CellLocation getCellLocation(); /** + * Get the current for the default apn DataState. No change notification + * exists at this interface -- use + * {@link android.telephony.PhoneStateListener} instead. + */ + DataState getDataConnectionState(); + + /** * Get the current DataState. No change notification exists at this * interface -- use * {@link android.telephony.PhoneStateListener} instead. + * @param apnType specify for which apn to get connection state info. */ - DataState getDataConnectionState(); + DataState getDataConnectionState(String apnType); /** * Get the current DataActivityState. No change notification exists at this diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index fbb658a..cf80691 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -737,8 +737,13 @@ public abstract class PhoneBase extends Handler implements Phone { mNotifier.notifyMessageWaitingChanged(this); } - public void notifyDataConnection(String reason) { - mNotifier.notifyDataConnection(this, reason); + public void notifyDataConnection(String reason, String apnType, + Phone.DataState state) { + mNotifier.notifyDataConnection(this, reason, apnType, state); + } + + public void notifyDataConnection(String reason, String apnType) { + mNotifier.notifyDataConnection(this, reason, apnType); } public abstract String getPhoneName(); @@ -962,6 +967,10 @@ public abstract class PhoneBase extends Handler implements Phone { return mDataConnection.disableApnType(type); } + public boolean isDataConnectivityPossible() { + return ((mDataConnection != null) && (mDataConnection.isDataPossible())); + } + /** * simulateDataConnection * @@ -990,7 +999,7 @@ public abstract class PhoneBase extends Handler implements Phone { } mDataConnection.setState(dcState); - notifyDataConnection(null); + notifyDataConnection(null, Phone.APN_TYPE_DEFAULT); } /** @@ -1036,4 +1045,8 @@ public abstract class PhoneBase extends Handler implements Phone { Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + "called, CDMAPhone inactive."); } + + public DataState getDataConnectionState() { + return getDataConnectionState(APN_TYPE_DEFAULT); + } } diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java index e96eeae..691271f 100644 --- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java +++ b/telephony/java/com/android/internal/telephony/PhoneNotifier.java @@ -33,9 +33,12 @@ public interface PhoneNotifier { public void notifyCallForwardingChanged(Phone sender); - public void notifyDataConnection(Phone sender, String reason); + public void notifyDataConnection(Phone sender, String reason, String apnType); - public void notifyDataConnectionFailed(Phone sender, String reason); + public void notifyDataConnection(Phone sender, String reason, String apnType, + Phone.DataState state); + + public void notifyDataConnectionFailed(Phone sender, String reason, String apnType); public void notifyDataActivity(Phone sender); diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index 8c2a661..fb2a938 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -172,7 +172,11 @@ public class PhoneProxy extends Handler implements Phone { } public DataState getDataConnectionState() { - return mActivePhone.getDataConnectionState(); + return mActivePhone.getDataConnectionState(Phone.APN_TYPE_DEFAULT); + } + + public DataState getDataConnectionState(String apnType) { + return mActivePhone.getDataConnectionState(apnType); } public DataActivityState getDataActivityState() { diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 8934037..44c65f7 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -504,14 +504,6 @@ public class CDMAPhone extends PhoneBase { return false; } - public boolean isDataConnectivityPossible() { - boolean noData = mDataConnection.getDataEnabled() && - getDataConnectionState() == DataState.DISCONNECTED; - return !noData && getIccCard().getState() == IccCard.State.READY && - getServiceState().getState() == ServiceState.STATE_IN_SERVICE && - (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming()); - } - /** * Removes the given MMI from the pending list and notifies registrants that * it is complete. @@ -602,7 +594,7 @@ public class CDMAPhone extends PhoneBase { } } - public DataState getDataConnectionState() { + public DataState getDataConnectionState(String apnType) { DataState ret = DataState.DISCONNECTED; if (mSST == null) { @@ -614,6 +606,8 @@ public class CDMAPhone extends PhoneBase { // If we're out of service, open TCP sockets may still work // but no data will flow ret = DataState.DISCONNECTED; + } else if (mDataConnection.isApnTypeEnabled(apnType) == false) { + ret = DataState.DISCONNECTED; } else { switch (mDataConnection.getState()) { case FAILED: diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 9f2a44b..bd103d4 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -305,9 +305,40 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { return true; } - private boolean isDataAllowed() { - boolean roaming = phone.getServiceState().getRoaming(); - return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()) && mMasterDataEnabled; + protected boolean isDataAllowed() { + int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState(); + boolean roaming = (phone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()); + boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState(); + + boolean allowed = (psState == ServiceState.STATE_IN_SERVICE && + (phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY || + mCdmaPhone.mRuimRecords.getRecordsLoaded()) && + (mCdmaPhone.mSST.isConcurrentVoiceAndData() || + phone.getState() == Phone.State.IDLE) && + !roaming && + mMasterDataEnabled && + desiredPowerState && + !mPendingRestartRadio && + !mCdmaPhone.needsOtaServiceProvisioning()); + if (!allowed && DBG) { + String reason = ""; + if (psState != ServiceState.STATE_IN_SERVICE) reason += " - psState= " + psState; + if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY && + !mCdmaPhone.mRuimRecords.getRecordsLoaded()) { + reason += " - radioState= " + phone.mCM.getRadioState() + " - RUIM not loaded"; + } + if (phone.getState() != Phone.State.IDLE && + mCdmaPhone.mSST.isConcurrentVoiceAndData()) { + reason += " - concurrentVoiceAndData not allowed and state= " + phone.getState(); + } + if (roaming) reason += " - Roaming"; + if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false"; + if (!desiredPowerState) reason += " - desiredPowerState= false"; + if (mPendingRestartRadio) reason += " - mPendingRestartRadio= true"; + if (mCdmaPhone.needsOtaServiceProvisioning()) reason += " - needs Provisioning"; + log("Data not allowed due to" + reason); + } + return allowed; } private boolean trySetupData(String reason) { @@ -317,7 +348,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { // Assume data is connected on the simulator // FIXME this can be improved setState(State.CONNECTED); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); + notifyOffApnsOfAvailability(reason, true); Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected"); return true; @@ -327,36 +359,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { boolean roaming = phone.getServiceState().getRoaming(); boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState(); - if ((state == State.IDLE || state == State.SCANNING) - && (psState == ServiceState.STATE_IN_SERVICE) - && ((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) || - mCdmaPhone.mRuimRecords.getRecordsLoaded()) - && (mCdmaPhone.mSST.isConcurrentVoiceAndData() || - phone.getState() == Phone.State.IDLE ) - && isDataAllowed() - && desiredPowerState - && !mPendingRestartRadio - && !mCdmaPhone.needsOtaServiceProvisioning()) { - - return setupData(reason); - + if ((state == State.IDLE || state == State.SCANNING) && + isDataAllowed() && getAnyDataEnabled()) { + boolean retValue = setupData(reason); + notifyOffApnsOfAvailability(reason, retValue); + return retValue; } else { - if (DBG) { - log("trySetupData: Not ready for data: " + - " dataState=" + state + - " PS state=" + psState + - " radio state=" + phone.mCM.getRadioState() + - " ruim=" + mCdmaPhone.mRuimRecords.getRecordsLoaded() + - " concurrentVoice&Data=" + mCdmaPhone.mSST.isConcurrentVoiceAndData() + - " phoneState=" + phone.getState() + - " dataEnabled=" + getAnyDataEnabled() + - " roaming=" + roaming + - " dataOnRoamingEnable=" + getDataOnRoamingEnabled() + - " desiredPowerState=" + desiredPowerState + - " PendingRestartRadio=" + mPendingRestartRadio + - " MasterDataEnabled=" + mMasterDataEnabled + - " needsOtaServiceProvisioning=" + mCdmaPhone.needsOtaServiceProvisioning()); - } + notifyOffApnsOfAvailability(reason, false); return false; } } @@ -382,6 +391,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } setState(State.DISCONNECTING); + notifyDataAvailability(reason); boolean notificationDeferred = false; for (DataConnection conn : dataConnectionList) { @@ -440,13 +450,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { conn.connect(msg, mActiveApn); setState(State.INITING); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); return true; } private void notifyDefaultData(String reason) { setState(State.CONNECTED); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); startNetStatPoll(); mRetryMgr.resetRetryCount(); } @@ -622,12 +632,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { private void notifyNoData(FailCause lastFailCauseCode) { setState(State.FAILED); + notifyDataAvailability(null); } private void gotoIdleAndNotifyDataConnection(String reason) { if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason); setState(State.IDLE); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); mActiveApn = null; } @@ -687,11 +698,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { // Assume data is connected on the simulator // FIXME this can be improved setState(State.CONNECTED); - phone.notifyDataConnection(null); + notifyDataConnection(null); Log.i(LOG_TAG, "We're on the simulator; assuming data is connected"); } + notifyDataAvailability(null); + if (state != State.IDLE) { cleanUpConnection(true, null); } @@ -762,7 +775,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { onRestartRadio(); } - phone.notifyDataConnection(reason); + notifyDataConnection(reason); mActiveApn = null; if (retryAfterDisconnected(reason)) { trySetupData(reason); @@ -789,7 +802,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { protected void onVoiceCallStarted() { if (state == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) { stopNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); + notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); + notifyDataAvailability(Phone.REASON_VOICE_CALL_STARTED); } } @@ -800,11 +814,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { if (state == State.CONNECTED) { if (!mCdmaPhone.mSST.isConcurrentVoiceAndData()) { startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); + notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); } else { // clean slate after call end. resetPollStats(); } + notifyDataAvailability(Phone.REASON_VOICE_CALL_ENDED); } else { mRetryMgr.resetRetryCount(); // in case data setup was attempted when we were on a voice call @@ -838,7 +853,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { private void onCdmaDataDetached() { if (state == State.CONNECTED) { startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); + notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); } else { if (state == State.FAILED) { cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 2cad6cc..5d4dc58 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -1119,7 +1119,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { } if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) { - phone.notifyDataConnection(null); + phone.notifyDataConnection(null, null); } if (hasRoamingOn) { diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index c7b1e5c..04b75bc 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -291,7 +291,7 @@ public class GSMPhone extends PhoneBase { return mPendingMMIs; } - public DataState getDataConnectionState() { + public DataState getDataConnectionState(String apnType) { DataState ret = DataState.DISCONNECTED; if (mSST == null) { @@ -304,6 +304,8 @@ public class GSMPhone extends PhoneBase { // If we're out of service, open TCP sockets may still work // but no data will flow ret = DataState.DISCONNECTED; + } else if (mDataConnection.isApnTypeEnabled(apnType) == false) { + ret = DataState.DISCONNECTED; } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */ switch (mDataConnection.getState()) { case FAILED: @@ -405,8 +407,8 @@ public class GSMPhone extends PhoneBase { } /*package*/ void - notifyDataConnectionFailed(String reason) { - mNotifier.notifyDataConnectionFailed(this, reason); + notifyDataConnectionFailed(String reason, String apnType) { + mNotifier.notifyDataConnectionFailed(this, reason, apnType); } /*package*/ void @@ -1093,27 +1095,6 @@ public class GSMPhone extends PhoneBase { } /** - * The only circumstances under which we report that data connectivity is not - * possible are - * <ul> - * <li>Data roaming is disallowed and we are roaming.</li> - * <li>The current data state is {@code DISCONNECTED} for a reason other than - * having explicitly disabled connectivity. In other words, data is not available - * because the phone is out of coverage or some like reason.</li> - * </ul> - * @return {@code true} if data connectivity is possible, {@code false} otherwise. - */ - public boolean isDataConnectivityPossible() { - // TODO: Currently checks if any GPRS connection is active. Should it only - // check for "default"? - boolean noData = mDataConnection.getDataEnabled() && - getDataConnectionState() == DataState.DISCONNECTED; - return !noData && getIccCard().getState() == SimCard.State.READY && - getServiceState().getState() == ServiceState.STATE_IN_SERVICE && - (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming()); - } - - /** * Removes the given MMI from the pending list and notifies * registrants that it is complete. * @param mmi MMI that is done diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index f6d4491..6826fa8 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -388,12 +388,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { return pdps; } - private boolean isDataAllowed() { - boolean roaming = phone.getServiceState().getRoaming(); - return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()) && - mMasterDataEnabled; - } - //****** Called from ServiceStateTracker /** * Invoked when ServiceStateTracker observes a transition from GPRS @@ -405,13 +399,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { * when GPRS detaches, but we should stop the network polling. */ stopNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_GPRS_DETACHED); + notifyDataConnection(Phone.REASON_GPRS_DETACHED); } private void onGprsAttached() { if (state == State.CONNECTED) { startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED); + notifyDataConnection(Phone.REASON_GPRS_ATTACHED); } else { if (state == State.FAILED) { cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED); @@ -421,6 +415,35 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } } + protected boolean isDataAllowed() { + int gprsState = mGsmPhone.mSST.getCurrentGprsState(); + boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState(); + + boolean allowed = ((gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach) && + mGsmPhone.mSIMRecords.getRecordsLoaded() && + phone.getState() == Phone.State.IDLE && + mMasterDataEnabled && + (!phone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) && + !mIsPsRestricted && + desiredPowerState); + if (!allowed && DBG) { + String reason = ""; + if (gprsState != ServiceState.STATE_IN_SERVICE) reason += " - gprs= " + gprsState; + if (!mGsmPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded"; + if (phone.getState() != Phone.State.IDLE) { + reason += " - PhoneState= " + phone.getState(); + } + if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false"; + if (phone.getServiceState().getRoaming() && getDataOnRoamingEnabled()) { + reason += " - Roaming"; + } + if (mIsPsRestricted) reason += " - mIsPsRestricted= true"; + if (!desiredPowerState) reason += " - desiredPowerState= false"; + log("Data not allowed due to" + reason); + } + return allowed; + } + private boolean trySetupData(String reason) { if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason)); @@ -430,7 +453,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // Assume data is connected on the simulator // FIXME this can be improved setState(State.CONNECTED); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected"); return true; @@ -439,19 +462,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { int gprsState = mGsmPhone.mSST.getCurrentGprsState(); boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState(); - if ((state == State.IDLE || state == State.SCANNING) - && (gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach) - && mGsmPhone.mSIMRecords.getRecordsLoaded() - && phone.getState() == Phone.State.IDLE - && isDataAllowed() - && !mIsPsRestricted - && desiredPowerState ) { + if (((state == State.IDLE) || (state == State.SCANNING)) && + isDataAllowed() && getAnyDataEnabled()) { if (state == State.IDLE) { waitingApns = buildWaitingApns(); if (waitingApns.isEmpty()) { if (DBG) log("No APN found"); notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN); + notifyOffApnsOfAvailability(reason, false); return false; } else { log ("Create from allApns : " + apnListToString(allApns)); @@ -461,22 +480,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (DBG) { log ("Setup waitngApns : " + apnListToString(waitingApns)); } - return setupData(reason); + boolean retValue = setupData(reason); + notifyOffApnsOfAvailability(reason, retValue); + return retValue; } else { - if (DBG) - log("trySetupData: Not ready for data: " + - " dataState=" + state + - " gprsState=" + gprsState + - " sim=" + mGsmPhone.mSIMRecords.getRecordsLoaded() + - " UMTS=" + mGsmPhone.mSST.isConcurrentVoiceAndData() + - " phoneState=" + phone.getState() + - " isDataAllowed=" + isDataAllowed() + - " dataEnabled=" + getAnyDataEnabled() + - " roaming=" + phone.getServiceState().getRoaming() + - " dataOnRoamingEnable=" + getDataOnRoamingEnabled() + - " ps restricted=" + mIsPsRestricted + - " desiredPowerState=" + desiredPowerState + - " MasterDataEnabled=" + mMasterDataEnabled); + notifyOffApnsOfAvailability(reason, false); return false; } } @@ -595,7 +603,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { pdp.connect(msg, apn); setState(State.INITING); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); return true; } @@ -746,7 +754,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private void notifyDefaultData(String reason) { setState(State.CONNECTED); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); startNetStatPoll(); // reset reconnect timer mRetryMgr.resetRetryCount(); @@ -756,7 +764,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private void gotoIdleAndNotifyDataConnection(String reason) { if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason); setState(State.IDLE); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); mActiveApn = null; } @@ -998,7 +1006,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (!mRetryMgr.isRetryNeeded()) { if (!mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) { // if no more retries on a secondary APN attempt, tell the world and revert. - phone.notifyDataConnection(Phone.REASON_APN_FAILED); + notifyDataConnection(Phone.REASON_APN_FAILED); onEnableApn(apnTypeToId(mRequestedApnType), DISABLED); return; } @@ -1091,7 +1099,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // Assume data is connected on the simulator // FIXME this can be improved setState(State.CONNECTED); - phone.notifyDataConnection(null); + notifyDataConnection(null); Log.i(LOG_TAG, "We're on the simulator; assuming data is connected"); } @@ -1158,7 +1166,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (cause.isPermanentFail()) { notifyNoData(cause); if (!mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) { - phone.notifyDataConnection(Phone.REASON_APN_FAILED); + notifyDataConnection(Phone.REASON_APN_FAILED); onEnableApn(apnTypeToId(mRequestedApnType), DISABLED); } return; @@ -1188,7 +1196,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { reason = (String) ar.userObj; } setState(State.IDLE); - phone.notifyDataConnection(reason); + notifyDataConnection(reason); mActiveApn = null; if (retryAfterDisconnected(reason)) { trySetupData(reason); @@ -1219,7 +1227,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { protected void onVoiceCallStarted() { if (state == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) { stopNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); + notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); } } @@ -1227,7 +1235,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (state == State.CONNECTED) { if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) { startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); + notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); } else { // clean slate after call end. resetPollStats(); diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index d539f6f..c2f6330 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -1011,7 +1011,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } if (hasNetworkTypeChanged) { - phone.notifyDataConnection(null); + // TODO - do we really want this? + phone.notifyDataConnection(null, null); } if (hasRoamingOn) { diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java index 427795b..8cb05cc 100644 --- a/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java +++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java @@ -16,6 +16,8 @@ package com.android.internal.telephony; +import com.android.internal.telephony.Phone; + /** * Stub class used for unit tests */ @@ -32,7 +34,7 @@ public class TestPhoneNotifier implements PhoneNotifier { public void notifyCellLocation(Phone sender) { } - + public void notifySignalStrength(Phone sender) { } @@ -42,10 +44,14 @@ public class TestPhoneNotifier implements PhoneNotifier { public void notifyCallForwardingChanged(Phone sender) { } - public void notifyDataConnection(Phone sender, String reason) { + public void notifyDataConnection(Phone sender, String reason, String apnType) { + } + + public void notifyDataConnection(Phone sender, String reason, String apnType, + Phone.DataState state) { } - public void notifyDataConnectionFailed(Phone sender, String reason) { + public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) { } public void notifyDataActivity(Phone sender) { diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 2c8be31..364cc16 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -2051,26 +2051,6 @@ public class WifiStateTracker extends NetworkStateTracker { return mWM.setWifiEnabled(turnOn); } - /** - * {@inheritDoc} - * There are currently no Wi-Fi-specific features supported. - * @param feature the name of the feature - * @return {@code -1} indicating failure, always - */ - public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) { - return -1; - } - - /** - * {@inheritDoc} - * There are currently no Wi-Fi-specific features supported. - * @param feature the name of the feature - * @return {@code -1} indicating failure, always - */ - public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) { - return -1; - } - @Override public void interpretScanResultsAvailable() { |
