diff options
| author | Robert Greenwalt <robdroid@android.com> | 2010-05-18 10:52:51 -0700 |
|---|---|---|
| committer | Robert Greenwalt <robdroid@android.com> | 2010-06-09 16:52:01 -0700 |
| commit | 02648a4b8422733ed401f07edf8e426318bb2f8d (patch) | |
| tree | 870635094119f5b91423b69e67ee06601fd75b0f /telephony/java | |
| parent | 1d46191d88ee9262ea05b868d2db5b44ad85fa43 (diff) | |
| download | frameworks_base-02648a4b8422733ed401f07edf8e426318bb2f8d.zip frameworks_base-02648a4b8422733ed401f07edf8e426318bb2f8d.tar.gz frameworks_base-02648a4b8422733ed401f07edf8e426318bb2f8d.tar.bz2 | |
Clean up APN notifications.
Add APNType info to notifications so you can tell what's happening. Now, even if a new APN
shares a connection with an already-connected-to- apn type, the new type will get all
the connecting and connected messages on connect and disconnecting/disconnected on disconnect
even though the shared connection remains connected.
Cleaning out the hacks MobileDataStateTracker needed to deal with the old situation.
bug:2226092
Change-Id: Iddd7421d6b91cda7c8405f9c3d5404ac04ef8e42
Diffstat (limited to 'telephony/java')
14 files changed, 285 insertions, 154 deletions
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) { |
