diff options
author | Steve Kondik <shade@chemlab.org> | 2012-03-29 00:09:58 -0700 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2012-03-29 00:09:58 -0700 |
commit | d6590d4c89a5cf2c174e83561b09125732c8bcab (patch) | |
tree | 629cf90df08fbc849cd448c27977c1aff2b18fc5 /telephony | |
parent | 1e5dab5b7653758a198a3314c445cc514c4a52a7 (diff) | |
parent | df331873c8576e0ae34ae1ee3cc258beed373535 (diff) | |
download | frameworks_base-d6590d4c89a5cf2c174e83561b09125732c8bcab.zip frameworks_base-d6590d4c89a5cf2c174e83561b09125732c8bcab.tar.gz frameworks_base-d6590d4c89a5cf2c174e83561b09125732c8bcab.tar.bz2 |
Merge branch 'ics-mr1-release' of https://android.googlesource.com/platform/frameworks/base into aosp
Conflicts:
core/res/res/values-de/strings.xml
core/res/res/values-el/strings.xml
core/res/res/values-nl/strings.xml
core/res/res/values-pt/strings.xml
core/res/res/values-ru/strings.xml
core/res/res/values-tr/strings.xml
core/res/res/values-zh-rCN/strings.xml
core/res/res/values/config.xml
data/fonts/Roboto-Bold.ttf
data/fonts/Roboto-BoldItalic.ttf
data/fonts/Roboto-Italic.ttf
data/fonts/Roboto-Regular.ttf
packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
Change-Id: I376757e52555fe45860f404da5fd2293ea45ddce
Diffstat (limited to 'telephony')
14 files changed, 505 insertions, 130 deletions
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index a88825b..1049669 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -47,6 +47,9 @@ public class SignalStrength implements Parcelable { "none", "poor", "moderate", "good", "great" }; + /** @hide */ + public static final int INVALID_SNR = 0x7FFFFFFF; + private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 private int mCdmaDbm; // This value is the RSSI value @@ -96,7 +99,7 @@ public class SignalStrength implements Parcelable { mLteSignalStrength = -1; mLteRsrp = -1; mLteRsrq = -1; - mLteRssnr = -1; + mLteRssnr = INVALID_SNR; mLteCqi = -1; isGsm = true; } @@ -136,7 +139,8 @@ public class SignalStrength implements Parcelable { int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm) { this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, - evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, gsm); + evdoDbm, evdoEcio, evdoSnr, -1, -1, + -1, INVALID_SNR, -1, gsm); } /** @@ -289,10 +293,11 @@ public class SignalStrength implements Parcelable { int level; if (isGsm) { + // TODO Need solve the discrepancy of invalid values between + // RIL_LTE_SignalStrength and here. if ((mLteSignalStrength == -1) && (mLteRsrp == -1) && (mLteRsrq == -1) - && (mLteRssnr == -1) && (mLteCqi == -1)) { level = getGsmLevel(); } else { @@ -327,7 +332,6 @@ public class SignalStrength implements Parcelable { if ((mLteSignalStrength == -1) && (mLteRsrp == -1) && (mLteRsrq == -1) - && (mLteRssnr == -1) && (mLteCqi == -1)) { asuLevel = getGsmAsuLevel(); } else { @@ -363,7 +367,6 @@ public class SignalStrength implements Parcelable { if ((mLteSignalStrength == -1) && (mLteRsrp == -1) && (mLteRsrq == -1) - && (mLteRssnr == -1) && (mLteCqi == -1)) { dBm = getGsmDbm(); } else { @@ -566,16 +569,31 @@ public class SignalStrength implements Parcelable { */ public int getLteLevel() { int levelLteRsrp = 0; + int levelLteRssnr = 0; if (mLteRsrp == -1) levelLteRsrp = 0; - else if (mLteRsrp >= -85) levelLteRsrp = SIGNAL_STRENGTH_GREAT; - else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GOOD; - else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_MODERATE; - else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_POOR; - else levelLteRsrp = 0; - - if (DBG) log("Lte level: "+levelLteRsrp); - return levelLteRsrp; + else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GREAT; + else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_GOOD; + else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_MODERATE; + else levelLteRsrp = SIGNAL_STRENGTH_POOR; + + if (mLteRssnr == INVALID_SNR) levelLteRssnr = 0; + else if (mLteRssnr >= 45) levelLteRssnr = SIGNAL_STRENGTH_GREAT; + else if (mLteRssnr >= 10) levelLteRssnr = SIGNAL_STRENGTH_GOOD; + else if (mLteRssnr >= -30) levelLteRssnr = SIGNAL_STRENGTH_MODERATE; + else levelLteRssnr = SIGNAL_STRENGTH_POOR; + + int level; + if (mLteRsrp == -1) + level = levelLteRssnr; + else if (mLteRssnr == INVALID_SNR) + level = levelLteRsrp; + else + level = (levelLteRssnr < levelLteRsrp) ? levelLteRssnr : levelLteRsrp; + + if (DBG) log("Lte rsrp level: "+levelLteRsrp + + " snr level: " + levelLteRssnr + " level: " + level); + return level; } /** diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java index 19a396e..0056701 100644 --- a/telephony/java/com/android/internal/telephony/DataConnection.java +++ b/telephony/java/com/android/internal/telephony/DataConnection.java @@ -68,6 +68,8 @@ public abstract class DataConnection extends StateMachine { private List<ApnContext> mApnList = null; PendingIntent mReconnectIntent = null; + private DataConnectionTracker mDataConnectionTracker = null; + /** * Used internally for saving connecting parameters. */ @@ -134,7 +136,8 @@ public abstract class DataConnection extends StateMachine { // specified here UNKNOWN(0x10000), RADIO_NOT_AVAILABLE(0x10001), - UNACCEPTABLE_NETWORK_PARAMETER(0x10002); + UNACCEPTABLE_NETWORK_PARAMETER(0x10002), + CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003); private final int mErrorCode; private static final HashMap<Integer, FailCause> sErrorCodeToFailCauseMap; @@ -201,6 +204,7 @@ public abstract class DataConnection extends StateMachine { protected static final int EVENT_DEACTIVATE_DONE = BASE + 3; protected static final int EVENT_DISCONNECT = BASE + 4; protected static final int EVENT_RIL_CONNECTED = BASE + 5; + protected static final int EVENT_DISCONNECT_ALL = BASE + 6; //***** Tag IDs for EventLog protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100; @@ -233,10 +237,12 @@ public abstract class DataConnection extends StateMachine { //***** Constructor - protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm) { + protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { super(name); if (DBG) log("DataConnection constructor E"); this.phone = phone; + this.mDataConnectionTracker = dct; mId = id; mRetryMgr = rm; this.cid = -1; @@ -315,11 +321,19 @@ public abstract class DataConnection extends StateMachine { * * @param dp is the DisconnectParams. */ - private void notifyDisconnectCompleted(DisconnectParams dp) { + private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { if (VDBG) log("NotifyDisconnectCompleted"); + ApnContext alreadySent = null; + String reason = null; + if (dp.onCompletedMsg != null) { + // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices. Message msg = dp.onCompletedMsg; + if (msg.obj instanceof ApnContext) { + alreadySent = (ApnContext)msg.obj; + } + reason = dp.reason; if (VDBG) { log(String.format("msg=%s msg.obj=%s", msg.toString(), ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>"))); @@ -327,6 +341,17 @@ public abstract class DataConnection extends StateMachine { AsyncResult.forMessage(msg); msg.sendToTarget(); } + if (sendAll) { + for (ApnContext a : mApnList) { + if (a == alreadySent) continue; + if (reason != null) a.setReason(reason); + Message msg = mDataConnectionTracker.obtainMessage( + DataConnectionTracker.EVENT_DISCONNECT_DONE, a); + AsyncResult.forMessage(msg); + msg.sendToTarget(); + } + } + if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); } @@ -720,6 +745,13 @@ public abstract class DataConnection extends StateMachine { deferMessage(msg); break; + case EVENT_DISCONNECT_ALL: + if (DBG) { + log("DcDefaultState deferring msg.what=EVENT_DISCONNECT_ALL" + mRefCount); + } + deferMessage(msg); + break; + case EVENT_RIL_CONNECTED: ar = (AsyncResult)msg.obj; if (ar.exception == null) { @@ -785,7 +817,7 @@ public abstract class DataConnection extends StateMachine { } if (mDisconnectParams != null) { if (VDBG) log("DcInactiveState: enter notifyDisconnectCompleted"); - notifyDisconnectCompleted(mDisconnectParams); + notifyDisconnectCompleted(mDisconnectParams, true); } clearSettings(); } @@ -826,7 +858,13 @@ public abstract class DataConnection extends StateMachine { case EVENT_DISCONNECT: if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); - notifyDisconnectCompleted((DisconnectParams)msg.obj); + notifyDisconnectCompleted((DisconnectParams)msg.obj, false); + retVal = HANDLED; + break; + + case EVENT_DISCONNECT_ALL: + if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); + notifyDisconnectCompleted((DisconnectParams)msg.obj, false); retVal = HANDLED; break; @@ -1003,12 +1041,24 @@ public abstract class DataConnection extends StateMachine { transitionTo(mDisconnectingState); } else { if (msg.obj != null) { - notifyDisconnectCompleted((DisconnectParams) msg.obj); + notifyDisconnectCompleted((DisconnectParams) msg.obj, false); } } retVal = HANDLED; break; + case EVENT_DISCONNECT_ALL: + if (DBG) { + log("DcActiveState msg.what=EVENT_DISCONNECT_ALL RefCount=" + mRefCount); + } + mRefCount = 0; + DisconnectParams dp = (DisconnectParams) msg.obj; + dp.tag = mTag; + tearDownData(dp); + transitionTo(mDisconnectingState); + retVal = HANDLED; + break; + default: if (VDBG) { log("DcActiveState not handled msg.what=0x" + @@ -1138,4 +1188,16 @@ public abstract class DataConnection extends StateMachine { public void tearDown(String reason, Message onCompletedMsg) { sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(reason, onCompletedMsg))); } + + /** + * Tear down the connection through the apn on the network. Ignores refcount and + * and always tears down. + * + * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. + * With AsyncResult.userObj set to the original msg.obj. + */ + public void tearDownAll(String reason, Message onCompletedMsg) { + sendMessage(obtainMessage(EVENT_DISCONNECT_ALL, + new DisconnectParams(reason, onCompletedMsg))); + } } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 6d9a2c2..863235b 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -212,8 +212,10 @@ public abstract class DataConnectionTracker extends Handler { // represents an invalid IP address protected static final String NULL_IP = "0.0.0.0"; - // Default for the data stall alarm - protected static final int DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6; + // Default for the data stall alarm while non-aggressive stall detection + protected static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6; + // Default for the data stall alarm for aggressive stall detection + protected static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60; // If attempt is less than this value we're doing first level recovery protected static final int DATA_STALL_NO_RECV_POLL_LIMIT = 1; // Tag for tracking stale alarms @@ -323,10 +325,12 @@ public abstract class DataConnectionTracker extends Handler { mIsScreenOn = true; stopNetStatPoll(); startNetStatPoll(); + restartDataStallAlarm(); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { mIsScreenOn = false; stopNetStatPoll(); startNetStatPoll(); + restartDataStallAlarm(); } else if (action.startsWith(getActionIntentReconnectAlarm())) { log("Reconnect alarm. Previous state was " + mState); onActionIntentReconnectAlarm(intent); @@ -622,6 +626,7 @@ public abstract class DataConnectionTracker extends Handler { protected abstract String getActionIntentDataStallAlarm(); protected abstract void startNetStatPoll(); protected abstract void stopNetStatPoll(); + protected abstract void restartDataStallAlarm(); protected abstract void restartRadio(); protected abstract void log(String s); protected abstract void loge(String s); @@ -1024,8 +1029,11 @@ public abstract class DataConnectionTracker extends Handler { didDisable = true; } } - if (didDisable && enabledCount == 0) { - onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED); + if (didDisable) { + if ((enabledCount == 0) || (apnId == APN_DUN_ID)) { + mRequestedApnType = Phone.APN_TYPE_DEFAULT; + onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED); + } // send the disconnect msg manually, since the normal route wont send // it (it's not enabled) diff --git a/telephony/java/com/android/internal/telephony/cat/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java index 2eb6ccb..299e140 100644 --- a/telephony/java/com/android/internal/telephony/cat/AppInterface.java +++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java @@ -42,6 +42,7 @@ public interface AppInterface { * Enumeration for representing "Type of Command" of proactive commands. * Those are the only commands which are supported by the Telephony. Any app * implementation should support those. + * Refer to ETSI TS 102.223 section 9.4 */ public static enum CommandType { DISPLAY_TEXT(0x21), @@ -59,7 +60,11 @@ public interface AppInterface { SET_UP_IDLE_MODE_TEXT(0x28), SET_UP_MENU(0x25), SET_UP_CALL(0x10), - PROVIDE_LOCAL_INFORMATION(0x26); + PROVIDE_LOCAL_INFORMATION(0x26), + OPEN_CHANNEL(0x40), + CLOSE_CHANNEL(0x41), + RECEIVE_DATA(0x42), + SEND_DATA(0x43); private int mValue; diff --git a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java index 5155bb2..48c2e2b 100644 --- a/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java +++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java @@ -85,6 +85,13 @@ public class CatCmdMessage implements Parcelable { mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg; mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg; break; + case OPEN_CHANNEL: + case CLOSE_CHANNEL: + case RECEIVE_DATA: + case SEND_DATA: + BIPClientParams param = (BIPClientParams) cmdParams; + mTextMsg = param.textMsg; + break; } } diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java index 5a994f3..74af9fa 100644 --- a/telephony/java/com/android/internal/telephony/cat/CatService.java +++ b/telephony/java/com/android/internal/telephony/cat/CatService.java @@ -18,6 +18,8 @@ package com.android.internal.telephony.cat; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.AsyncResult; import android.os.Handler; import android.os.HandlerThread; @@ -32,6 +34,7 @@ import com.android.internal.telephony.IccRecords; import java.io.ByteArrayOutputStream; +import java.util.List; import java.util.Locale; class RilMessage { @@ -72,6 +75,7 @@ public class CatService extends Handler implements AppInterface { private CatCmdMessage mMenuCmd = null; private RilMessageDecoder mMsgDecoder = null; + private boolean mStkAppInstalled = false; // Service constants. static final int MSG_ID_SESSION_END = 1; @@ -125,7 +129,10 @@ public class CatService extends Handler implements AppInterface { mCmdIf.registerForNVReady(this, MSG_ID_SIM_READY, null); mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null); - CatLog.d(this, "Is running"); + // Check if STK application is availalbe + mStkAppInstalled = isStkAppInstalled(); + + CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled); } public void dispose() { @@ -154,7 +161,7 @@ public class CatService extends Handler implements AppInterface { if (rilMsg.mResCode == ResultCode.OK) { cmdParams = (CommandParams) rilMsg.mData; if (cmdParams != null) { - handleProactiveCommand(cmdParams); + handleCommand(cmdParams, false); } } break; @@ -170,7 +177,7 @@ public class CatService extends Handler implements AppInterface { } if (cmdParams != null) { if (rilMsg.mResCode == ResultCode.OK) { - handleProactiveCommand(cmdParams); + handleCommand(cmdParams, true); } else { // for proactive commands that couldn't be decoded // successfully respond with the code generated by the @@ -183,7 +190,7 @@ public class CatService extends Handler implements AppInterface { case MSG_ID_REFRESH: cmdParams = (CommandParams) rilMsg.mData; if (cmdParams != null) { - handleProactiveCommand(cmdParams); + handleCommand(cmdParams, false); } break; case MSG_ID_SESSION_END: @@ -197,11 +204,13 @@ public class CatService extends Handler implements AppInterface { } /** - * Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL. + * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command + * from RIL. * Sends valid proactive command data to the application using intents. - * + * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is + * from RIL_UNSOL_STK_PROACTIVE_COMMAND. */ - private void handleProactiveCommand(CommandParams cmdParams) { + private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) { CatLog.d(this, cmdParams.getCommandType().name()); CharSequence message; @@ -235,15 +244,16 @@ public class CatService extends Handler implements AppInterface { case CommandParamsFactory.DTTZ_SETTING: resp = new DTTZResponseData(null); sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); - return; + break; case CommandParamsFactory.LANGUAGE_SETTING: resp = new LanguageResponseData(Locale.getDefault().getLanguage()); sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp); - return; + break; default: sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); - return; } + // No need to start STK app here. + return; case LAUNCH_BROWSER: if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null) && (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) { @@ -274,6 +284,42 @@ public class CatService extends Handler implements AppInterface { ((CallSetupParams) cmdParams).confirmMsg.text = message.toString(); } break; + case OPEN_CHANNEL: + case CLOSE_CHANNEL: + case RECEIVE_DATA: + case SEND_DATA: + BIPClientParams cmd = (BIPClientParams) cmdParams; + if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) { + CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id"); + // If alpha length is zero, we just respond with OK. + if (isProactiveCmd) { + sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); + } + return; + } + // Respond with permanent failure to avoid retry if STK app is not present. + if (!mStkAppInstalled) { + CatLog.d(this, "No STK application found."); + if (isProactiveCmd) { + sendTerminalResponse(cmdParams.cmdDet, + ResultCode.BEYOND_TERMINAL_CAPABILITY, + false, 0, null); + return; + } + } + /* + * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by + * either PROACTIVE_COMMAND or EVENT_NOTIFY. + * If PROACTIVE_COMMAND is used for those commands, send terminal + * response here. + */ + if (isProactiveCmd && + ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) || + (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) || + (cmdParams.getCommandType() == CommandType.SEND_DATA))) { + sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null); + } + break; default: CatLog.d(this, "Unsupported command"); return; @@ -684,6 +730,7 @@ public class CatService extends Handler implements AppInterface { case NO_RESPONSE_FROM_USER: case UICC_SESSION_TERM_BY_USER: case BACKWARD_MOVE_BY_USER: + case USER_NOT_ACCEPT: resp = null; break; default: @@ -692,4 +739,14 @@ public class CatService extends Handler implements AppInterface { sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); mCurrntCmd = null; } + + private boolean isStkAppInstalled() { + Intent intent = new Intent(AppInterface.CAT_CMD_ACTION); + PackageManager pm = mContext.getPackageManager(); + List<ResolveInfo> broadcastReceivers = + pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA); + int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size(); + + return (numReceiver > 0); + } } diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java index 22a5c8c..959c9e2 100644 --- a/telephony/java/com/android/internal/telephony/cat/CommandParams.java +++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java @@ -166,4 +166,29 @@ class GetInputParams extends CommandParams { } } +/* + * BIP (Bearer Independent Protocol) is the mechanism for SIM card applications + * to access data connection through the mobile device. + * + * SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and + * RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for + * the details of proactive commands procedures and their structures. + */ +class BIPClientParams extends CommandParams { + TextMessage textMsg; + boolean bHasAlphaId; + + BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) { + super(cmdDet); + this.textMsg = textMsg; + this.bHasAlphaId = has_alpha_id; + } + boolean setIcon(Bitmap icon) { + if (icon != null && textMsg != null) { + textMsg.icon = icon; + return true; + } + return false; + } +} diff --git a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java index e7fca5a..89c1329 100644 --- a/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java +++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java @@ -165,6 +165,12 @@ class CommandParamsFactory extends Handler { case PROVIDE_LOCAL_INFORMATION: cmdPending = processProvideLocalInfo(cmdDet, ctlvs); break; + case OPEN_CHANNEL: + case CLOSE_CHANNEL: + case RECEIVE_DATA: + case SEND_DATA: + cmdPending = processBIPClient(cmdDet, ctlvs); + break; default: // unsupported proactive commands mCmdParams = new CommandParams(cmdDet); @@ -893,4 +899,43 @@ class CommandParamsFactory extends Handler { } return false; } + + private boolean processBIPClient(CommandDetails cmdDet, + List<ComprehensionTlv> ctlvs) throws ResultException { + AppInterface.CommandType commandType = + AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); + if (commandType != null) { + CatLog.d(this, "process "+ commandType.name()); + } + + TextMessage textMsg = new TextMessage(); + IconId iconId = null; + ComprehensionTlv ctlv = null; + boolean has_alpha_id = false; + + // parse alpha identifier + ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); + if (ctlv != null) { + textMsg.text = ValueParser.retrieveAlphaId(ctlv); + CatLog.d(this, "alpha TLV text=" + textMsg.text); + has_alpha_id = true; + } + + // parse icon identifier + ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); + if (ctlv != null) { + iconId = ValueParser.retrieveIconId(ctlv); + textMsg.iconSelfExplanatory = iconId.selfExplanatory; + } + + textMsg.responseNeeded = false; + mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id); + + if (iconId != null) { + mIconLoadState = LOAD_SINGLE_ICON; + mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE)); + return true; + } + return false; + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java index d55f346..a93d94f 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java @@ -20,6 +20,7 @@ import android.os.Message; import android.util.Log; import com.android.internal.telephony.DataConnection; +import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.RetryManager; @@ -32,8 +33,9 @@ public class CdmaDataConnection extends DataConnection { private static final String LOG_TAG = "CDMA"; // ***** Constructor - private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm) { - super(phone, name, id, rm); + private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { + super(phone, name, id, rm, dct); } /** @@ -44,12 +46,13 @@ public class CdmaDataConnection extends DataConnection { * @param rm the RetryManager * @return CdmaDataConnection that was created. */ - static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm) { + static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm, + DataConnectionTracker dct) { synchronized (mCountLock) { mCount += 1; } CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount, - id, rm); + id, rm, dct); cdmaDc.start(); if (DBG) cdmaDc.log("Made " + cdmaDc.getName()); return cdmaDc; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 5889372..0a1b1e4 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -41,6 +41,7 @@ import com.android.internal.telephony.DataConnectionAc; import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.RetryManager; +import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.Phone; import com.android.internal.util.AsyncChannel; @@ -92,6 +93,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { Phone.APN_TYPE_MMS, Phone.APN_TYPE_HIPRI }; + private String[] mDunApnTypes = { + Phone.APN_TYPE_DUN }; + private static final int mDefaultApnId = DataConnectionTracker.APN_DEFAULT_ID; /* Constructor */ @@ -117,11 +121,26 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { createAllDataConnectionList(); broadcastMessenger(); + + Context c = mCdmaPhone.getContext(); + String[] t = c.getResources().getStringArray( + com.android.internal.R.array.config_cdma_dun_supported_types); + if (t != null && t.length > 0) { + ArrayList<String> temp = new ArrayList<String>(); + for(int i=0; i< t.length; i++) { + if (!Phone.APN_TYPE_DUN.equalsIgnoreCase(t[i])) { + temp.add(t[i]); + } + } + temp.add(0, Phone.APN_TYPE_DUN); + mDunApnTypes = temp.toArray(t); + } + } @Override public void dispose() { - cleanUpConnection(false, null); + cleanUpConnection(false, null, false); super.dispose(); @@ -158,6 +177,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } @Override + protected void restartDataStallAlarm() {} + + @Override protected void setState(State s) { if (DBG) log ("setState: " + s); if (mState != s) { @@ -204,7 +226,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { internalDataEnabled && desiredPowerState && !mPendingRestartRadio && - !mCdmaPhone.needsOtaServiceProvisioning(); + ((mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) || + !mCdmaPhone.needsOtaServiceProvisioning()); if (!allowed && DBG) { String reason = ""; if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) { @@ -273,7 +296,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { * @param tearDown true if the underlying DataConnection should be disconnected. * @param reason for the clean up. */ - private void cleanUpConnection(boolean tearDown, String reason) { + private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) { if (DBG) log("cleanUpConnection: reason: " + reason); // Clear the reconnect alarm, if set. @@ -293,9 +316,15 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { DataConnectionAc dcac = mDataConnectionAsyncChannels.get(conn.getDataConnectionId()); if (tearDown) { - if (DBG) log("cleanUpConnection: teardown, call conn.disconnect"); - conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE, - conn.getDataConnectionId(), 0, reason)); + if (doAll) { + if (DBG) log("cleanUpConnection: teardown, conn.tearDownAll"); + conn.tearDownAll(reason, obtainMessage(EVENT_DISCONNECT_DONE, + conn.getDataConnectionId(), 0, reason)); + } else { + if (DBG) log("cleanUpConnection: teardown, conn.tearDown"); + conn.tearDown(reason, obtainMessage(EVENT_DISCONNECT_DONE, + conn.getDataConnectionId(), 0, reason)); + } notificationDeferred = true; } else { if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously"); @@ -339,8 +368,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { String[] types; int apnId; if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) { - types = new String[1]; - types[0] = Phone.APN_TYPE_DUN; + types = mDunApnTypes; apnId = DataConnectionTracker.APN_DUN_ID; } else { types = mDefaultApnTypes; @@ -506,7 +534,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { return retry; } - private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) { + private void reconnectAfterFail(FailCause lastFailCauseCode, String reason, int retryOverride) { if (mState == State.FAILED) { /** * For now With CDMA we never try to reconnect on @@ -514,9 +542,12 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { * at the last time until the state is changed. * TODO: Make this configurable? */ - int nextReconnectDelay = mDataConnections.get(0).getRetryTimer(); + int nextReconnectDelay = retryOverride; + if (nextReconnectDelay < 0) { + nextReconnectDelay = mDataConnections.get(0).getRetryTimer(); + mDataConnections.get(0).increaseRetryCount(); + } startAlarmForReconnect(nextReconnectDelay, reason); - mDataConnections.get(0).increaseRetryCount(); if (!shouldPostNotification(lastFailCauseCode)) { log("NOT Posting Data Connection Unavailable notification " @@ -575,7 +606,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { @Override protected void onEnableNewApn() { // No mRequestedApnType check; only one connection is supported - cleanUpConnection(true, Phone.REASON_APN_SWITCHED); + cleanUpConnection(true, Phone.REASON_APN_SWITCHED, false); } /** @@ -674,7 +705,17 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { notifyNoData(cause); return; } - startDelayedRetry(cause, reason); + + int retryOverride = -1; + if (ar.exception instanceof DataConnection.CallSetupException) { + retryOverride = + ((DataConnection.CallSetupException)ar.exception).getRetryOverride(); + } + if (retryOverride == RILConstants.MAX_INT) { + if (DBG) log("No retry is suggested."); + } else { + startDelayedRetry(cause, reason, retryOverride); + } } } @@ -747,13 +788,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { @Override protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) { // No apnId check; only one connection is supported - cleanUpConnection(tearDown, reason); + cleanUpConnection(tearDown, reason, (apnId == APN_DUN_ID)); } @Override protected void onCleanUpAllConnections(String cause) { // Only one CDMA connection is supported - cleanUpConnection(true, cause); + cleanUpConnection(true, cause, false); } private void createAllDataConnectionList() { @@ -772,7 +813,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } int id = mUniqueIdGenerator.getAndIncrement(); - dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm); + dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm, this); mDataConnections.put(id, dataConn); DataConnectionAc dcac = new DataConnectionAc(dataConn, LOG_TAG); int status = dcac.fullyConnectSync(mPhone.getContext(), this, dataConn.getHandler()); @@ -799,7 +840,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); } else { if (mState == State.FAILED) { - cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED); + cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED, false); mDataConnections.get(0).resetRetryCount(); CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation()); @@ -878,7 +919,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { log("onDataStateChanged: No active connection" + "state is CONNECTED, disconnecting/cleanup"); writeEventLogCdmaDataDrop(); - cleanUpConnection(true, null); + cleanUpConnection(true, null, false); return; } @@ -907,9 +948,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } } - private void startDelayedRetry(FailCause cause, String reason) { + private void startDelayedRetry(FailCause cause, String reason, int retryOverride) { notifyNoData(cause); - reconnectAfterFail(cause, reason); + reconnectAfterFail(cause, reason, retryOverride); } @Override diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java index 3486190..610cd5d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java @@ -147,7 +147,9 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { @Override protected void setSignalStrengthDefaultValues() { - mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, false); + // TODO Make a constructor only has boolean gsm as parameter + mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, + -1, -1, -1, SignalStrength.INVALID_SNR, -1, false); } @Override @@ -452,8 +454,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { setSignalStrengthDefaultValues(); } else { int[] ints = (int[])ar.result; - int lteCqi = 99, lteRsrp = -1; - int lteRssi = 99; + + int lteRssi = -1; + int lteRsrp = -1; + int lteRsrq = -1; + int lteRssnr = SignalStrength.INVALID_SNR; + int lteCqi = -1; + int offset = 2; int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120; int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160; @@ -461,10 +468,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1; int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4] : -1; + if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) { - lteRssi = (ints[offset + 5] >= 0) ? ints[offset + 5] : 99; - lteRsrp = (ints[offset + 6] < 0) ? ints[offset + 6] : -1; - lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 7] : 99; + lteRssi = ints[offset+5]; + lteRsrp = ints[offset+6]; + lteRsrq = ints[offset+7]; + lteRssnr = ints[offset+8]; + lteCqi = ints[offset+9]; } if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) { @@ -472,7 +482,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { evdoSnr, false); } else { mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, - evdoSnr, lteRssi, lteRsrp, -1, -1, lteCqi, true); + evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true); } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java index 1f24b58..1f5b7ab 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java @@ -22,6 +22,7 @@ import android.util.Patterns; import android.text.TextUtils; import com.android.internal.telephony.DataConnection; +import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneBase; import com.android.internal.telephony.RILConstants; @@ -38,8 +39,9 @@ public class GsmDataConnection extends DataConnection { protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT; protected String mActiveApnType = Phone.APN_TYPE_DEFAULT; //***** Constructor - private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) { - super(phone, name, id, rm); + private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm, + DataConnectionTracker dct) { + super(phone, name, id, rm, dct); } /** @@ -50,11 +52,12 @@ public class GsmDataConnection extends DataConnection { * @param rm the RetryManager * @return GsmDataConnection that was created. */ - static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm) { + static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm, + DataConnectionTracker dct) { synchronized (mCountLock) { mCount += 1; } - GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm); + GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct); gsmDc.start(); if (DBG) gsmDc.log("Made " + gsmDc.getName()); return gsmDc; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index cbcedb4..4c2666a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -76,6 +76,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class GsmDataConnectionTracker extends DataConnectionTracker { protected final String LOG_TAG = "GSM"; + private static final boolean RADIO_TESTS = false; /** * Handles changes to the APN db. @@ -97,13 +98,21 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private ContentResolver mResolver; // Recovery action taken in case of data stall - class RecoveryAction { + private static class RecoveryAction { public static final int GET_DATA_CALL_LIST = 0; public static final int CLEANUP = 1; public static final int REREGISTER = 2; public static final int RADIO_RESTART = 3; public static final int RADIO_RESTART_WITH_PROP = 4; + + private static boolean isAggressiveRecovery(int value) { + return ((value == RecoveryAction.CLEANUP) || + (value == RecoveryAction.REREGISTER) || + (value == RecoveryAction.RADIO_RESTART) || + (value == RecoveryAction.RADIO_RESTART_WITH_PROP)); + } } + public int getRecoveryAction() { int action = Settings.System.getInt(mPhone.getContext().getContentResolver(), "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST); @@ -127,10 +136,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private static final String INTENT_DATA_STALL_ALARM = "com.android.internal.telephony.gprs-data-stall"; - static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn"); + static final Uri PREFERAPN_NO_UPDATE_URI = + Uri.parse("content://telephony/carriers/preferapn_no_update"); static final String APN_ID = "apn_id"; private boolean canSetPreferApn = false; + private static final boolean DATA_STALL_SUSPECTED = true; + private static final boolean DATA_STALL_NOT_SUSPECTED = false; + @Override protected void onActionIntentReconnectAlarm(Intent intent) { if (DBG) log("GPRS reconnect alarm. Previous state was " + mState); @@ -595,7 +608,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (getOverallState() == State.CONNECTED) { if (DBG) log("onDataConnectionAttached: start polling notify attached"); startNetStatPoll(); - startDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); notifyDataConnection(Phone.REASON_DATA_ATTACHED); } else { // update APN availability so that APN can be enabled. @@ -846,9 +859,28 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // Connection is still there. Try to clean up. if (dcac != null) { if (apnContext.getState() != State.DISCONNECTING) { - if (DBG) log("cleanUpConnection: tearing down"); + boolean disconnectAll = false; + if (Phone.APN_TYPE_DUN.equals(apnContext.getApnType())) { + ApnSetting dunSetting = fetchDunApn(); + if (dunSetting != null && + dunSetting.equals(apnContext.getApnSetting())) { + if (DBG) log("tearing down dedicated DUN connection"); + // we need to tear it down - we brought it up just for dun and + // other people are camped on it and now dun is done. We need + // to stop using it and let the normal apn list get used to find + // connections for the remaining desired connections + disconnectAll = true; + } + } + if (DBG) { + log("cleanUpConnection: tearing down" + (disconnectAll ? " all" :"")); + } Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext); - apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); + if (disconnectAll) { + apnContext.getDataConnection().tearDownAll(apnContext.getReason(), msg); + } else { + apnContext.getDataConnection().tearDown(apnContext.getReason(), msg); + } apnContext.setState(State.DISCONNECTING); } } else { @@ -1280,7 +1312,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { // setState(State.CONNECTED); mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType()); startNetStatPoll(); - startDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); // reset reconnect timer apnContext.getDataConnection().resetRetryCount(); } @@ -1403,7 +1435,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts; received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts; - if (VDBG) { + if (RADIO_TESTS) { if (SystemProperties.getBoolean("radio.test.data.stall", false)) { log("updateDataStallInfo: radio.test.data.stall true received = 0;"); received = 0; @@ -1446,10 +1478,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, NUMBER_SENT_PACKETS_OF_HANG); + boolean suspectedStall = DATA_STALL_NOT_SUSPECTED; if (mSentSinceLastRecv >= hangWatchdogTrigger) { if (DBG) { log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction()); } + suspectedStall = DATA_STALL_SUSPECTED; sendMessage(obtainMessage(EVENT_DO_RECOVERY)); } else { if (VDBG) { @@ -1457,7 +1491,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger); } } - startDataStallAlarm(); + startDataStallAlarm(suspectedStall); } @@ -1623,12 +1657,24 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } - private void startDataStallAlarm() { - int delayInMs = Settings.Secure.getInt(mResolver, - Settings.Secure.DATA_STALL_ALARM_DELAY_IN_MS, - DATA_STALL_ALARM_DELAY_IN_MS_DEFAULT); + private void startDataStallAlarm(boolean suspectedStall) { + int nextAction = getRecoveryAction(); + int delayInMs; + + // If screen is on or data stall is currently suspected, set the alarm + // with an aggresive timeout. + if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) { + delayInMs = Settings.Secure.getInt(mResolver, + Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS, + DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT); + } else { + delayInMs = Settings.Secure.getInt(mResolver, + Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS, + DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT); + } + mDataStallAlarmTag += 1; - if (DBG) { + if (VDBG) { log("startDataStallAlarm: tag=" + mDataStallAlarmTag + " delay=" + (delayInMs / 1000) + "s"); } @@ -1647,7 +1693,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { AlarmManager am = (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - if (DBG) { + if (VDBG) { log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag + " mDataStallAlarmIntent=" + mDataStallAlarmIntent); } @@ -1658,6 +1704,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } } + @Override + protected void restartDataStallAlarm() { + // To be called on screen status change. + // Do not cancel the alarm if it is set with aggressive timeout. + int nextAction = getRecoveryAction(); + + if (RecoveryAction.isAggressiveRecovery(nextAction)) { + if (DBG) log("data stall recovery action is pending. not resetting the alarm."); + return; + } + stopDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); + } + private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode, ApnContext apnContext) { if (DBG) log( "notifyNoData: type=" + apnContext.getApnType()); @@ -1861,6 +1921,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { @Override protected void onDataSetupComplete(AsyncResult ar) { + DataConnection.FailCause cause = DataConnection.FailCause.UNKNOWN; + boolean handleError = false; ApnContext apnContext = null; if(ar.userObj instanceof ApnContext){ @@ -1871,52 +1933,73 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (isDataSetupCompleteOk(ar)) { DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (dcac == null) { - throw new RuntimeException("onDataSetupCompete: No dcac"); - } - DataConnection dc = apnContext.getDataConnection(); - if (DBG) { - // TODO We may use apnContext.getApnSetting() directly - // instead of getWaitingApns().get(0) - String apnStr = "<unknown>"; - if (apnContext.getWaitingApns() != null - && !apnContext.getWaitingApns().isEmpty()){ - apnStr = apnContext.getWaitingApns().get(0).apn; + if (RADIO_TESTS) { + // Note: To change radio.test.onDSC.null.dcac from command line you need to + // adb root and adb remount and from the command line you can only change the + // value to 1 once. To change it a second time you can reboot or execute + // adb shell stop and then adb shell start. The command line to set the value is: + // adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');" + ContentResolver cr = mPhone.getContext().getContentResolver(); + String radioTestProperty = "radio.test.onDSC.null.dcac"; + if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) { + log("onDataSetupComplete: " + radioTestProperty + + " is true, set dcac to null and reset property to false"); + dcac = null; + Settings.System.putInt(cr, radioTestProperty, 0); + log("onDataSetupComplete: " + radioTestProperty + "=" + + Settings.System.getInt(mPhone.getContext().getContentResolver(), + radioTestProperty, -1)); } - log("onDataSetupComplete: success apn=" + apnStr); } - ApnSetting apn = apnContext.getApnSetting(); - if (apn.proxy != null && apn.proxy.length() != 0) { - try { - String port = apn.port; - if (TextUtils.isEmpty(port)) port = "8080"; - ProxyProperties proxy = new ProxyProperties(apn.proxy, - Integer.parseInt(port), null); - dcac.setLinkPropertiesHttpProxySync(proxy); - } catch (NumberFormatException e) { - loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" + - apn.port + "): " + e); + if (dcac == null) { + log("onDataSetupComplete: no connection to DC, handle as error"); + cause = DataConnection.FailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN; + handleError = true; + } else { + DataConnection dc = apnContext.getDataConnection(); + + if (DBG) { + // TODO We may use apnContext.getApnSetting() directly + // instead of getWaitingApns().get(0) + String apnStr = "<unknown>"; + if (apnContext.getWaitingApns() != null + && !apnContext.getWaitingApns().isEmpty()){ + apnStr = apnContext.getWaitingApns().get(0).apn; + } + log("onDataSetupComplete: success apn=" + apnStr); + } + ApnSetting apn = apnContext.getApnSetting(); + if (apn.proxy != null && apn.proxy.length() != 0) { + try { + String port = apn.port; + if (TextUtils.isEmpty(port)) port = "8080"; + ProxyProperties proxy = new ProxyProperties(apn.proxy, + Integer.parseInt(port), null); + dcac.setLinkPropertiesHttpProxySync(proxy); + } catch (NumberFormatException e) { + loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" + + apn.port + "): " + e); + } } - } - // everything is setup - if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) { - SystemProperties.set("gsm.defaultpdpcontext.active", "true"); - if (canSetPreferApn && mPreferredApn == null) { - if (DBG) log("onDataSetupComplete: PREFERED APN is null"); - mPreferredApn = apnContext.getApnSetting(); - if (mPreferredApn != null) { - setPreferredApn(mPreferredApn.id); + // everything is setup + if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) { + SystemProperties.set("gsm.defaultpdpcontext.active", "true"); + if (canSetPreferApn && mPreferredApn == null) { + if (DBG) log("onDataSetupComplete: PREFERED APN is null"); + mPreferredApn = apnContext.getApnSetting(); + if (mPreferredApn != null) { + setPreferredApn(mPreferredApn.id); + } } + } else { + SystemProperties.set("gsm.defaultpdpcontext.active", "false"); } - } else { - SystemProperties.set("gsm.defaultpdpcontext.active", "false"); + notifyDefaultData(apnContext); } - notifyDefaultData(apnContext); } else { String apnString; - DataConnection.FailCause cause; cause = (DataConnection.FailCause) (ar.result); if (DBG) { @@ -1944,7 +2027,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { apnContext.getWaitingApns().size(), apnContext.getWaitingApnsPermFailCount())); } + handleError = true; + } + if (handleError) { // See if there are more APN's to try if (apnContext.getWaitingApns().isEmpty()) { if (apnContext.getWaitingApnsPermFailCount() == 0) { @@ -1956,9 +2042,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { apnContext.setDataConnection(null); apnContext.setDataConnectionAc(null); - if (DBG) { - log("onDataSetupComplete: permanent error apn=%s" + apnString ); - } } else { if (DBG) log("onDataSetupComplete: Not all permanent failures, retry"); // check to see if retry should be overridden for this failure. @@ -2053,7 +2136,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { if (isConnected()) { if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { startNetStatPoll(); - startDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); } else { // clean slate after call end. @@ -2158,7 +2241,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { RetryManager rm = new RetryManager(); int id = mUniqueIdGenerator.getAndIncrement(); - GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm); + GsmDataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm, this); mDataConnections.put(id, conn); DataConnectionAc dcac = new DataConnectionAc(conn, LOG_TAG); int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler()); @@ -2288,26 +2371,30 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private void setPreferredApn(int pos) { if (!canSetPreferApn) { + log("setPreferredApn: X !canSEtPreferApn"); return; } + log("setPreferredApn: delete"); ContentResolver resolver = mPhone.getContext().getContentResolver(); - resolver.delete(PREFERAPN_URI, null, null); + resolver.delete(PREFERAPN_NO_UPDATE_URI, null, null); if (pos >= 0) { + log("setPreferredApn: insert"); ContentValues values = new ContentValues(); values.put(APN_ID, pos); - resolver.insert(PREFERAPN_URI, values); + resolver.insert(PREFERAPN_NO_UPDATE_URI, values); } } private ApnSetting getPreferredApn() { if (mAllApns.isEmpty()) { + log("getPreferredApn: X not found mAllApns.isEmpty"); return null; } Cursor cursor = mPhone.getContext().getContentResolver().query( - PREFERAPN_URI, new String[] { "_id", "name", "apn" }, + PREFERAPN_NO_UPDATE_URI, new String[] { "_id", "name", "apn" }, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER); if (cursor != null) { @@ -2322,6 +2409,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)); for(ApnSetting p:mAllApns) { if (p.id == pos && p.canHandleType(mRequestedApnType)) { + log("getPreferredApn: X found apnSetting" + p); cursor.close(); return p; } @@ -2332,6 +2420,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { cursor.close(); } + log("getPreferredApn: X not found"); return null; } @@ -2395,7 +2484,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { mIsPsRestricted = false; if (isConnected()) { startNetStatPoll(); - startDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); } else { // TODO: Should all PDN states be checked to fail? if (mState == State.FAILED) { diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 8ddbc5c..21167a9 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -671,7 +671,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } private void setSignalStrengthDefaultValues() { - mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, true); + // TODO Make a constructor only has boolean gsm as parameter + mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, + -1, -1, -1, SignalStrength.INVALID_SNR, -1, true); } /** @@ -1023,7 +1025,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { int lteSignalStrength = -1; int lteRsrp = -1; int lteRsrq = -1; - int lteRssnr = -1; + int lteRssnr = SignalStrength.INVALID_SNR; int lteCqi = -1; if (ar.exception != null) { |