am 01b13a11: Merge "Replacing browser playback controls for inactive videos Bug: 4136024" into honeycomb-mr1
* commit '01b13a11e6492ebba66c496eaefdb008f2638870':
Replacing browser playback controls for inactive videos Bug: 4136024
diff --git a/Android.mk b/Android.mk
index b266061..6216a2c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -123,10 +123,10 @@
core/java/android/nfc/ILlcpServiceSocket.aidl \
core/java/android/nfc/ILlcpSocket.aidl \
core/java/android/nfc/INfcAdapter.aidl \
+ core/java/android/nfc/INfcAdapterExtras.aidl \
core/java/android/nfc/INfcTag.aidl \
core/java/android/nfc/IP2pInitiator.aidl \
core/java/android/nfc/IP2pTarget.aidl \
- core/java/android/nfc/INfcSecureElement.aidl \
core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkManagementService.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2eee813..023ce59 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -95,7 +95,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PerfTest_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/RSTest_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware/IUsbManager.java)
-
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ccd65de..c9351af 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -416,7 +416,7 @@
if (this.largeIcon != null) {
that.largeIcon = Bitmap.createBitmap(this.largeIcon);
}
- that.iconLevel = that.iconLevel;
+ that.iconLevel = this.iconLevel;
that.sound = this.sound; // android.net.Uri is immutable
that.audioStreamType = this.audioStreamType;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index cab8ed2..26f375d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -221,12 +221,32 @@
/** {@hide} */
public static final int TYPE_DUMMY = 8;
+
/** {@hide} */
public static final int TYPE_ETHERNET = 9;
- /** {@hide} TODO: Need to adjust this for WiMAX. */
- public static final int MAX_RADIO_TYPE = TYPE_DUMMY;
- /** {@hide} TODO: Need to adjust this for WiMAX. */
- public static final int MAX_NETWORK_TYPE = TYPE_DUMMY;
+ /**
+ * Over the air Adminstration.
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_FOTA = 10;
+
+ /**
+ * IP Multimedia Subsystem
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_IMS = 11;
+
+ /**
+ * Carrier Branded Services
+ * {@hide}
+ */
+ public static final int TYPE_MOBILE_CBS = 12;
+
+ /** {@hide} */
+ public static final int MAX_RADIO_TYPE = TYPE_MOBILE_CBS;
+
+ /** {@hide} */
+ public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_CBS;
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index b6e9751..81d62a0 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -91,7 +91,7 @@
}
public void addLinkAddress(LinkAddress address) {
- mLinkAddresses.add(address);
+ if (address != null) mLinkAddresses.add(address);
}
public Collection<LinkAddress> getLinkAddresses() {
@@ -99,7 +99,7 @@
}
public void addDns(InetAddress dns) {
- mDnses.add(dns);
+ if (dns != null) mDnses.add(dns);
}
public Collection<InetAddress> getDnses() {
@@ -107,7 +107,7 @@
}
public void addGateway(InetAddress gateway) {
- mGateways.add(gateway);
+ if (gateway != null) mGateways.add(gateway);
}
public Collection<InetAddress> getGateways() {
return Collections.unmodifiableCollection(mGateways);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index e04964e..5b4da66 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -437,7 +437,8 @@
retValue = true;
break;
case Phone.APN_REQUEST_STARTED:
- // no need to do anything - we're already due some status update intents
+ // set IDLE here , avoid the following second FAILED not sent out
+ mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
retValue = true;
break;
case Phone.APN_REQUEST_FAILED:
@@ -546,6 +547,12 @@
return Phone.APN_TYPE_DUN;
case ConnectivityManager.TYPE_MOBILE_HIPRI:
return Phone.APN_TYPE_HIPRI;
+ case ConnectivityManager.TYPE_MOBILE_FOTA:
+ return Phone.APN_TYPE_FOTA;
+ case ConnectivityManager.TYPE_MOBILE_IMS:
+ return Phone.APN_TYPE_IMS;
+ case ConnectivityManager.TYPE_MOBILE_CBS:
+ return Phone.APN_TYPE_CBS;
default:
sloge("Error mapping networkType " + netType + " to apnType.");
return null;
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index d439a48..870127c 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -28,7 +28,7 @@
import android.nfc.INfcTag;
import android.nfc.IP2pTarget;
import android.nfc.IP2pInitiator;
-import android.nfc.INfcSecureElement;
+import android.nfc.INfcAdapterExtras;
/**
* @hide
@@ -41,13 +41,12 @@
INfcTag getNfcTagInterface();
IP2pTarget getP2pTargetInterface();
IP2pInitiator getP2pInitiatorInterface();
- INfcSecureElement getNfcSecureElementInterface();
+ INfcAdapterExtras getNfcAdapterExtrasInterface();
// NfcAdapter-class related methods
boolean isEnabled();
NdefMessage localGet();
void localSet(in NdefMessage message);
- void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
@@ -59,12 +58,8 @@
int createLlcpConnectionlessSocket(int sap);
int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
- int deselectSecureElement();
boolean disable();
boolean enable();
String getProperties(String param);
- int[] getSecureElementList();
- int getSelectedSecureElement();
- int selectSecureElement(int seId);
int setProperties(String param, String value);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/nfc/INfcSecureElement.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
similarity index 63%
rename from core/java/android/nfc/INfcSecureElement.aidl
rename to core/java/android/nfc/INfcAdapterExtras.aidl
index aa98dd2..ab5c1a6 100755
--- a/core/java/android/nfc/INfcSecureElement.aidl
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@
package android.nfc;
+import android.os.Bundle;
+
/**
* {@hide}
*/
-interface INfcSecureElement {
- int openSecureElementConnection();
- int closeSecureElementConnection(int nativeHandle);
- byte[] exchangeAPDU(int nativeHandle, in byte[] data);
- int[] getSecureElementTechList(int nativeHandle);
- byte[] getSecureElementUid(int nativeHandle);
-}
\ No newline at end of file
+interface INfcAdapterExtras {
+ Bundle open(IBinder b);
+ Bundle close();
+ Bundle transceive(in byte[] data_in);
+ int getCardEmulationRoute();
+ void setCardEmulationRoute(int route);
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 8c56fda..4689804 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -157,31 +157,6 @@
public static final String EXTRA_ID = "android.nfc.extra.ID";
/**
- * Broadcast Action: a transaction with a secure element has been detected.
- * <p>
- * Always contains the extra field
- * {@link android.nfc.NfcAdapter#EXTRA_AID}
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TRANSACTION_DETECTED =
- "android.nfc.action.TRANSACTION_DETECTED";
-
- /**
- * Broadcast Action: an RF field ON has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_ON_DETECTED =
- "android.nfc.action.RF_FIELD_ON_DETECTED";
-
- /**
- * Broadcast Action: an RF Field OFF has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_OFF_DETECTED =
- "android.nfc.action.RF_FIELD_OFF_DETECTED";
-
- /**
* Broadcast Action: an adapter's state changed between enabled and disabled.
*
* The new value is stored in the extra EXTRA_NEW_BOOLEAN_STATE and just contains
@@ -201,15 +176,6 @@
public static final String EXTRA_NEW_BOOLEAN_STATE = "android.nfc.isEnabled";
/**
- * Mandatory byte array extra field in
- * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}.
- * <p>
- * Contains the AID of the applet involved in the transaction.
- * @hide
- */
- public static final String EXTRA_AID = "android.nfc.extra.AID";
-
- /**
* LLCP link status: The LLCP link is activated.
* @hide
*/
@@ -691,39 +657,14 @@
}
/**
- * Create an Nfc Secure Element Connection
* @hide
*/
- public NfcSecureElement createNfcSecureElementConnection() {
+ public INfcAdapterExtras getNfcAdapterExtrasInterface() {
try {
- return new NfcSecureElement(sService.getNfcSecureElementInterface());
+ return sService.getNfcAdapterExtrasInterface();
} catch (RemoteException e) {
- Log.e(TAG, "createNfcSecureElementConnection failed", e);
+ attemptDeadServiceRecovery(e);
return null;
}
}
-
- /**
- * To change the Secure Element Card Emulation state (ON/OFF)
- * @hide
- */
- public void changeNfcSecureElementCardEmulationState(boolean state)
- {
- int seId = 11259375;
- if(state){
- /* Enable card emulation */
- try {
- sService.selectSecureElement(seId);
- } catch (RemoteException e) {
- Log.e(TAG, "Enable card emulation failed", e);
- }
- }else{
- /* Disable card emulation */
- try {
- sService.deselectSecureElement();
- } catch (RemoteException e) {
- Log.e(TAG, " card emulation failed", e);
- }
- }
- }
}
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
deleted file mode 100755
index 3b5f39e..0000000
--- a/core/java/android/nfc/NfcSecureElement.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.tech.TagTechnology;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//import android.util.Log;
-
-/**
- * This class provides the primary API for managing all aspects Secure Element.
- * Get an instance of this class by calling
- * Context.getSystemService(Context.NFC_SERVICE).
- * @hide
- */
-public final class NfcSecureElement {
-
- private static final String TAG = "NfcSecureElement";
-
- private INfcSecureElement mService;
-
-
- /**
- * @hide
- */
- public NfcSecureElement(INfcSecureElement mSecureElementService) {
- mService = mSecureElementService;
- }
-
- public int openSecureElementConnection(String seType) throws IOException {
- if (seType.equals("SmartMX")) {
- try {
- int handle = mService.openSecureElementConnection();
- // Handle potential errors
- if (handle != 0) {
- return handle;
- } else {
- throw new IOException("SmartMX connection not allowed");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e);
- return 0;
- }
-
- } else if (seType.equals("UICC")) {
- return 0;
- } else {
- throw new IOException("Wrong Secure Element type");
- }
- }
-
-
- public byte [] exchangeAPDU(int handle,byte [] data) throws IOException {
-
-
- // Perform exchange APDU
- try {
- byte[] response = mService.exchangeAPDU(handle, data);
- // Handle potential errors
- if (response == null) {
- throw new IOException("Exchange APDU failed");
- }
- return response;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in exchangeAPDU(): ", e);
- return null;
- }
- }
-
- public void closeSecureElementConnection(int handle) throws IOException {
-
- try {
- int status = mService.closeSecureElementConnection(handle);
- // Handle potential errors
- if (ErrorCodes.isError(status)) {
- throw new IOException("Error during the conection close");
- };
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in closeSecureElement(): ", e);
- }
- }
-
-
- /**
- * Returns target type. constants.
- *
- * @return Secure Element technology type. The possible values are defined in
- * {@link TagTechnology}
- *
- */
- public int[] getSecureElementTechList(int handle) throws IOException {
- try {
- return mService.getSecureElementTechList(handle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
- /**
- * Returns Secure Element UID.
- *
- * @return Secure Element UID.
- */
- public byte[] getSecureElementUid(int handle) throws IOException {
-
- byte[] uid = null;
- try {
- uid = mService.getSecureElementUid(handle);
- // Handle potential errors
- if (uid == null) {
- throw new IOException("Get Secure Element UID failed");
- }
- return uid;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
-}
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 62f66b6..d2d2557 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1723,6 +1723,14 @@
public static final String TYPE = "type";
+ public static final String INACTIVE_TIMER = "inactivetimer";
+
+ // Only if enabled try Data Connection.
+ public static final String ENABLED = "enabled";
+
+ // Rules apply based on class.
+ public static final String CLASS = "class";
+
/**
* The protocol to be used to connect to this APN.
*
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a53c6d0..7d6e18f 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1175,10 +1175,11 @@
}
}
mSurfaceHolder.mSurfaceLock.lock();
- // Make surface invalid.
- //mSurfaceHolder.mSurface.copyFrom(mSurface);
- mSurfaceHolder.mSurface = new Surface();
- mSurfaceHolder.mSurfaceLock.unlock();
+ try {
+ mSurfaceHolder.mSurface = new Surface();
+ } finally {
+ mSurfaceHolder.mSurfaceLock.unlock();
+ }
}
}
diff --git a/core/java/com/google/android/mms/pdu/PduParser.java b/core/java/com/google/android/mms/pdu/PduParser.java
old mode 100644
new mode 100755
index 8edfe52..3f185aa
--- a/core/java/com/google/android/mms/pdu/PduParser.java
+++ b/core/java/com/google/android/mms/pdu/PduParser.java
@@ -29,6 +29,8 @@
import java.util.Arrays;
import java.util.HashMap;
+import android.content.res.Resources;
+
public class PduParser {
/**
* The next are WAP values defined in WSP specification.
@@ -1557,43 +1559,55 @@
* Attachment = <Octet 129>
* Inline = <Octet 130>
*/
- int len = parseValueLength(pduDataStream);
- pduDataStream.mark(1);
- int thisStartPos = pduDataStream.available();
- int thisEndPos = 0;
- int value = pduDataStream.read();
- if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
- part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
- } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
- part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
- } else if (value == PduPart.P_DISPOSITION_INLINE) {
- part.setContentDisposition(PduPart.DISPOSITION_INLINE);
- } else {
- pduDataStream.reset();
- /* Token-text */
- part.setContentDisposition(parseWapString(pduDataStream, TYPE_TEXT_STRING));
- }
+ /*
+ * some carrier mmsc servers do not support content_disposition
+ * field correctly
+ */
+ boolean contentDisposition = Resources.getSystem().getBoolean(com
+ .android.internal.R.bool.config_mms_content_disposition_support);
- /* get filename parameter and skip other parameters */
- thisEndPos = pduDataStream.available();
- if (thisStartPos - thisEndPos < len) {
- value = pduDataStream.read();
- if (value == PduPart.P_FILENAME) { //filename is text-string
- part.setFilename(parseWapString(pduDataStream, TYPE_TEXT_STRING));
+ if (contentDisposition) {
+ int len = parseValueLength(pduDataStream);
+ pduDataStream.mark(1);
+ int thisStartPos = pduDataStream.available();
+ int thisEndPos = 0;
+ int value = pduDataStream.read();
+
+ if (value == PduPart.P_DISPOSITION_FROM_DATA ) {
+ part.setContentDisposition(PduPart.DISPOSITION_FROM_DATA);
+ } else if (value == PduPart.P_DISPOSITION_ATTACHMENT) {
+ part.setContentDisposition(PduPart.DISPOSITION_ATTACHMENT);
+ } else if (value == PduPart.P_DISPOSITION_INLINE) {
+ part.setContentDisposition(PduPart.DISPOSITION_INLINE);
+ } else {
+ pduDataStream.reset();
+ /* Token-text */
+ part.setContentDisposition(parseWapString(pduDataStream
+ , TYPE_TEXT_STRING));
}
- /* skip other parameters */
+ /* get filename parameter and skip other parameters */
thisEndPos = pduDataStream.available();
if (thisStartPos - thisEndPos < len) {
- int last = len - (thisStartPos - thisEndPos);
- byte[] temp = new byte[last];
- pduDataStream.read(temp, 0, last);
- }
- }
+ value = pduDataStream.read();
+ if (value == PduPart.P_FILENAME) { //filename is text-string
+ part.setFilename(parseWapString(pduDataStream
+ , TYPE_TEXT_STRING));
+ }
- tempPos = pduDataStream.available();
- lastLen = length - (startPos - tempPos);
+ /* skip other parameters */
+ thisEndPos = pduDataStream.available();
+ if (thisStartPos - thisEndPos < len) {
+ int last = len - (thisStartPos - thisEndPos);
+ byte[] temp = new byte[last];
+ pduDataStream.read(temp, 0, last);
+ }
+ }
+
+ tempPos = pduDataStream.available();
+ lastLen = length - (startPos - tempPos);
+ }
break;
default:
if (LOCAL_LOGV) {
diff --git a/core/java/com/google/android/mms/util/PduCache.java b/core/java/com/google/android/mms/util/PduCache.java
index 7c3fad7..866ca1e 100644
--- a/core/java/com/google/android/mms/util/PduCache.java
+++ b/core/java/com/google/android/mms/util/PduCache.java
@@ -235,7 +235,7 @@
}
private void removeFromMessageBoxes(Uri key, PduCacheEntry entry) {
- HashSet<Uri> msgBox = mThreads.get(entry.getMessageBox());
+ HashSet<Uri> msgBox = mThreads.get(Long.valueOf(entry.getMessageBox()));
if (msgBox != null) {
msgBox.remove(key);
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 9e00a7d..09a5fd41 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -680,6 +680,15 @@
static void android_os_Binder_restoreCallingIdentity(JNIEnv* env, jobject clazz, jlong token)
{
+ // XXX temporary sanity check to debug crashes.
+ int uid = (int)(token>>32);
+ if (uid > 0 && uid < 999) {
+ // In Android currently there are no uids in this range.
+ char buf[128];
+ sprintf(buf, "Restoring bad calling ident: 0x%Lx", token);
+ jniThrowException(env, "java/lang/IllegalStateException", buf);
+ return;
+ }
IPCThreadState::self()->restoreCallingIdentity(token);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c684e7e..0c9a2ef 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -91,10 +91,15 @@
<protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
<protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.AID_SELECTED" />
+
<protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
<protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
<protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
+
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
<!-- ====================================== -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
old mode 100644
new mode 100755
index e46eecc..2037191
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -51,6 +51,11 @@
manager will disable alpha trasformation in animations where not
strictly needed. -->
<bool name="config_sf_limitedAlpha">false</bool>
+
+ <!-- Default value used to block data calls if ims is not
+ connected. If you use the ims apn DCT will block
+ any other apn from connecting until ims apn is connected-->
+ <bool name="ImsConnectedDefaultValue">false</bool>
<!-- Flag indicating whether the surface flinger is inefficient
at performing a blur. Used by parts of the UI to turn off
@@ -133,6 +138,9 @@
<item>"mobile_mms,2,0,2"</item>
<item>"mobile_supl,3,0,2"</item>
<item>"mobile_hipri,5,0,3"</item>
+ <item>"mobile_fota,10,0,2"</item>
+ <item>"mobile_ims,11,0,2"</item>
+ <item>"mobile_cbs,12,0,2"</item>
</string-array>
<!-- This string array should be overridden by the device to present a list of radio
@@ -563,4 +571,27 @@
<!-- The VoiceMail default value is displayed to my own number if it is true -->
<bool name="config_telephony_use_own_number_for_voicemail">false</bool>
+
+ <!-- If this value is true, Sms encoded as octet is decoded by utf8 decoder.
+ If false, decoded by Latin decoder. -->
+ <bool name="config_sms_utf8_support">false</bool>
+
+ <!-- If this value is true, The mms content-disposition field is supported correctly.
+ If false, Content-disposition fragments are ignored -->
+ <bool name="config_mms_content_disposition_support">true</bool>
+
+ <!-- If this value is true, the carrier supports sms delivery reports.
+ If false, sms delivery reports are not supported and the preference
+ option to enable/disable delivery reports is removed in the Messaging app. -->
+ <bool name="config_sms_delivery_reports_support">true</bool>
+
+ <!-- If this value is true, the carrier supports mms delivery reports.
+ If false, mms delivery reports are not supported and the preference
+ option to enable/disable delivery reports is removed in the Messaging app. -->
+ <bool name="config_mms_delivery_reports_support">true</bool>
+
+ <!-- If this value is true, the carrier supports mms read reports.
+ If false, mms read reports are not supported and the preference
+ option to enable/disable read reports is removed in the Messaging app. -->
+ <bool name="config_mms_read_reports_support">true</bool>
</resources>
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 498c7b8..2caf211 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -220,40 +220,58 @@
return ERROR_ALREADY_CONNECTED;
}
- struct hostent *ent = gethostbyname(server);
- if (ent == NULL) {
+ if (port < 0 || port > (int) USHRT_MAX) {
+ return UNKNOWN_ERROR;
+ }
+
+ char service[sizeof("65536")];
+ sprintf(service, "%d", port);
+ struct addrinfo hints, *ai;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+ hints.ai_socktype = SOCK_STREAM;
+
+ int ret = getaddrinfo(server, service, &hints, &ai);
+ if (ret) {
return ERROR_UNKNOWN_HOST;
}
CHECK_EQ(mSocket, -1);
- mSocket = socket(AF_INET, SOCK_STREAM, 0);
-
- if (mSocket < 0) {
- return UNKNOWN_ERROR;
- }
-
- setReceiveTimeout(30); // Time out reads after 30 secs by default
mState = CONNECTING;
+ status_t res = -1;
+ struct addrinfo *tmp;
+ for (tmp = ai; tmp; tmp = tmp->ai_next) {
+ mSocket = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
+ if (mSocket < 0) {
+ continue;
+ }
- int s = mSocket;
+ setReceiveTimeout(30); // Time out reads after 30 secs by default.
- mLock.unlock();
+ int s = mSocket;
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
- memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+ mLock.unlock();
- status_t res = MyConnect(s, (const struct sockaddr *)&addr, sizeof(addr));
+ res = MyConnect(s, tmp->ai_addr, tmp->ai_addrlen);
- mLock.lock();
+ mLock.lock();
- if (mState != CONNECTING) {
- return UNKNOWN_ERROR;
+ if (mState != CONNECTING) {
+ close(s);
+ freeaddrinfo(ai);
+ return UNKNOWN_ERROR;
+ }
+
+ if (res == OK) {
+ break;
+ }
+
+ close(s);
}
+ freeaddrinfo(ai);
+
if (res != OK) {
close(mSocket);
mSocket = -1;
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index 7802efd..81c6167 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -22,11 +22,6 @@
SkOmxPixelRef.cpp \
StreamSource.cpp
-
-# add external/skia/src/images/SkImageDecoder_libjpeg.cpp
-LOCAL_SRC_FILES += \
- ../../../../../external/skia/src/images/SkImageDecoder_libjpeg.cpp
-
LOCAL_SHARED_LIBRARIES := \
libcutils \
libskia \
diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk
new file mode 100644
index 0000000..131d898
--- /dev/null
+++ b/nfc-extras/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE:= com.android.nfc_extras
+
+include $(BUILD_JAVA_LIBRARY)
+
+# put the classes.jar, with full class files instead of classes.dex inside, into the dist directory
+$(call dist-for-goals, droidcore, $(full_classes_jar):com.android.nfc_extras.jar)
diff --git a/nfc-extras/com.android.nfc_extras.xml b/nfc-extras/com.android.nfc_extras.xml
new file mode 100644
index 0000000..370145d
--- /dev/null
+++ b/nfc-extras/com.android.nfc_extras.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<permissions>
+ <library name="com.android.nfc_extras"
+ file="/system/framework/com.android.nfc_extras.jar" />
+</permissions>
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
new file mode 100644
index 0000000..cf38bd1
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.nfc_extras;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Provides additional methods on an {@link NfcAdapter} for Card Emulation
+ * and management of {@link NfcExecutionEnvironment}'s.
+ *
+ * There is a 1-1 relationship between an {@link NfcAdapterExtras} object and
+ * a {@link NfcAdapter} object.
+ */
+public final class NfcAdapterExtras {
+ private static final String TAG = "NfcAdapterExtras";
+
+ /**
+ * Broadcast Action: an RF field ON has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_ON_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
+
+ /**
+ * Broadcast Action: an RF field OFF has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_OFF_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
+
+ // protected by NfcAdapterExtras.class, and final after first construction
+ private static INfcAdapterExtras sService;
+ private static boolean sIsInitialized = false;
+ private static NfcAdapterExtras sSingleton;
+ private static NfcExecutionEnvironment sEmbeddedEe;
+ private static CardEmulationRoute sRouteOff;
+ private static CardEmulationRoute sRouteOnWhenScreenOn;
+
+ /**
+ * Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param adapter a {@link NfcAdapter}, must not be null
+ * @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter}
+ */
+ public static NfcAdapterExtras get(NfcAdapter adapter) {
+ synchronized(NfcAdapterExtras.class) {
+ if (!sIsInitialized) {
+ sIsInitialized = true;
+ sService = adapter.getNfcAdapterExtrasInterface();
+ sEmbeddedEe = new NfcExecutionEnvironment(sService);
+ sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
+ sRouteOnWhenScreenOn = new CardEmulationRoute(
+ CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
+ sSingleton = new NfcAdapterExtras();
+ }
+ return sSingleton;
+ }
+ }
+
+ private NfcAdapterExtras() {}
+
+ /**
+ * Immutable data class that describes a card emulation route.
+ */
+ public final static class CardEmulationRoute {
+ /**
+ * Card Emulation is turned off on this NfcAdapter.
+ * <p>This is the default routing state after boot.
+ */
+ public static final int ROUTE_OFF = 1;
+
+ /**
+ * Card Emulation is routed to {@link #nfcEe} only when the screen is on,
+ * otherwise it is turned off.
+ */
+ public static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
+
+ /**
+ * A route such as {@link #ROUTE_OFF} or {@link #ROUTE_ON_WHEN_SCREEN_ON}.
+ */
+ public final int route;
+
+ /**
+ * The {@link NFcExecutionEnvironment} that is Card Emulation is routed to.
+ * <p>null if {@link #route} is {@link #ROUTE_OFF}, otherwise not null.
+ */
+ public final NfcExecutionEnvironment nfcEe;
+
+ public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) {
+ if (route == ROUTE_OFF && nfcEe != null) {
+ throw new IllegalArgumentException("must not specifiy a NFC-EE with ROUTE_OFF");
+ } else if (route != ROUTE_OFF && nfcEe == null) {
+ throw new IllegalArgumentException("must specifiy a NFC-EE for this route");
+ }
+ this.route = route;
+ this.nfcEe = nfcEe;
+ }
+ }
+
+ /**
+ * Get the routing state of this NFC EE.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return
+ */
+ public CardEmulationRoute getCardEmulationRoute() {
+ try {
+ int route = sService.getCardEmulationRoute();
+ return route == CardEmulationRoute.ROUTE_OFF ?
+ sRouteOff :
+ sRouteOnWhenScreenOn;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return sRouteOff;
+ }
+ }
+
+ /**
+ * Set the routing state of this NFC EE.
+ *
+ * <p>This routing state is not persisted across reboot.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param route a {@link #CardEmulationRoute}
+ */
+ public void setCardEmulationRoute(CardEmulationRoute route) {
+ try {
+ sService.setCardEmulationRoute(route.route);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ /**
+ * Get the {@link NfcExecutionEnvironment} that is embedded with the
+ * {@link NFcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE
+ */
+ public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() {
+ return sEmbeddedEe;
+ }
+}
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
new file mode 100644
index 0000000..3efe492
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.nfc_extras;
+
+import java.io.IOException;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class NfcExecutionEnvironment {
+ private final INfcAdapterExtras mService;
+
+ /**
+ * Broadcast Action: An ISO-DEP AID was selected.
+ *
+ * <p>This happens as the result of a 'SELECT AID' command from an
+ * external NFC reader/writer.
+ *
+ * <p>Always contains the extra field {@link #EXTRA_AID}
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_AID_SELECTED =
+ "com.android.nfc_extras.action.AID_SELECTED";
+
+ /**
+ * Mandatory byte array extra field in {@link #ACTION_AID_SELECTED}.
+ *
+ * <p>Contains the AID selected.
+ * @hide
+ */
+ public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
+
+ NfcExecutionEnvironment(INfcAdapterExtras service) {
+ mService = service;
+ }
+
+ /**
+ * Open the NFC Execution Environment on its contact interface.
+ *
+ * <p>Only one process may open the secure element at a time. If it is
+ * already open, an {@link IOException} is thrown.
+ *
+ * <p>All other NFC functionality is disabled while the NFC-EE is open
+ * on its contact interface, so make sure to call {@link #close} once complete.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void open() throws IOException {
+ try {
+ Bundle b = mService.open(new Binder());
+ throwBundle(b);
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Close the NFC Execution Environment on its contact interface.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void close() throws IOException {
+ try {
+ throwBundle(mService.close());
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Send raw commands to the NFC-EE and receive the response.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is not open, or some other error occurs
+ */
+ public byte[] transceive(byte[] in) throws IOException {
+ Bundle b;
+ try {
+ b = mService.transceive(in);
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
+ throwBundle(b);
+ return b.getByteArray("out");
+ }
+
+ private static void throwBundle(Bundle b) throws IOException {
+ if (b.getInt("e") == -1) {
+ throw new IOException(b.getString("m"));
+ }
+ }
+}
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4g.png
new file mode 100644
index 0000000..84ac927
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 0273a4c..826ac92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -246,6 +246,16 @@
R.drawable.stat_sys_data_fully_out_3g,
R.drawable.stat_sys_data_fully_inandout_3g }
};
+ private static final int[][] sDataNetType_4g = {
+ { R.drawable.stat_sys_data_connected_4g,
+ R.drawable.stat_sys_data_in_4g,
+ R.drawable.stat_sys_data_out_4g,
+ R.drawable.stat_sys_data_inandout_4g },
+ { R.drawable.stat_sys_data_fully_connected_4g,
+ R.drawable.stat_sys_data_fully_in_4g,
+ R.drawable.stat_sys_data_fully_out_4g,
+ R.drawable.stat_sys_data_fully_inandout_4g }
+ };
private static final int[][] sDataNetType_e = {
{ R.drawable.stat_sys_data_connected_e,
R.drawable.stat_sys_data_in_e,
@@ -670,9 +680,12 @@
case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
mDataIconList = sDataNetType_3g[mInetCondition];
break;
- // TODO - add support for NETWORK_TYPE_LTE and NETWORK_TYPE_EHRPD
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ mDataIconList = sDataNetType_4g[mInetCondition];
+ break;
default:
mDataIconList = sDataNetType_g[mInetCondition];
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index a693e60..70a78df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -427,10 +427,14 @@
case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_3g;
break;
- // TODO - add support for NETWORK_TYPE_LTE and NETWORK_TYPE_EHRPD
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
+ mDataTypeIconId = R.drawable.stat_sys_signal_4g;
+ break;
default:
mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_gprs;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 29d35e3..9093b3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -124,5 +124,18 @@
R.drawable.stat_sys_data_fully_inandout_1x }
};
+ // LTE and eHRPD
+ static final int[][] DATA_4G = {
+ { R.drawable.stat_sys_data_connected_4g,
+ R.drawable.stat_sys_data_in_4g,
+ R.drawable.stat_sys_data_out_4g,
+ R.drawable.stat_sys_data_inandout_4g },
+ { R.drawable.stat_sys_data_fully_connected_4g,
+ R.drawable.stat_sys_data_fully_in_4g,
+ R.drawable.stat_sys_data_fully_out_4g,
+ R.drawable.stat_sys_data_fully_inandout_4g }
+ };
+
+
}
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index fcb4c23..f170cb7 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -696,15 +696,10 @@
// TODO - move this into the MobileDataStateTracker
int usedNetworkType = networkType;
if(networkType == ConnectivityManager.TYPE_MOBILE) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
- TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ usedNetworkType = convertFeatureToNetworkType(feature);
+ if (usedNetworkType < 0) {
+ Slog.e(TAG, "Can't match any netTracker!");
+ usedNetworkType = networkType;
}
}
NetworkStateTracker network = mNetTrackers[usedNetworkType];
@@ -848,15 +843,9 @@
// TODO - move to MobileDataStateTracker
int usedNetworkType = networkType;
if (networkType == ConnectivityManager.TYPE_MOBILE) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
- TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
- } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
- usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ usedNetworkType = convertFeatureToNetworkType(feature);
+ if (usedNetworkType < 0) {
+ usedNetworkType = networkType;
}
}
tracker = mNetTrackers[usedNetworkType];
@@ -2179,4 +2168,24 @@
private void loge(String s) {
Slog.e(TAG, s);
}
+ int convertFeatureToNetworkType(String feature){
+ int networkType = -1;
+ if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_MMS;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_SUPL;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
+ TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_DUN;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_FOTA;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_IMS;
+ } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
+ networkType = ConnectivityManager.TYPE_MOBILE_CBS;
+ }
+ return networkType;
+ }
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 290f2c1..ba05837 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -91,6 +91,12 @@
public static final int RADIO_TECHNOLOGY_HSPA = 11;
/** @hide */
public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
+ /** @hide */
+ public static final int RADIO_TECHNOLOGY_EHRPD = 13;
+ /** @hide */
+ public static final int RADIO_TECHNOLOGY_LTE = 14;
+ /** @hide */
+ public static final int RADIO_TECHNOLOGY_HSPAP = 15;
/**
* Available registration states for GSM, UMTS and CDMA.
@@ -424,6 +430,15 @@
case 12:
radioTechnology = "EvDo rev. B";
break;
+ case 13:
+ radioTechnology = "eHRPD";
+ break;
+ case 14:
+ radioTechnology = "LTE";
+ break;
+ case 15:
+ radioTechnology = "HSPAP";
+ break;
default:
Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
break;
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
new file mode 100644
index 0000000..bd1bc1d
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/ApnContext.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.app.PendingIntent;
+
+import android.util.Log;
+import java.util.ArrayList;
+import com.android.internal.telephony.gsm.GsmDataConnection;
+
+/**
+ * Maintain the Apn context
+ */
+public class ApnContext {
+
+ public static final int PENDING_ACTION_NONE = 1;
+ public static final int PENDING_ACTION_RECONNECT = 2;
+ public static final int PENDING_ACTION_APN_DISABLE = 3;
+ public final String LOG_TAG;
+
+ int pendingAction;
+
+ protected static final boolean DBG = true;
+
+ String mApnType;
+
+ DataConnectionTracker.State mState;
+
+ ArrayList<ApnSetting> mWaitingApns = null;
+
+ private int mWaitingApnsPermanentFailureCountDown = 0;
+
+ ApnSetting mApnSetting;
+
+ GsmDataConnection mDataConnection;
+
+ String mReason;
+
+ PendingIntent mReconnectIntent;
+
+ public ApnContext(String apnType, String logTag) {
+ mApnType = apnType;
+ mState = DataConnectionTracker.State.IDLE;
+ setReason(Phone.REASON_DATA_ENABLED);
+ pendingAction = PENDING_ACTION_NONE;
+ LOG_TAG = logTag;
+ }
+
+ public int getPendingAction() {
+ return pendingAction;
+ }
+
+ public void setPendingAction(int pa) {
+ pendingAction = pa;
+ }
+
+ public int getPermFailCount() {
+ return mWaitingApnsPermanentFailureCountDown;
+ }
+
+ public void decPermFailCount() {
+ mWaitingApnsPermanentFailureCountDown--;
+ }
+
+ public String getApnType() {
+ return mApnType;
+ }
+
+ public GsmDataConnection getDataConnection() {
+ return mDataConnection;
+ }
+
+ public void setDataConnection(GsmDataConnection dataConnection) {
+ mDataConnection = dataConnection;
+ }
+
+ public ApnSetting getApnSetting() {
+ return mApnSetting;
+ }
+
+ public void setApnSetting(ApnSetting apnSetting) {
+ mApnSetting = apnSetting;
+ }
+
+ public void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
+ mWaitingApns = waitingApns;
+ }
+
+ public ApnSetting getNextApn() {
+ ArrayList<ApnSetting> list = mWaitingApns;
+ ApnSetting apn = null;
+
+ if (list != null) {
+ if (!list.isEmpty()) {
+ apn = list.get(0);
+ }
+ }
+ return apn;
+ }
+
+ public void removeNextApn() {
+ if ((mWaitingApns != null) && (!mWaitingApns.isEmpty())) {
+ mWaitingApns.remove(0);
+ }
+ }
+
+ public ArrayList<ApnSetting> getWaitingApns() {
+ return mWaitingApns;
+ }
+
+ public void setState(DataConnectionTracker.State s) {
+ if (DBG)
+ log("setState: " + s + " for type " + mApnType + ", previous state:" + mState);
+
+ mState = s;
+
+ if (mState == DataConnectionTracker.State.FAILED) {
+ if (mWaitingApns != null)
+ mWaitingApns.clear(); // when teardown the connection and set to IDLE
+ }
+ }
+
+ public DataConnectionTracker.State getState() {
+ return mState;
+ }
+
+ public void setReason(String reason) {
+ if (DBG)
+ log("set reason as " + reason + ", for type " + mApnType + ",current state " + mState);
+ mReason = reason;
+ }
+
+ public String getReason() {
+ return mReason;
+ }
+
+ public void setReconnectIntent(PendingIntent intent) {
+ if (DBG)
+ log("set ReconnectIntent for type " + mApnType);
+ mReconnectIntent = intent;
+ }
+
+ public PendingIntent getReconnectIntent() {
+ return mReconnectIntent;
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "[ApnContext] " + s);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 9b19600..0fc81b0 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -34,6 +34,9 @@
//***** Instance Variables
protected Context mContext;
protected RadioState mState = RadioState.RADIO_UNAVAILABLE;
+ protected RadioState mSimState = RadioState.RADIO_UNAVAILABLE;
+ protected RadioState mRuimState = RadioState.RADIO_UNAVAILABLE;
+ protected RadioState mNvState = RadioState.RADIO_UNAVAILABLE;
protected Object mStateMonitor = new Object();
protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList();
@@ -105,6 +108,18 @@
return mState;
}
+ public RadioState getSimState() {
+ return mSimState;
+ }
+
+ public RadioState getRuimState() {
+ return mRuimState;
+ }
+
+ public RadioState getNvState() {
+ return mNvState;
+ }
+
public void registerForRadioStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
@@ -200,7 +215,7 @@
synchronized (mStateMonitor) {
mSIMReadyRegistrants.add(r);
- if (mState.isSIMReady()) {
+ if (mSimState.isSIMReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
@@ -219,7 +234,7 @@
synchronized (mStateMonitor) {
mRUIMReadyRegistrants.add(r);
- if (mState.isRUIMReady()) {
+ if (mRuimState.isRUIMReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
@@ -238,7 +253,7 @@
synchronized (mStateMonitor) {
mNVReadyRegistrants.add(r);
- if (mState.isNVReady()) {
+ if (mNvState.isNVReady()) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
@@ -256,7 +271,7 @@
synchronized (mStateMonitor) {
mSIMLockedRegistrants.add(r);
- if (mState == RadioState.SIM_LOCKED_OR_ABSENT) {
+ if (mSimState == RadioState.SIM_LOCKED_OR_ABSENT) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
@@ -274,7 +289,7 @@
synchronized (mStateMonitor) {
mRUIMLockedRegistrants.add(r);
- if (mState == RadioState.RUIM_LOCKED_OR_ABSENT) {
+ if (mRuimState == RadioState.RUIM_LOCKED_OR_ABSENT) {
r.notifyRegistrant(new AsyncResult(null, null, null));
}
}
@@ -653,6 +668,22 @@
return;
}
+ // FIXME: Use Constants or Enums
+ if(mState.getType() == 0) {
+ mSimState = mState;
+ mRuimState = mState;
+ mNvState = mState;
+ }
+ else if (mState.getType() == 1) {
+ mSimState = mState;
+ }
+ else if (mState.getType() == 2) {
+ mRuimState = mState;
+ }
+ else if (mState.getType() == 3) {
+ mNvState = mState;
+ }
+
mRadioStateChangedRegistrants.notifyRegistrants();
if (mState.isAvailable() && !oldState.isAvailable()) {
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
index 9619a66..31f9e18 100644
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ b/telephony/java/com/android/internal/telephony/CallTracker.java
@@ -119,6 +119,10 @@
//***** Overridden from Handler
public abstract void handleMessage (Message msg);
+ public abstract void registerForVoiceCallStarted(Handler h, int what, Object obj);
+ public abstract void unregisterForVoiceCallStarted(Handler h);
+ public abstract void registerForVoiceCallEnded(Handler h, int what, Object obj);
+ public abstract void unregisterForVoiceCallEnded(Handler h);
protected abstract void log(String msg);
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index ad21a18..9e1e0c6 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -20,25 +20,28 @@
import android.os.Message;
import android.os.Handler;
+import android.os.SystemProperties;
/**
* {@hide}
*/
public interface CommandsInterface {
+ static final boolean LTE_AVAILABLE_ON_CDMA =
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
enum RadioState {
- RADIO_OFF, /* Radio explicitly powered off (e.g. CFUN=0) */
- RADIO_UNAVAILABLE, /* Radio unavailable (e.g. resetting or not booted) */
- SIM_NOT_READY, /* Radio is on, but the SIM interface is not ready */
- SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network
- personalization, or SIM absent */
- SIM_READY, /* Radio is on and SIM interface is available */
- RUIM_NOT_READY, /* Radio is on, but the RUIM interface is not ready */
- RUIM_READY, /* Radio is on and the RUIM interface is available */
- RUIM_LOCKED_OR_ABSENT, /* RUIM PIN locked, PUK required, network
- personalization locked, or RUIM absent */
- NV_NOT_READY, /* Radio is on, but the NV interface is not available */
- NV_READY; /* Radio is on and the NV interface is available */
+ RADIO_OFF(0), /* Radio explictly powered off (eg CFUN=0) */
+ RADIO_UNAVAILABLE(0), /* Radio unavailable (eg, resetting or not booted) */
+ SIM_NOT_READY(1), /* Radio is on, but the SIM interface is not ready */
+ SIM_LOCKED_OR_ABSENT(1), /* SIM PIN locked, PUK required, network
+ personalization, or SIM absent */
+ SIM_READY(1), /* Radio is on and SIM interface is available */
+ RUIM_NOT_READY(2), /* Radio is on, but the RUIM interface is not ready */
+ RUIM_READY(2), /* Radio is on and the RUIM interface is available */
+ RUIM_LOCKED_OR_ABSENT(2), /* RUIM PIN locked, PUK required, network
+ personalization locked, or RUIM absent */
+ NV_NOT_READY(3), /* Radio is on, but the NV interface is not available */
+ NV_READY(3); /* Radio is on and the NV interface is available */
public boolean isOn() /* and available...*/ {
return this == SIM_NOT_READY
@@ -50,6 +53,14 @@
|| this == NV_NOT_READY
|| this == NV_READY;
}
+ private int stateType;
+ private RadioState (int type) {
+ stateType = type;
+ }
+
+ public int getType() {
+ return stateType;
+ }
public boolean isAvailable() {
return this != RADIO_UNAVAILABLE;
@@ -68,17 +79,25 @@
}
public boolean isGsm() {
- return this == SIM_NOT_READY
- || this == SIM_LOCKED_OR_ABSENT
- || this == SIM_READY;
+ if (LTE_AVAILABLE_ON_CDMA) {
+ return false;
+ } else {
+ return this == SIM_NOT_READY
+ || this == SIM_LOCKED_OR_ABSENT
+ || this == SIM_READY;
+ }
}
public boolean isCdma() {
- return this == RUIM_NOT_READY
- || this == RUIM_READY
- || this == RUIM_LOCKED_OR_ABSENT
- || this == NV_NOT_READY
- || this == NV_READY;
+ if (LTE_AVAILABLE_ON_CDMA) {
+ return true;
+ } else {
+ return this == RUIM_NOT_READY
+ || this == RUIM_READY
+ || this == RUIM_LOCKED_OR_ABSENT
+ || this == NV_NOT_READY
+ || this == NV_READY;
+ }
}
}
@@ -153,6 +172,9 @@
//***** Methods
RadioState getRadioState();
+ RadioState getSimState();
+ RadioState getRuimState();
+ RadioState getNvState();
/**
* Fires on any RadioState transition
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 89513fd..b5578c3 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -219,10 +219,9 @@
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
- protected int mId;
+ protected ApnSetting mApn;
protected int mTag;
protected PhoneBase phone;
- protected RetryManager mRetryMgr;
protected int cid;
protected LinkProperties mLinkProperties = new LinkProperties();
protected LinkCapabilities mCapabilities = new LinkCapabilities();
@@ -244,10 +243,11 @@
//***** Constructor
- protected DataConnection(PhoneBase phone, String name, RetryManager rm) {
+ protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
super(name);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
+ mId = id;
mRetryMgr = rm;
this.cid = -1;
clearSettings();
@@ -342,21 +342,100 @@
clearSettings();
}
- public RetryManager getRetryMgr() {
- return mRetryMgr;
+ /*
+ * **************************************************************************
+ * Begin Members and methods owned by DataConnectionTracker but stored
+ * in a DataConnection because there is one per connection.
+ * **************************************************************************
+ */
+
+ /*
+ * The id is owned by DataConnectionTracker.
+ */
+ private int mId;
+
+ /**
+ * Get the DataConnection ID
+ */
+ public int getDataConnectionId() {
+ return mId;
}
+ /*
+ * The retry manager is currently owned by the DataConnectionTracker but is stored
+ * in the DataConnection because there is one per connection. These methods
+ * should only be used by the DataConnectionTracker although someday the retrying
+ * maybe managed by the DataConnection itself and these methods could disappear.
+ */
+ private RetryManager mRetryMgr;
+
+ /**
+ * @return retry manager retryCount
+ */
+ public int getRetryCount() {
+ return mRetryMgr.getRetryCount();
+ }
+
+ /**
+ * @return retry manager retryTimer
+ */
+ public int getRetryTimer() {
+ return mRetryMgr.getRetryTimer();
+ }
+
+ /**
+ * increaseRetryCount of retry manager
+ */
+ public void increaseRetryCount() {
+ mRetryMgr.increaseRetryCount();
+ }
+
+ /**
+ * @return retry manager isRetryNeeded
+ */
+ public boolean isRetryNeeded() {
+ return mRetryMgr.isRetryNeeded();
+ }
+
+ /**
+ * resetRetryCount of retry manager
+ */
+ public void resetRetryCount() {
+ mRetryMgr.resetRetryCount();
+ }
+
+ /**
+ * set retryForeverUsingLasttimeout of retry manager
+ */
+ public void retryForeverUsingLastTimeout() {
+ mRetryMgr.retryForeverUsingLastTimeout();
+ }
+
+ /**
+ * @return retry manager isRetryForever
+ */
+ public boolean isRetryForever() {
+ return mRetryMgr.isRetryForever();
+ }
+
+ /*
+ * **************************************************************************
+ * End members owned by DataConnectionTracker
+ * **************************************************************************
+ */
+
/**
* Clear all settings called when entering mInactiveState.
*/
protected void clearSettings() {
if (DBG) log("clearSettings");
- this.createTime = -1;
- this.lastFailTime = -1;
- this.lastFailCause = FailCause.NONE;
+ createTime = -1;
+ lastFailTime = -1;
+ lastFailCause = FailCause.NONE;
mLinkProperties = new LinkProperties();
+ mApn = null;
}
/**
@@ -964,13 +1043,6 @@
}
/**
- * Get the DataConnection ID
- */
- public int getDataConnectionId() {
- return mId;
- }
-
- /**
* Return the LinkProperties for the connection.
*
* @return a copy of the LinkProperties, is never null.
@@ -1017,4 +1089,11 @@
public FailCause getLastFailCause() {
return lastFailCause;
}
+
+ /**
+ * @return the current ApnSetting
+ */
+ public ApnSetting getApn() {
+ return mApn;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 7f8485b..8a029f1 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -38,8 +38,11 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
+
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -97,14 +100,14 @@
protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12;
protected static final int EVENT_VOICE_CALL_STARTED = 14;
protected static final int EVENT_VOICE_CALL_ENDED = 15;
- protected static final int EVENT_GPRS_DETACHED = 19;
+ protected static final int EVENT_DATA_CONNECTION_DETACHED = 19;
protected static final int EVENT_LINK_STATE_CHANGED = 20;
protected static final int EVENT_ROAMING_ON = 21;
protected static final int EVENT_ROAMING_OFF = 22;
protected static final int EVENT_ENABLE_NEW_APN = 23;
protected static final int EVENT_RESTORE_DEFAULT_APN = 24;
protected static final int EVENT_DISCONNECT_DONE = 25;
- protected static final int EVENT_GPRS_ATTACHED = 26;
+ protected static final int EVENT_DATA_CONNECTION_ATTACHED = 26;
protected static final int EVENT_START_NETSTAT_POLL = 27;
protected static final int EVENT_START_RECOVERY = 28;
protected static final int EVENT_APN_CHANGED = 29;
@@ -117,8 +120,8 @@
protected static final int EVENT_RESTART_RADIO = 36;
protected static final int EVENT_SET_INTERNAL_DATA_ENABLE = 37;
protected static final int EVENT_RESET_DONE = 38;
-
public static final int CMD_SET_DATA_ENABLE = 39;
+ public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = 40;
/***** Constants *****/
@@ -128,7 +131,10 @@
protected static final int APN_SUPL_ID = 2;
protected static final int APN_DUN_ID = 3;
protected static final int APN_HIPRI_ID = 4;
- protected static final int APN_NUM_TYPES = 5;
+ protected static final int APN_IMS_ID = 5;
+ protected static final int APN_FOTA_ID = 6;
+ protected static final int APN_CBS_ID = 7;
+ protected static final int APN_NUM_TYPES = 8;
public static final int DISABLED = 0;
public static final int ENABLED = 1;
@@ -206,9 +212,6 @@
protected int mNoRecvPollCount = 0;
protected boolean mNetStatPollEnabled = false;
- /** Manage the behavior of data retry after failure (TODO: One per connection in the future?) */
- protected RetryManager mRetryMgr = new RetryManager();
-
// wifi connection status will be updated by sticky intent
protected boolean mIsWifiConnected = false;
@@ -242,9 +245,29 @@
protected HashMap<Integer, DataConnection> mDataConnections =
new HashMap<Integer, DataConnection>();
+ /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
+ protected HashMap<String, Integer> mApnToDataConnectionId =
+ new HashMap<String, Integer>();
+
+ /** Phone.APN_TYPE_* ===> ApnContext */
+ protected ConcurrentHashMap<String, ApnContext> mApnContexts;
+
/* Currently active APN */
protected ApnSetting mActiveApn;
+ /** allApns holds all apns */
+ protected ArrayList<ApnSetting> mAllApns = null;
+
+ /** preferred apn */
+ protected ApnSetting mPreferredApn = null;
+
+ /** Is packet service restricted by network */
+ protected boolean mIsPsRestricted = false;
+
+
+ /* Once disposed dont handle any messages */
+ protected boolean mIsDisposed = false;
+
protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
{
@Override
@@ -261,15 +284,8 @@
startNetStatPoll();
} else if (action.equals(getActionIntentReconnectAlarm())) {
log("Reconnect alarm. Previous state was " + mState);
+ onActionIntentReconnectAlarm(intent);
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (mState == State.FAILED) {
- Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 0; // tearDown is false
- msg.obj = reason;
- sendMessage(msg);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
final android.net.NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
@@ -287,6 +303,18 @@
}
};
+ protected void onActionIntentReconnectAlarm(Intent intent) {
+ String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
+ if (mState == State.FAILED) {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 0; // tearDown is false
+ msg.arg2 = 0;
+ msg.obj = reason;
+ sendMessage(msg);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ }
+
/**
* Default constructor
*/
@@ -320,6 +348,7 @@
}
public void dispose() {
+ mIsDisposed = true;
mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
}
@@ -333,23 +362,6 @@
return mActivity;
}
- public State getState() {
- return mState;
- }
-
- public String getStateInString() {
- switch (mState) {
- case IDLE: return "IDLE";
- case INITING: return "INIT";
- case CONNECTING: return "CING";
- case SCANNING: return "SCAN";
- case CONNECTED: return "CNTD";
- case DISCONNECTING: return "DING";
- case FAILED: return "FAIL";
- default: return "ERRO";
- }
- }
-
/**
* @return the data connections
*/
@@ -360,9 +372,26 @@
public boolean isApnTypeActive(String type) {
// TODO: support simultaneous with List instead
+ if (Phone.APN_TYPE_DUN.equals(type)) {
+ ApnSetting dunApn = fetchDunApn();
+ if (dunApn != null) {
+ return ((mActiveApn != null) && (dunApn.toString().equals(mActiveApn.toString())));
+ }
+ }
return mActiveApn != null && mActiveApn.canHandleType(type);
}
+ protected ApnSetting fetchDunApn() {
+ Context c = mPhone.getContext();
+ String apnData = Settings.Secure.getString(c.getContentResolver(),
+ Settings.Secure.TETHER_DUN_APN);
+ ApnSetting dunSetting = ApnSetting.fromString(apnData);
+ if (dunSetting != null) return dunSetting;
+
+ apnData = c.getResources().getString(R.string.config_tether_apndata);
+ return ApnSetting.fromString(apnData);
+ }
+
public String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -374,17 +403,8 @@
return result;
}
- public String getActiveApnType() {
- String result;
- if (mActiveApn != null) {
- result = apnIdToType(mActiveApn.id);
- } else {
- result = null;
- }
- return result;
- }
-
- protected String getActiveApnString() {
+ /** TODO: See if we can remove */
+ public String getActiveApnString() {
String result = null;
if (mActiveApn != null) {
result = mActiveApn.apn;
@@ -392,17 +412,6 @@
return result;
}
- /**
- * The data connection is expected to be setup while device
- * 1. has Icc card
- * 2. registered for data service
- * 3. user doesn't explicitly disable data service
- * 4. wifi is not on
- *
- * @return false while no data connection if all above requirements are met.
- */
- public abstract boolean isDataConnectionAsDesired();
-
//The data roaming setting is now located in the shared preferences.
// See if the requested preference value is the same as that stored in
// the shared values. If it is not, then update it.
@@ -412,7 +421,7 @@
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
if (mPhone.getServiceState().getRoaming()) {
if (enabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
sendMessage(obtainMessage(EVENT_ROAMING_ON));
}
@@ -429,10 +438,19 @@
}
}
-
+ // abstract methods
protected abstract String getActionIntentReconnectAlarm();
+ protected abstract void startNetStatPoll();
+ protected abstract void stopNetStatPoll();
+ protected abstract void restartRadio();
+ protected abstract void log(String s);
+ protected abstract void loge(String s);
+ protected abstract boolean isDataAllowed();
+ protected abstract boolean isApnTypeAvailable(String type);
+ public abstract State getState(String apnType);
+ protected abstract void setState(State s);
+ protected abstract void gotoIdleAndNotifyDataConnection(String reason);
- // abstract handler methods
protected abstract boolean onTrySetupData(String reason);
protected abstract void onRoamingOff();
protected abstract void onRoamingOn();
@@ -440,10 +458,10 @@
protected abstract void onRadioOffOrNotAvailable();
protected abstract void onDataSetupComplete(AsyncResult ar);
protected abstract void onDisconnectDone(int connId, AsyncResult ar);
- protected abstract void onResetDone(AsyncResult ar);
protected abstract void onVoiceCallStarted();
protected abstract void onVoiceCallEnded();
- protected abstract void onCleanUpConnection(boolean tearDown, String reason);
+ protected abstract void onCleanUpConnection(boolean tearDown, int apnId, String reason);
+ protected abstract void onCleanUpAllConnections();
@Override
public void handleMessage(Message msg) {
@@ -463,7 +481,7 @@
case EVENT_ROAMING_OFF:
if (getDataOnRoamingEnabled() == false) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
}
onRoamingOff();
break;
@@ -498,19 +516,24 @@
onVoiceCallEnded();
break;
- case EVENT_CLEAN_UP_CONNECTION:
- boolean tearDown = (msg.arg1 == 0) ? false : true;
- onCleanUpConnection(tearDown, (String) msg.obj);
+ case EVENT_CLEAN_UP_ALL_CONNECTIONS: {
+ onCleanUpAllConnections();
break;
-
+ }
+ case EVENT_CLEAN_UP_CONNECTION: {
+ boolean tearDown = (msg.arg1 == 0) ? false : true;
+ onCleanUpConnection(tearDown, msg.arg2, (String) msg.obj);
+ break;
+ }
case EVENT_SET_INTERNAL_DATA_ENABLE: {
boolean enabled = (msg.arg1 == ENABLED) ? true : false;
onSetInternalDataEnabled(enabled);
break;
}
- case EVENT_RESET_DONE:
+ case EVENT_RESET_DONE: {
onResetDone((AsyncResult) msg.obj);
break;
+ }
case CMD_SET_DATA_ENABLE: {
log("CMD_SET_DATA_ENABLE msg=" + msg);
boolean enabled = (msg.arg1 == ENABLED) ? true : false;
@@ -536,16 +559,6 @@
return result;
}
- protected abstract void startNetStatPoll();
-
- protected abstract void stopNetStatPoll();
-
- protected abstract void restartRadio();
-
- protected abstract void log(String s);
-
- protected abstract void loge(String s);
-
protected int apnTypeToId(String type) {
if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
return APN_DEFAULT_ID;
@@ -557,6 +570,12 @@
return APN_DUN_ID;
} else if (TextUtils.equals(type, Phone.APN_TYPE_HIPRI)) {
return APN_HIPRI_ID;
+ } else if (TextUtils.equals(type, Phone.APN_TYPE_IMS)) {
+ return APN_IMS_ID;
+ } else if (TextUtils.equals(type, Phone.APN_TYPE_FOTA)) {
+ return APN_FOTA_ID;
+ } else if (TextUtils.equals(type, Phone.APN_TYPE_CBS)) {
+ return APN_CBS_ID;
} else {
return APN_INVALID_ID;
}
@@ -574,16 +593,18 @@
return Phone.APN_TYPE_DUN;
case APN_HIPRI_ID:
return Phone.APN_TYPE_HIPRI;
+ case APN_IMS_ID:
+ return Phone.APN_TYPE_IMS;
+ case APN_FOTA_ID:
+ return Phone.APN_TYPE_FOTA;
+ case APN_CBS_ID:
+ return Phone.APN_TYPE_CBS;
default:
log("Unknown id (" + id + ") in apnIdToType");
return Phone.APN_TYPE_DEFAULT;
}
}
- protected abstract boolean isApnTypeAvailable(String type);
-
- protected abstract void setState(State s);
-
protected LinkProperties getLinkProperties(String apnType) {
int id = apnTypeToId(apnType);
if (isApnIdEnabled(id)) {
@@ -704,13 +725,12 @@
return possible;
}
- protected abstract boolean isDataAllowed();
-
public boolean isApnTypeEnabled(String apnType) {
if (apnType == null) {
- apnType = getActiveApnType();
+ return false;
+ } else {
+ return isApnIdEnabled(apnTypeToId(apnType));
}
- return isApnIdEnabled(apnTypeToId(apnType));
}
protected synchronized boolean isApnIdEnabled(int id) {
@@ -826,7 +846,7 @@
dataEnabled[apnId] = false;
enabledCount--;
if (enabledCount == 0) {
- onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ onCleanUpConnection(true, apnId, Phone.REASON_DATA_DISABLED);
}
// send the disconnect msg manually, since the normal route wont send
@@ -855,6 +875,22 @@
}
/**
+ * Called when EVENT_RESET_DONE is received so goto
+ * IDLE state and send notifications to those interested.
+ *
+ * TODO - currently unused. Needs to be hooked into DataConnection cleanup
+ * TODO - needs to pass some notion of which connection is reset..
+ */
+ protected void onResetDone(AsyncResult ar) {
+ if (DBG) log("EVENT_RESET_DONE");
+ String reason = null;
+ if (ar.userObj instanceof String) {
+ reason = (String) ar.userObj;
+ }
+ gotoIdleAndNotifyDataConnection(reason);
+ }
+
+ /**
* Prevent mobile data connections from being established, or once again
* allow mobile data connections. If the state toggles, then either tear
* down or set up data, as appropriate to match the new state.
@@ -881,10 +917,10 @@
}
if (prevEnabled != getAnyDataEnabled()) {
if (!prevEnabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
- onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ cleanUpAllConnections();
}
}
}
@@ -894,6 +930,17 @@
return mDataEnabled;
}
+ public void cleanUpAllConnections() {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_ALL_CONNECTIONS);
+ sendMessage(msg);
+ }
+
+ public boolean isAnyActiveDataConnections() {
+ // TODO: Remember if there are any connected or
+ // loop asking each DC/APN?
+ return true;
+ }
+
protected void onSetDataEnabled(boolean enable) {
boolean prevEnabled = getAnyDataEnabled();
if (mDataEnabled != enable) {
@@ -904,12 +951,18 @@
Settings.Secure.MOBILE_DATA, enable ? 1 : 0);
if (prevEnabled != getAnyDataEnabled()) {
if (!prevEnabled) {
- mRetryMgr.resetRetryCount();
+ resetAllRetryCounts();
onTrySetupData(Phone.REASON_DATA_ENABLED);
} else {
- onCleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ onCleanUpConnection(true, APN_DEFAULT_ID, Phone.REASON_DATA_DISABLED);
}
}
}
}
+
+ protected void resetAllRetryCounts() {
+ for (DataConnection dc : mDataConnections.values()) {
+ dc.resetRetryCount();
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index e270ce9..dbfc0d4 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -28,6 +28,7 @@
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.CommandsInterface.RadioState;
+import android.os.SystemProperties;
/**
* {@hide}
@@ -85,6 +86,9 @@
private static final int EVENT_QUERY_FACILITY_FDN_DONE = 10;
private static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11;
+ static final boolean LTE_AVAILABLE_ON_CDMA =
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
+
/*
UNKNOWN is a transient state, for example, after uesr inputs ICC pin under
PIN_REQUIRED state, the query for ICC status returns UNKNOWN before it
@@ -426,6 +430,9 @@
broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
INTENT_VALUE_LOCKED_NETWORK);
}
+ if (oldState != State.READY && newState == State.READY && LTE_AVAILABLE_ON_CDMA) {
+ mPhone.mSIMRecords.onSimReady();
+ }
}
/**
@@ -612,14 +619,16 @@
currentRadioState == RadioState.SIM_NOT_READY ||
currentRadioState == RadioState.RUIM_NOT_READY ||
currentRadioState == RadioState.NV_NOT_READY ||
- currentRadioState == RadioState.NV_READY) {
+ (currentRadioState == RadioState.NV_READY && !LTE_AVAILABLE_ON_CDMA)) {
return IccCard.State.NOT_READY;
}
if( currentRadioState == RadioState.SIM_LOCKED_OR_ABSENT ||
currentRadioState == RadioState.SIM_READY ||
currentRadioState == RadioState.RUIM_LOCKED_OR_ABSENT ||
- currentRadioState == RadioState.RUIM_READY) {
+ currentRadioState == RadioState.RUIM_READY ||
+ (currentRadioState == RadioState.NV_READY && LTE_AVAILABLE_ON_CDMA)) {
+
int index;
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
index 9f60a6c..4cf21ee 100644
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java
@@ -28,7 +28,8 @@
APPTYPE_SIM,
APPTYPE_USIM,
APPTYPE_RUIM,
- APPTYPE_CSIM
+ APPTYPE_CSIM,
+ APPTYPE_ISIM
};
public enum AppState{
@@ -115,6 +116,7 @@
case 2: newType = AppType.APPTYPE_USIM; break;
case 3: newType = AppType.APPTYPE_RUIM; break;
case 4: newType = AppType.APPTYPE_CSIM; break;
+ case 5: newType = AppType.APPTYPE_ISIM; break;
default:
throw new RuntimeException(
"Unrecognized RIL_AppType: " +type);
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index b12d2d4..b40f945 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -58,6 +58,13 @@
static final int EF_CST = 0x6f32;
static final int EF_RUIM_SPN =0x6F41;
+ //ISIM access
+ static final int EF_IMPU = 0x6f04;
+ static final int EF_IMPI = 0x6f02;
+ static final int EF_DOMAIN = 0x6f03;
+ static final int EF_IST = 0x6f07;
+ static final int EF_PCSCF = 0x6f09;
+
// SMS record length from TS 51.011 10.5.3
static public final int SMS_RECORD_LENGTH = 176;
@@ -67,4 +74,7 @@
static final String DF_GRAPHICS = "5F50";
static final String DF_GSM = "7F20";
static final String DF_CDMA = "7F25";
+
+ //ISIM access
+ static final String DF_ADFISIM = "7FFF";
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index acb86d4..7450047 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -125,6 +125,12 @@
static final String APN_TYPE_DUN = "dun";
/** APN type for HiPri traffic */
static final String APN_TYPE_HIPRI = "hipri";
+ /** APN type for FOTA */
+ static final String APN_TYPE_FOTA = "fota";
+ /** APN type for IMS */
+ static final String APN_TYPE_IMS = "ims";
+ /** APN type for CBS */
+ static final String APN_TYPE_CBS = "cbs";
// "Features" accessible through the connectivity manager
static final String FEATURE_ENABLE_MMS = "enableMMS";
@@ -132,6 +138,9 @@
static final String FEATURE_ENABLE_DUN = "enableDUN";
static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
static final String FEATURE_ENABLE_DUN_ALWAYS = "enableDUNAlways";
+ static final String FEATURE_ENABLE_FOTA = "enableFOTA";
+ static final String FEATURE_ENABLE_IMS = "enableIMS";
+ static final String FEATURE_ENABLE_CBS = "enableCBS";
/**
* Return codes for <code>enableApnType()</code>
@@ -140,6 +149,7 @@
static final int APN_REQUEST_STARTED = 1;
static final int APN_TYPE_NOT_AVAILABLE = 2;
static final int APN_REQUEST_FAILED = 3;
+ static final int APN_ALREADY_INACTIVE = 4;
/**
@@ -164,6 +174,7 @@
static final String REASON_PS_RESTRICT_ENABLED = "psRestrictEnabled";
static final String REASON_PS_RESTRICT_DISABLED = "psRestrictDisabled";
static final String REASON_SIM_LOADED = "simLoaded";
+ static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
// Used for band mode selection methods
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
@@ -193,6 +204,7 @@
int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
+ int NT_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY;
int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE;
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 54341b1..5408ce9 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -38,6 +38,8 @@
import com.android.internal.R;
import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.gsm.SimCard;
import java.util.Locale;
@@ -116,6 +118,9 @@
int mCallRingDelay;
public boolean mIsTheCurrentActivePhone = true;
boolean mIsVoiceCapable = true;
+ public SIMRecords mSIMRecords;
+ public SimCard mSimCard;
+ public SMSDispatcher mSMS;
/**
* Set a system property, unless we're in unit test mode
@@ -237,7 +242,8 @@
public void dispose() {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
mCM.unSetOnCallRing(this);
- mDataConnection.onCleanUpConnection(false, REASON_RADIO_TURNED_OFF);
+ // Must cleanup all connectionS and needs to use sendMessage!
+ mDataConnection.cleanUpAllConnections();
mIsTheCurrentActivePhone = false;
}
}
@@ -662,6 +668,20 @@
}
/**
+ * Retrieves the ServiceStateTracker of the phone instance.
+ */
+ public ServiceStateTracker getServiceStateTracker() {
+ return null;
+ }
+
+ /**
+ * Get call tracker
+ */
+ public CallTracker getCallTracker() {
+ return null;
+ }
+
+ /**
* Query the status of the CDMA roaming preference
*/
public void queryCdmaRoamingPreference(Message response) {
@@ -1080,4 +1100,14 @@
Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
"called, GSMPhone inactive.");
}
+
+ // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
+ public void notifyCallForwardingIndicator() {
+ // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ }
+
+ public void notifyDataConnectionFailed(String reason, String apnType) {
+ mNotifier.notifyDataConnectionFailed(this, reason, apnType);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java
index 2e391cb..ab0bb63 100644
--- a/telephony/java/com/android/internal/telephony/PhoneFactory.java
+++ b/telephony/java/com/android/internal/telephony/PhoneFactory.java
@@ -21,8 +21,10 @@
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
+import android.os.SystemProperties;
import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.cdma.CDMALTEPhone;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.sip.SipPhone;
import com.android.internal.telephony.sip.SipPhoneFactory;
@@ -34,6 +36,9 @@
static final String LOG_TAG = "PHONE";
static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000;
static final int SOCKET_OPEN_MAX_RETRY = 3;
+ static final boolean LTE_AVAILABLE_ON_CDMA =
+ SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false);
+
//***** Class Variables
static private Phone sProxyPhone = null;
@@ -115,9 +120,15 @@
sProxyPhone = new PhoneProxy(new GSMPhone(context,
sCommandsInterface, sPhoneNotifier));
} else if (phoneType == Phone.PHONE_TYPE_CDMA) {
- Log.i(LOG_TAG, "Creating CDMAPhone");
- sProxyPhone = new PhoneProxy(new CDMAPhone(context,
- sCommandsInterface, sPhoneNotifier));
+ if (LTE_AVAILABLE_ON_CDMA == false ) {
+ Log.i(LOG_TAG, "Creating CDMAPhone");
+ sProxyPhone = new PhoneProxy(new CDMAPhone(context,
+ sCommandsInterface, sPhoneNotifier));
+ } else {
+ Log.i(LOG_TAG, "Creating CDMALTEPhone");
+ sProxyPhone = new PhoneProxy(new CDMALTEPhone(context,
+ sCommandsInterface, sPhoneNotifier));
+ }
}
sMadeDefaults = true;
@@ -147,6 +158,14 @@
case RILConstants.NETWORK_MODE_GLOBAL:
return Phone.PHONE_TYPE_CDMA;
+
+ case RILConstants.NETWORK_MODE_LTE_ONLY:
+ if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA,
+ false)) {
+ return Phone.PHONE_TYPE_CDMA;
+ } else {
+ return Phone.PHONE_TYPE_GSM;
+ }
default:
return Phone.PHONE_TYPE_GSM;
}
@@ -166,8 +185,13 @@
public static Phone getCdmaPhone() {
synchronized(PhoneProxy.lockForRadioTechnologyChange) {
- Phone phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
- return phone;
+ if (LTE_AVAILABLE_ON_CDMA == false) {
+ Phone phone = new CDMAPhone(sContext, sCommandsInterface, sPhoneNotifier);
+ return phone;
+ } else {
+ Phone phone = new CDMALTEPhone(sContext, sCommandsInterface, sPhoneNotifier);
+ return phone;
+ }
}
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 15b23bb..49497b4 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -741,6 +741,10 @@
return mActivePhone.getCdmaEriIconMode();
}
+ public Phone getActivePhone() {
+ return mActivePhone;
+ }
+
public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){
mActivePhone.sendBurstDtmf(dtmfString, on, off, onComplete);
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 804ace4..1d47405 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -207,9 +207,8 @@
*/
public final class RIL extends BaseCommands implements CommandsInterface {
static final String LOG_TAG = "RILJ";
- private static final boolean DBG = false;
- static final boolean RILJ_LOGD = Config.LOGD;
- static final boolean RILJ_LOGV = DBG ? Config.LOGD : Config.LOGV;
+ static final boolean RILJ_LOGD = true;
+ static final boolean RILJ_LOGV = false; // STOP SHIP if true
/**
* Wake lock timeout should be longer than the longest timeout in
@@ -638,6 +637,14 @@
case RILConstants.NETWORK_MODE_GLOBAL:
mPhoneType = RILConstants.CDMA_PHONE;
break;
+ case RILConstants.NETWORK_MODE_LTE_ONLY:
+ if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA,
+ false)) {
+ mPhoneType = RILConstants.CDMA_PHONE;
+ } else {
+ mPhoneType = RILConstants.GSM_PHONE;
+ }
+ break;
default:
mPhoneType = RILConstants.CDMA_PHONE;
}
@@ -1389,33 +1396,29 @@
if(mInitialRadioStateChange) {
synchronized (mStateMonitor) {
if (!mState.isOn()) {
- RILRequest rrPnt = RILRequest.obtain(
- RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, null);
-
- rrPnt.mp.writeInt(1);
- rrPnt.mp.writeInt(mNetworkMode);
- if (RILJ_LOGD) riljLog(rrPnt.serialString() + "> "
- + requestToString(rrPnt.mRequest) + " : " + mNetworkMode);
-
- send(rrPnt);
+ setPreferredNetworkType(mNetworkMode, null);
RILRequest rrCs = RILRequest.obtain(
RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, null);
rrCs.mp.writeInt(1);
rrCs.mp.writeInt(mCdmaSubscription);
- if (RILJ_LOGD) riljLog(rrCs.serialString() + "> "
- + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
+ if (RILJ_LOGD) {
+ riljLog(rrCs.serialString() + "> "
+ + requestToString(rrCs.mRequest) + " : " + mCdmaSubscription);
+ }
send(rrCs);
}
}
}
- RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result);
rr.mp.writeInt(1);
rr.mp.writeInt(on ? 1 : 0);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+ if (RILJ_LOGD) {
+ riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + (on ? " on" : " off"));
+ }
send(rr);
}
@@ -2065,8 +2068,9 @@
if (RILJ_LOGD) Log.d(LOG_TAG, "Radio ON @ init; reset to OFF");
setRadioPower(false, null);
} else {
- if (DBG) Log.d(LOG_TAG, "Radio OFF @ init");
+ if (RILJ_LOGD) Log.d(LOG_TAG, "Radio OFF @ init");
setRadioState(newState);
+ setPreferredNetworkType(mNetworkMode, null);
}
mInitialRadioStateChange = false;
} else {
@@ -2361,7 +2365,10 @@
case RIL_REQUEST_GET_IMSI:
case RIL_REQUEST_GET_IMEI:
case RIL_REQUEST_GET_IMEISV:
- return "";
+ if (!RILJ_LOGV) {
+ // If not versbose logging just return and don't display IMSI and IMEI, IMEISV
+ return "";
+ }
}
StringBuilder sb;
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index cdf1977..8c9fb79 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -66,6 +66,8 @@
int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */
int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
AVAILABLE Application Settings menu*/
+ int NETWORK_MODE_LTE_ONLY = 8; /* LTE Only mode. Used only for testing purposes.Not
+ user selectable from regular UI */
int PREFERRED_NETWORK_MODE = NETWORK_MODE_WCDMA_PREF;
/* CDMA subscription source. See ril.h RIL_REQUEST_CDMA_SET_SUBSCRIPTION */
@@ -138,10 +140,12 @@
int RIL_RESTRICTED_STATE_PS_ALL = 0x10;
/** Data profile for RIL_REQUEST_SETUP_DATA_CALL */
- static final int DATA_PROFILE_DEFAULT = 0;
- static final int DATA_PROFILE_TETHERED = 1;
- static final int DATA_PROFILE_OEM_BASE = 1000;
-
+ public static final int DATA_PROFILE_DEFAULT = 0;
+ public static final int DATA_PROFILE_TETHERED = 1;
+ public static final int DATA_PROFILE_IMS = 2;
+ public static final int DATA_PROFILE_FOTA = 3;
+ public static final int DATA_PROFILE_CBS = 4;
+ public static final int DATA_PROFILE_OEM_BASE = 1000;
int RIL_REQUEST_GET_SIM_STATUS = 1;
int RIL_REQUEST_ENTER_SIM_PIN = 2;
diff --git a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java b/telephony/java/com/android/internal/telephony/RestrictedState.java
similarity index 98%
rename from telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
rename to telephony/java/com/android/internal/telephony/RestrictedState.java
index 3f7d5d7..ad2b88d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
+++ b/telephony/java/com/android/internal/telephony/RestrictedState.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
import android.telephony.ServiceState;
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index befee8c..6af9b1c 100755
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -582,7 +582,7 @@
* {@link Activity#RESULT_OK} if the message has been broadcast
* to applications
*/
- protected abstract int dispatchMessage(SmsMessageBase sms);
+ public abstract int dispatchMessage(SmsMessageBase sms);
/**
@@ -916,7 +916,7 @@
* @param response
* Callback message is empty on completion
*/
- protected abstract void activateCellBroadcastSms(int activate, Message response);
+ public abstract void activateCellBroadcastSms(int activate, Message response);
/**
* Query the current configuration of cell broadcast SMS.
@@ -925,7 +925,7 @@
* Callback message contains the configuration from the modem on completion
* @see #setCellBroadcastConfig
*/
- protected abstract void getCellBroadcastSmsConfig(Message response);
+ public abstract void getCellBroadcastSmsConfig(Message response);
/**
* Configure cell broadcast SMS.
@@ -937,7 +937,7 @@
* @param response
* Callback message is empty on completion
*/
- protected abstract void setCellBroadcastConfig(int[] configValuesArray, Message response);
+ public abstract void setCellBroadcastConfig(int[] configValuesArray, Message response);
/**
* Send an acknowledge message.
@@ -1006,6 +1006,27 @@
return new SmsTracker(data, sentIntent, deliveryIntent);
}
+ public void initSipStack(boolean isObg) {
+ // This function should be overridden by the classes that support
+ // switching modes such as the CdmaSMSDispatcher.
+ // Not implemented in GsmSMSDispatcher.
+ Log.e(TAG, "Error! This function should never be executed.");
+ }
+
+ public void switchToCdma() {
+ // This function should be overridden by the classes that support
+ // switching modes such as the CdmaSMSDispatcher.
+ // Not implemented in GsmSMSDispatcher.
+ Log.e(TAG, "Error! This function should never be executed.");
+ }
+
+ public void switchToGsm() {
+ // This function should be overridden by the classes that support
+ // switching modes such as the CdmaSMSDispatcher.
+ // Not implemented in GsmSMSDispatcher.
+ Log.e(TAG, "Error! This function should never be executed.");
+ }
+
private DialogInterface.OnClickListener mListener =
new DialogInterface.OnClickListener() {
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 3f9ffc3..1b5bad9 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -29,23 +29,6 @@
*/
public abstract class ServiceStateTracker extends Handler {
- /**
- * Access technology currently in use.
- */
- protected static final int DATA_ACCESS_UNKNOWN = 0;
- protected static final int DATA_ACCESS_GPRS = 1;
- protected static final int DATA_ACCESS_EDGE = 2;
- protected static final int DATA_ACCESS_UMTS = 3;
- protected static final int DATA_ACCESS_CDMA_IS95A = 4;
- protected static final int DATA_ACCESS_CDMA_IS95B = 5;
- protected static final int DATA_ACCESS_CDMA_1xRTT = 6;
- protected static final int DATA_ACCESS_CDMA_EvDo_0 = 7;
- protected static final int DATA_ACCESS_CDMA_EvDo_A = 8;
- protected static final int DATA_ACCESS_HSDPA = 9;
- protected static final int DATA_ACCESS_HSUPA = 10;
- protected static final int DATA_ACCESS_HSPA = 11;
- protected static final int DATA_ACCESS_CDMA_EvDo_B = 12;
-
protected CommandsInterface cm;
public ServiceState ss;
@@ -53,6 +36,9 @@
public SignalStrength mSignalStrength;
+ // TODO - this should not be public
+ public RestrictedState mRestrictedState = new RestrictedState();
+
/* The otaspMode passed to PhoneStateListener#onOtaspChanged */
static public final int OTASP_UNINITIALIZED = 0;
static public final int OTASP_UNKNOWN = 1;
@@ -74,9 +60,14 @@
*/
protected boolean dontPollSignalStrength = false;
- protected RegistrantList networkAttachedRegistrants = new RegistrantList();
- protected RegistrantList roamingOnRegistrants = new RegistrantList();
- protected RegistrantList roamingOffRegistrants = new RegistrantList();
+ protected RegistrantList mRoamingOnRegistrants = new RegistrantList();
+ protected RegistrantList mRoamingOffRegistrants = new RegistrantList();
+ protected RegistrantList mAttachedRegistrants = new RegistrantList();
+ protected RegistrantList mDetachedRegistrants = new RegistrantList();
+ protected RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
+ protected RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
+ protected RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
+
protected static final boolean DBG = true;
@@ -163,7 +154,6 @@
protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
public ServiceStateTracker() {
-
}
public boolean getDesiredPowerState() {
@@ -180,7 +170,7 @@
*/
public void registerForRoamingOn(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
- roamingOnRegistrants.add(r);
+ mRoamingOnRegistrants.add(r);
if (ss.getRoaming()) {
r.notifyRegistrant();
@@ -188,7 +178,7 @@
}
public void unregisterForRoamingOn(Handler h) {
- roamingOnRegistrants.remove(h);
+ mRoamingOnRegistrants.remove(h);
}
/**
@@ -201,7 +191,7 @@
*/
public void registerForRoamingOff(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
- roamingOffRegistrants.add(r);
+ mRoamingOffRegistrants.add(r);
if (!ss.getRoaming()) {
r.notifyRegistrant();
@@ -209,7 +199,7 @@
}
public void unregisterForRoamingOff(Handler h) {
- roamingOffRegistrants.remove(h);
+ mRoamingOffRegistrants.remove(h);
}
/**
@@ -280,12 +270,107 @@
protected abstract void setPowerStateToDesired();
protected abstract void log(String s);
+ public abstract int getCurrentDataConnectionState();
+ public abstract boolean isConcurrentVoiceAndDataAllowed();
+
+ /**
+ * Registration point for transition into DataConnection attached.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj placed in Message.obj
+ */
+ public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+ mAttachedRegistrants.add(r);
+
+ if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
+ r.notifyRegistrant();
+ }
+ }
+ public void unregisterForDataConnectionAttached(Handler h) {
+ mAttachedRegistrants.remove(h);
+ }
+
+ /**
+ * Registration point for transition into DataConnection detached.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj placed in Message.obj
+ */
+ public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+ mDetachedRegistrants.add(r);
+
+ if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
+ r.notifyRegistrant();
+ }
+ }
+ public void unregisterForDataConnectionDetached(Handler h) {
+ mDetachedRegistrants.remove(h);
+ }
+
+ /**
+ * Registration point for transition into network attached.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj in Message.obj
+ */
+ public void registerForNetworkAttached(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+
+ mNetworkAttachedRegistrants.add(r);
+ if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
+ r.notifyRegistrant();
+ }
+ }
+ public void unregisterForNetworkAttached(Handler h) {
+ mNetworkAttachedRegistrants.remove(h);
+ }
+
+ /**
+ * Registration point for transition into packet service restricted zone.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj placed in Message.obj
+ */
+ public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+ mPsRestrictEnabledRegistrants.add(r);
+
+ if (mRestrictedState.isPsRestricted()) {
+ r.notifyRegistrant();
+ }
+ }
+
+ public void unregisterForPsRestrictedEnabled(Handler h) {
+ mPsRestrictEnabledRegistrants.remove(h);
+ }
+
+ /**
+ * Registration point for transition out of packet service restricted zone.
+ * @param h handler to notify
+ * @param what what code of message when delivered
+ * @param obj placed in Message.obj
+ */
+ public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
+ Registrant r = new Registrant(h, what, obj);
+ mPsRestrictDisabledRegistrants.add(r);
+
+ if (mRestrictedState.isPsRestricted()) {
+ r.notifyRegistrant();
+ }
+ }
+
+ public void unregisterForPsRestrictedDisabled(Handler h) {
+ mPsRestrictDisabledRegistrants.remove(h);
+ }
+
/**
* Clean up existing voice and data connection then turn off radio power.
*
* Hang up the existing voice calls to decrease call drop rate.
*/
- protected abstract void powerOffRadioSafely();
+ public abstract void powerOffRadioSafely();
/** Cancel a pending (if any) pollState() operation */
protected void cancelPollState() {
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index e6189be..c4fab66 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -72,6 +72,11 @@
*/
static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country";
+ /** 'true' if device supports both LTE and CDMA mode of operation.
+ * Availability: Set only on devices supporting LTE and CDMA.
+ */
+ static final String PROPERTY_NETWORK_LTE_ON_CDMA = "ro.telephony.lte_on_cdma";
+
static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type";
//****** SIM Card
diff --git a/telephony/java/com/android/internal/telephony/cat/CatService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
index 1e23e34..a6c7777 100644
--- a/telephony/java/com/android/internal/telephony/cat/CatService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -118,6 +118,8 @@
private static IccRecords mIccRecords;
// Service members.
+ // Protects singleton instance lazy initialization.
+ private static final Object sInstanceLock = new Object();
private static CatService sInstance;
private CommandsInterface mCmdIf;
private Context mContext;
@@ -373,25 +375,30 @@
private void encodeOptionalTags(CommandDetails cmdDet,
ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
- switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
- case GET_INKEY:
- // ETSI TS 102 384,27.22.4.2.8.4.2.
- // If it is a response for GET_INKEY command and the response timeout
- // occured, then add DURATION TLV for variable timeout case.
- if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
- (cmdInput != null) && (cmdInput.duration != null)) {
- getInKeyResponse(buf, cmdInput);
- }
- break;
- case PROVIDE_LOCAL_INFORMATION:
- if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
- (resultCode.value() == ResultCode.OK.value())) {
- getPliResponse(buf);
- }
- break;
- default:
- CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
- break;
+ CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
+ if (cmdType != null) {
+ switch (cmdType) {
+ case GET_INKEY:
+ // ETSI TS 102 384,27.22.4.2.8.4.2.
+ // If it is a response for GET_INKEY command and the response timeout
+ // occured, then add DURATION TLV for variable timeout case.
+ if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
+ (cmdInput != null) && (cmdInput.duration != null)) {
+ getInKeyResponse(buf, cmdInput);
+ }
+ break;
+ case PROVIDE_LOCAL_INFORMATION:
+ if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
+ (resultCode.value() == ResultCode.OK.value())) {
+ getPliResponse(buf);
+ }
+ break;
+ default:
+ CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
+ break;
+ }
+ } else {
+ CatLog.d(this, "encodeOptionalTags() bad Cmd:" + cmdDet.typeOfCommand);
}
}
@@ -515,26 +522,28 @@
*/
public static CatService getInstance(CommandsInterface ci, IccRecords ir,
Context context, IccFileHandler fh, IccCard ic) {
- if (sInstance == null) {
- if (ci == null || ir == null || context == null || fh == null
- || ic == null) {
- return null;
- }
- HandlerThread thread = new HandlerThread("Cat Telephony service");
- thread.start();
- sInstance = new CatService(ci, ir, context, fh, ic);
- CatLog.d(sInstance, "NEW sInstance");
- } else if ((ir != null) && (mIccRecords != ir)) {
- CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
- mIccRecords = ir;
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ if (ci == null || ir == null || context == null || fh == null
+ || ic == null) {
+ return null;
+ }
+ HandlerThread thread = new HandlerThread("Cat Telephony service");
+ thread.start();
+ sInstance = new CatService(ci, ir, context, fh, ic);
+ CatLog.d(sInstance, "NEW sInstance");
+ } else if ((ir != null) && (mIccRecords != ir)) {
+ CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
+ mIccRecords = ir;
- // re-Register for SIM ready event.
- mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
- CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
- } else {
- CatLog.d(sInstance, "Return current sInstance");
+ // re-Register for SIM ready event.
+ mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
+ CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
+ } else {
+ CatLog.d(sInstance, "Return current sInstance");
+ }
+ return sInstance;
}
- return sInstance;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
new file mode 100644
index 0000000..8fd6de1
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import android.os.SystemProperties;
+import android.content.Context;
+import android.net.Uri;
+import android.content.Context;
+import android.provider.Telephony;
+import android.content.ContentValues;
+import android.database.SQLException;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+
+import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.gsm.SimCard;
+import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.PhoneNotifier;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
+
+import android.util.Log;
+
+public class CDMALTEPhone extends CDMAPhone {
+ static final String LOG_TAG = "CDMA";
+
+ private static final boolean DBG = true;
+
+ // Constructors
+ public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
+ this(context, ci, notifier, false);
+ log("CDMALTEPhone Constructors");
+ }
+
+ public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
+ boolean unitTestMode) {
+ super(context, ci, notifier, false);
+
+ mSIMRecords = new SIMRecords(this);
+ mSimCard = new SimCard(this, LOG_TAG, DBG);
+ }
+
+ @Override
+ protected void initSST() {
+ mSST = new CdmaLteServiceStateTracker(this);
+ }
+
+ public void dispose() {
+ synchronized (PhoneProxy.lockForRadioTechnologyChange) {
+ super.dispose();
+ mSIMRecords.dispose();
+ mSimCard.dispose();
+ }
+ }
+
+ @Override
+ public void removeReferences() {
+ super.removeReferences();
+ this.mSIMRecords = null;
+ this.mSimCard = null;
+ }
+
+ @Override
+ public ServiceStateTracker getServiceStateTracker() {
+ return mSST;
+ }
+
+ public IccCard getIccCard() {
+ return mSimCard;
+ }
+
+ @Override
+ public String getIccSerialNumber() {
+ return mSIMRecords.iccid;
+ }
+
+ @Override
+ public DataState getDataConnectionState(String apnType) {
+ boolean isCdmaDataConnectionTracker = false;
+ if (mDataConnection instanceof CdmaDataConnectionTracker) {
+ isCdmaDataConnectionTracker = true;
+ }
+ log("getDataConnectionState");
+ DataState ret = DataState.DISCONNECTED;
+
+ if (!isCdmaDataConnectionTracker && (SystemProperties.get("adb.connected", "").length()
+ > 0)) {
+ // We're connected to an ADB host and we have USB networking
+ // turned on. No matter what the radio state is,
+ // we report data connected
+
+ ret = DataState.CONNECTED;
+ } else if (mSST == null) {
+ // Radio Technology Change is ongoning, dispose() and
+ // removeReferences() have
+ // already been called
+
+ ret = DataState.DISCONNECTED;
+ } else if (mSST.getCurrentCdmaDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
+ // 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(apnType)) {
+ case FAILED:
+ case IDLE:
+ ret = DataState.DISCONNECTED;
+ break;
+
+ case CONNECTED:
+ case DISCONNECTING:
+ if (mCT.state != Phone.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed()) {
+ ret = DataState.SUSPENDED;
+ } else {
+ ret = DataState.CONNECTED;
+ }
+ break;
+
+ case INITING:
+ case CONNECTING:
+ case SCANNING:
+ ret = DataState.CONNECTING;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+ public boolean updateCurrentCarrierInProvider() {
+ if (mSIMRecords != null) {
+ try {
+ Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
+ ContentValues map = new ContentValues();
+ map.put(Telephony.Carriers.NUMERIC, mSIMRecords.getSIMOperatorNumeric());
+ mContext.getContentResolver().insert(uri, map);
+ return true;
+ } catch (SQLException e) {
+ Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator", e);
+ }
+ }
+ return false;
+ }
+
+ public String getActiveApn(String apnType) {
+ if (mDataConnection instanceof CdmaDataConnectionTracker)
+ return mDataConnection.getActiveApnString();
+
+ return ((GsmDataConnectionTracker)mDataConnection).getActiveApnString(apnType);
+ }
+
+ protected void log(String s) {
+ if (DBG)
+ Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 74adebd..31abe34 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -66,6 +66,7 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.UUSInfo;
+import com.android.internal.telephony.CallTracker;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
@@ -97,7 +98,6 @@
// Instance Variables
CdmaCallTracker mCT;
- CdmaSMSDispatcher mSMS;
CdmaServiceStateTracker mSST;
RuimRecords mRuimRecords;
RuimCard mRuimCard;
@@ -141,16 +141,25 @@
// Constructors
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
- this(context,ci,notifier, false);
+ super(notifier, context, ci, false);
+ initSST();
+ init(context, notifier);
}
public CDMAPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
boolean unitTestMode) {
super(notifier, context, ci, unitTestMode);
+ initSST();
+ init(context, notifier);
+ }
+ protected void initSST() {
+ mSST = new CdmaServiceStateTracker(this);
+ }
+
+ protected void init(Context context, PhoneNotifier notifier) {
mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
mCT = new CdmaCallTracker(this);
- mSST = new CdmaServiceStateTracker (this);
mSMS = new CdmaSMSDispatcher(this);
mIccFileHandler = new RuimFileHandler(this);
mRuimRecords = new RuimRecords(this);
@@ -168,7 +177,7 @@
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
- mSST.registerForNetworkAttach(this, EVENT_REGISTERED_TO_NETWORK, null);
+ mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
mCM.registerForNVReady(this, EVENT_NV_READY, null);
mCM.setEmergencyCallbackMode(this, EVENT_EMERGENCY_CALLBACK_MODE_ENTER, null);
@@ -220,7 +229,7 @@
mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
mCM.unregisterForOn(this); //EVENT_RADIO_ON
mCM.unregisterForNVReady(this); //EVENT_NV_READY
- mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK
+ mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
mCM.unSetOnSuppServiceNotification(this);
removeCallbacks(mExitEcmRunnable);
@@ -270,10 +279,18 @@
return mSST.ss;
}
+ public CallTracker getCallTracker() {
+ return mCT;
+ }
+
public Phone.State getState() {
return mCT.state;
}
+ public ServiceStateTracker getServiceStateTracker() {
+ return mSST;
+ }
+
public String getPhoneName() {
return "CDMA";
}
@@ -616,7 +633,7 @@
mDataConnection.isApnTypeActive(apnType) == false) {
ret = DataState.DISCONNECTED;
} else {
- switch (mDataConnection.getState()) {
+ switch (mDataConnection.getState(apnType)) {
case FAILED:
case IDLE:
ret = DataState.DISCONNECTED;
@@ -625,7 +642,7 @@
case CONNECTED:
case DISCONNECTING:
if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndData()) {
+ && !mSST.isConcurrentVoiceAndDataAllowed()) {
ret = DataState.SUSPENDED;
} else {
ret = DataState.CONNECTED;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index a89f783..79f4152 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -134,6 +134,10 @@
public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
voiceCallStartedRegistrants.add(r);
+ // Notify if in call when registering
+ if (state != Phone.State.IDLE) {
+ r.notifyRegistrant(new AsyncResult(null, null, null));
+ }
}
public void unregisterForVoiceCallStarted(Handler h) {
voiceCallStartedRegistrants.remove(h);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index fbe455e..1a15393 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -430,7 +430,7 @@
} else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
|| serviceState == ServiceState.STATE_EMERGENCY_ONLY) {
return DisconnectCause.OUT_OF_SERVICE;
- } else if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY
+ } else if (phone.mCM.getNvState() != CommandsInterface.RadioState.NV_READY
&& phone.getIccCard().getState() != RuimCard.State.READY) {
return DisconnectCause.ICC_ERROR;
} else if (causeCode==CallFailCause.NORMAL_CLEARING) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 1a0dbc2..cccc053 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -33,8 +33,8 @@
private static final String LOG_TAG = "CDMA";
// ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name, RetryManager rm) {
- super(phone, name, rm);
+ private CdmaDataConnection(CDMAPhone phone, String name, int id, RetryManager rm) {
+ super(phone, name, id, rm);
}
/**
@@ -49,11 +49,10 @@
synchronized (mCountLock) {
mCount += 1;
}
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
- "CdmaDataConnection-" + mCount, rm);
+ CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDataConnection-" + mCount,
+ id, rm);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
- cdmaDc.mId = id;
return cdmaDc;
}
@@ -68,6 +67,7 @@
protected void onConnect(ConnectionParams cp) {
if (DBG) log("CdmaDataConnection Connecting...");
+ mApn = cp.apn;
createTime = -1;
lastFailTime = -1;
lastFailCause = FailCause.NONE;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 8c36106..01519a7 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -104,8 +104,8 @@
p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
- p.mSST.registerForCdmaDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
- p.mSST.registerForCdmaDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
+ p.mSST.registerForDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
+ p.mSST.registerForDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
@@ -118,6 +118,8 @@
@Override
public void dispose() {
+ cleanUpConnection(false, null);
+
super.dispose();
// Unregister from all events
@@ -128,8 +130,8 @@
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
- mCdmaPhone.mSST.unregisterForCdmaDataConnectionAttached(this);
- mCdmaPhone.mSST.unregisterForCdmaDataConnectionDetached(this);
+ mCdmaPhone.mSST.unregisterForDataConnectionAttached(this);
+ mCdmaPhone.mSST.unregisterForDataConnectionDetached(this);
mCdmaPhone.mSST.unregisterForRoamingOn(this);
mCdmaPhone.mSST.unregisterForRoamingOff(this);
mPhone.mCM.unregisterForCdmaOtaProvision(this);
@@ -158,6 +160,11 @@
}
@Override
+ public synchronized State getState(String apnType) {
+ return mState;
+ }
+
+ @Override
protected boolean isApnTypeAvailable(String type) {
for (String s : mSupportedApnTypes) {
if (TextUtils.equals(type, s)) {
@@ -167,30 +174,6 @@
return false;
}
- /**
- * The data connection is expected to be setup while device
- * 1. has ruim card or non-volatile data store
- * 2. registered to data connection service
- * 3. user doesn't explicitly disable data service
- * 4. wifi is not on
- *
- * @return false while no data connection if all above requirements are met.
- */
- @Override
- public boolean isDataConnectionAsDesired() {
- boolean roaming = mPhone.getServiceState().getRoaming();
-
- if (((mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
- mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
- (mCdmaPhone.mSST.getCurrentCdmaDataConnectionState() ==
- ServiceState.STATE_IN_SERVICE) &&
- (!roaming || getDataOnRoamingEnabled()) &&
- !mIsWifiConnected ) {
- return (mState == State.CONNECTED);
- }
- return true;
- }
-
@Override
protected boolean isDataAllowed() {
int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
@@ -200,9 +183,9 @@
boolean allowed =
(psState == ServiceState.STATE_IN_SERVICE ||
mAutoAttachOnCreation) &&
- (mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ (mPhone.mCM.getNvState() == CommandsInterface.RadioState.NV_READY ||
mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
- (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
+ (mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() == Phone.State.IDLE) &&
!roaming &&
mInternalDataEnabled &&
@@ -214,11 +197,11 @@
if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
reason += " - psState= " + psState;
}
- if (!(mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ if (!(mPhone.mCM.getNvState() == CommandsInterface.RadioState.NV_READY ||
mCdmaPhone.mRuimRecords.getRecordsLoaded())) {
- reason += " - radioState= " + mPhone.mCM.getRadioState() + " - RUIM not loaded";
+ reason += " - radioState= " + mPhone.mCM.getNvState() + " - RUIM not loaded";
}
- if (!(mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
+ if (!(mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed() ||
mPhone.getState() == Phone.State.IDLE)) {
reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState();
}
@@ -262,9 +245,7 @@
}
/**
- * Cleanup all connections.
- *
- * TODO: Cleanup only a specified connection passed as a parameter.
+ * Cleanup the CDMA data connection (only one is supported)
*
* @param tearDown true if the underlying DataConnection should be disconnected.
* @param reason for the clean up.
@@ -354,7 +335,7 @@
setState(State.CONNECTED);
notifyDataConnection(reason);
startNetStatPoll();
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
}
private void resetPollStats() {
@@ -386,7 +367,7 @@
protected void restartRadio() {
if (DBG) log("Cleanup connection and wait " +
(TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
- cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+ cleanUpAllConnections();
sendEmptyMessageDelayed(EVENT_RESTART_RADIO, TIME_DELAYED_TO_RESTART_RADIO);
mPendingRestartRadio = true;
}
@@ -504,7 +485,7 @@
* at the last time until the state is changed.
* TODO: Make this configurable?
*/
- int nextReconnectDelay = mRetryMgr.getRetryTimer();
+ int nextReconnectDelay = mDataConnections.get(0).getRetryTimer();
log("Data Connection activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
@@ -518,7 +499,7 @@
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
- mRetryMgr.increaseRetryCount();
+ mDataConnections.get(0).increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
log("NOT Posting Data Connection Unavailable notification "
@@ -534,7 +515,7 @@
notifyDataAvailability(null);
}
- private void gotoIdleAndNotifyDataConnection(String reason) {
+ protected void gotoIdleAndNotifyDataConnection(String reason) {
if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
setState(State.IDLE);
notifyDataConnection(reason);
@@ -543,14 +524,14 @@
protected void onRecordsLoaded() {
if (mState == State.FAILED) {
- cleanUpConnection(false, null);
+ cleanUpAllConnections();
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
protected void onNVReady() {
if (mState == State.FAILED) {
- cleanUpConnection(false, null);
+ cleanUpAllConnections();
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
}
@@ -560,6 +541,7 @@
*/
@Override
protected void onEnableNewApn() {
+ // No mRequestedApnType check; only one connection is supported
cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
}
@@ -588,7 +570,7 @@
trySetupData(Phone.REASON_ROAMING_ON);
} else {
if (DBG) log("Tear down data connection on roaming.");
- cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+ cleanUpAllConnections();
}
}
@@ -609,7 +591,7 @@
notifyDataAvailability(null);
if (mState != State.IDLE) {
- cleanUpConnection(true, null);
+ cleanUpAllConnections();
}
}
@@ -618,7 +600,7 @@
*/
@Override
protected void onRadioOffOrNotAvailable() {
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -626,7 +608,7 @@
log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
- cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
+ cleanUpAllConnections();
}
}
@@ -693,25 +675,11 @@
}
/**
- * Called when EVENT_RESET_DONE is received so goto
- * IDLE state and send notifications to those interested.
- */
- @Override
- protected void onResetDone(AsyncResult ar) {
- if (DBG) log("EVENT_RESET_DONE");
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
- gotoIdleAndNotifyDataConnection(reason);
- }
-
- /**
* @override com.android.internal.telephony.DataConnectionTracker
*/
@Override
protected void onVoiceCallStarted() {
- if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
stopNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
notifyDataAvailability(Phone.REASON_VOICE_CALL_STARTED);
@@ -724,7 +692,7 @@
@Override
protected void onVoiceCallEnded() {
if (mState == State.CONNECTED) {
- if (!mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ if (!mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
@@ -733,34 +701,40 @@
}
notifyDataAvailability(Phone.REASON_VOICE_CALL_ENDED);
} else {
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
}
@Override
- protected void onCleanUpConnection(boolean tearDown, String reason) {
+ protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
+ // No apnId check; only one connection is supported
cleanUpConnection(tearDown, reason);
}
+ @Override
+ protected void onCleanUpAllConnections() {
+ // Only one CDMA connection is supported
+ cleanUpConnection(true, null);
+ }
+
private void createAllDataConnectionList() {
CdmaDataConnection dataConn;
- /** TODO: Use one retry manager for all connections for now */
- RetryManager rm = mRetryMgr;
- if (!rm.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
- if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- rm.configure(20, 2000, 1000);
- }
- }
-
+ String retryConfig = SystemProperties.get("ro.cdma.data_retry_config");
for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
- int id = mUniqueIdGenerator.getAndIncrement();
+ RetryManager rm = new RetryManager();
+ if (!rm.configure(retryConfig)) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+ int id = mUniqueIdGenerator.getAndIncrement();
dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
mDataConnections.put(id, dataConn);
}
@@ -779,7 +753,7 @@
} else {
if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
@@ -797,7 +771,7 @@
switch (otaPrivision[0]) {
case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
- mRetryMgr.resetRetryCount();
+ mDataConnections.get(0).resetRetryCount();
break;
default:
break;
@@ -894,7 +868,7 @@
@Override
public void handleMessage (Message msg) {
- if (!mPhone.mIsTheCurrentActivePhone) {
+ if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
log("Ignore CDMA msgs since CDMA phone is inactive");
return;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
new file mode 100644
index 0000000..81b4077
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import com.android.internal.telephony.DataConnectionTracker;
+import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.MccTable;
+import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.RILConstants;
+
+import android.telephony.SignalStrength;
+import android.telephony.ServiceState;
+import android.telephony.cdma.CdmaCellLocation;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Registrant;
+import android.os.RegistrantList;
+import android.os.AsyncResult;
+import android.os.Message;
+
+import android.util.Log;
+import android.util.EventLog;
+
+import com.android.internal.telephony.RestrictedState;
+import com.android.internal.telephony.gsm.GsmDataConnectionTracker;
+
+public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
+ static final String LOG_TAG = "CDMA";
+
+ CDMALTEPhone mCdmaLtePhone;
+
+ private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
+
+ private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
+
+ public CdmaLteServiceStateTracker(CDMALTEPhone phone) {
+ super(phone);
+ mCdmaLtePhone = phone;
+ log("CdmaLteServiceStateTracker Constructors");
+ }
+
+ /**
+ * @return The current GPRS state. IN_SERVICE is the same as "attached" and
+ * OUT_OF_SERVICE is the same as detached.
+ */
+ public int getCurrentDataConnectionState() {
+ return gprsState;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ AsyncResult ar;
+ int[] ints;
+ String[] strings;
+ if (msg.what == EVENT_POLL_STATE_GPRS) {
+ log("handleMessage EVENT_POLL_STATE_GPRS");
+ ar = (AsyncResult)msg.obj;
+ handlePollStateResult(msg.what, ar);
+ } else {
+ super.handleMessage(msg);
+ }
+ }
+
+ /**
+ * The LTE data connection state, only return true here
+ */
+ @Override
+ protected boolean checkAdditionalDataAvaiable() {
+ return newGPRSState != ServiceState.STATE_IN_SERVICE;
+ }
+
+ /**
+ * Handle the result of one of the pollState()-related requests
+ */
+ @Override
+ protected void handlePollStateResultMessage(int what, AsyncResult ar) {
+ if (what == EVENT_POLL_STATE_GPRS) {
+ log("handlePollStateResultMessage EVENT_POLL_STATE_GPRS");
+ String states[] = (String[])ar.result;
+
+ int type = 0;
+ int regState = -1;
+ if (states.length > 0) {
+ try {
+ regState = Integer.parseInt(states[0]);
+
+ // states[3] (if present) is the current radio technology
+ if (states.length >= 4 && states[3] != null) {
+ type = Integer.parseInt(states[3]);
+ }
+ } catch (NumberFormatException ex) {
+ Log.w(LOG_TAG,
+ "[CdmaLteServiceStateTracker] error parsing GprsRegistrationState: "
+ + ex);
+ }
+ }
+
+ newGPRSState = regCodeToServiceState(regState);
+ // Not sure if this is needed in CDMALTE phone.
+ // mDataRoaming = regCodeIsRoaming(regState);
+ if (newGPRSState == ServiceState.STATE_IN_SERVICE) {
+ this.newCdmaDataConnectionState = newGPRSState;
+ newNetworkType = type;
+ newSS.setRadioTechnology(type);
+ }
+ } else {
+ super.handlePollStateResultMessage(what, ar);
+ }
+ }
+
+ @Override
+ protected void setSignalStrengthDefaultValues() {
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, false);
+ }
+
+ @Override
+ protected void pollState() {
+ pollingContext = new int[1];
+ pollingContext[0] = 0;
+
+ switch (cm.getRadioState()) {
+ case RADIO_UNAVAILABLE:
+ newSS.setStateOutOfService();
+ newCellLoc.setStateInvalid();
+ setSignalStrengthDefaultValues();
+ mGotCountryCode = false;
+
+ pollStateDone();
+ break;
+
+ case RADIO_OFF:
+ newSS.setStateOff();
+ newCellLoc.setStateInvalid();
+ setSignalStrengthDefaultValues();
+ mGotCountryCode = false;
+
+ pollStateDone();
+ break;
+
+ case SIM_NOT_READY:
+ case SIM_LOCKED_OR_ABSENT:
+ case SIM_READY:
+ log("Radio Technology Change ongoing, setting SS to off");
+ newSS.setStateOff();
+ newCellLoc.setStateInvalid();
+ setSignalStrengthDefaultValues();
+ mGotCountryCode = false;
+ // NOTE: pollStateDone() is not needed in this case
+ break;
+
+ default:
+ // Issue all poll-related commands at once, then count
+ // down the responses which are allowed to arrive
+ // out-of-order.
+
+ pollingContext[0]++;
+ // RIL_REQUEST_OPERATOR is necessary for CDMA
+ cm.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
+
+ pollingContext[0]++;
+ // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
+ cm.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA,
+ pollingContext));
+
+ int networkMode = android.provider.Settings.Secure.getInt(phone.getContext()
+ .getContentResolver(),
+ android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+ RILConstants.PREFERRED_NETWORK_MODE);
+ Log.v(LOG_TAG, "[CdmaLteServiceStateTracker] The network mode here is = "
+ + networkMode);
+ if ((networkMode == RILConstants.NETWORK_MODE_GLOBAL)
+ || (networkMode == RILConstants.NETWORK_MODE_LTE_ONLY)) {
+ pollingContext[0]++;
+ // RIL_REQUEST_DATA_REGISTRATION_STATE
+ cm.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS,
+ pollingContext));
+ }
+ break;
+ }
+ }
+
+ protected static String networkTypeToString(int type) {
+ String ret = "unknown";
+
+ switch (type) {
+ case ServiceState.RADIO_TECHNOLOGY_IS95A:
+ case ServiceState.RADIO_TECHNOLOGY_IS95B:
+ ret = "CDMA";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_1xRTT:
+ ret = "CDMA - 1xRTT";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_0:
+ ret = "CDMA - EvDo rev. 0";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_A:
+ ret = "CDMA - EvDo rev. A";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_B:
+ ret = "CDMA - EvDo rev. B";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_LTE:
+ ret = "LTE";
+ break;
+ case ServiceState.RADIO_TECHNOLOGY_EHRPD:
+ ret = "CDMA - eHRPD";
+ break;
+ default:
+ if (DBG) {
+ Log.e(LOG_TAG, " [CdmaLteServiceStateTracker] Wrong network."
+ + " Can not return a string.");
+ }
+ break;
+ }
+ return ret;
+ }
+
+ @Override
+ protected void pollStateDone() {
+ log("Poll ServiceState done: oldSS=[" + ss + "] newSS=[" + newSS + "]");
+
+ boolean hasRegistered = ss.getState() != ServiceState.STATE_IN_SERVICE
+ && newSS.getState() == ServiceState.STATE_IN_SERVICE;
+
+ boolean hasDeregistered = ss.getState() == ServiceState.STATE_IN_SERVICE
+ && newSS.getState() != ServiceState.STATE_IN_SERVICE;
+
+ boolean hasCdmaDataConnectionAttached =
+ this.cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE
+ && this.newCdmaDataConnectionState == ServiceState.STATE_IN_SERVICE;
+
+ boolean hasCdmaDataConnectionDetached =
+ this.cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE
+ && this.newCdmaDataConnectionState != ServiceState.STATE_IN_SERVICE;
+
+ boolean hasCdmaDataConnectionChanged =
+ cdmaDataConnectionState != newCdmaDataConnectionState;
+
+ boolean hasNetworkTypeChanged = networkType != newNetworkType;
+
+ boolean hasChanged = !newSS.equals(ss);
+
+ boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming();
+
+ boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming();
+
+ boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
+
+ boolean has4gHandoff =
+ ((networkType == ServiceState.RADIO_TECHNOLOGY_LTE) &&
+ (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) ||
+ ((networkType == ServiceState.RADIO_TECHNOLOGY_EHRPD) &&
+ (newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE));
+
+ boolean hasMultiApnSupport =
+ (((newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE) ||
+ (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) &&
+ ((networkType != ServiceState.RADIO_TECHNOLOGY_LTE) &&
+ (networkType != ServiceState.RADIO_TECHNOLOGY_EHRPD)));
+
+ boolean hasLostMultiApnSupport =
+ ((newNetworkType >= ServiceState.RADIO_TECHNOLOGY_IS95A) &&
+ (newNetworkType <= ServiceState.RADIO_TECHNOLOGY_EVDO_A));
+
+ log("hasRegistered = " + hasRegistered + " hasCdmaDataConnectionAttached = "
+ + hasCdmaDataConnectionAttached + " hasCdmaDataConnectionChanged = "
+ + hasCdmaDataConnectionChanged + " hasNetworkTypeChanged = "
+ + hasNetworkTypeChanged + " has4gHandoff = " + has4gHandoff
+ + " hasMultiApnSupport = " + hasMultiApnSupport + " hasLostMultiApnSupport = "
+ + hasLostMultiApnSupport);
+ // Add an event log when connection state changes
+ if (ss.getState() != newSS.getState()
+ || cdmaDataConnectionState != newCdmaDataConnectionState) {
+ EventLog.writeEvent(EventLogTags.CDMA_SERVICE_STATE_CHANGE, ss.getState(),
+ cdmaDataConnectionState, newSS.getState(), newCdmaDataConnectionState);
+ }
+
+ ServiceState tss;
+ tss = ss;
+ ss = newSS;
+ newSS = tss;
+ // clean slate for next time
+ newSS.setStateOutOfService();
+
+ // TODO: 4G Tech Handoff
+ // if (has4gHandoff) {
+ // Message msg = phone.mDataConnection.obtainMessage(
+ // DataConnectionTracker.EVENT_4G_TECHNOLOGY_CHANGE);
+ // phone.mDataConnection.sendMessage(msg);
+ // }
+
+ if ((hasMultiApnSupport)
+ && (phone.mDataConnection instanceof CdmaDataConnectionTracker)) {
+ log("GsmDataConnectionTracker Created");
+ phone.mDataConnection.dispose();
+ phone.mDataConnection = new GsmDataConnectionTracker(mCdmaLtePhone);
+ }
+
+ if ((hasLostMultiApnSupport)
+ && (phone.mDataConnection instanceof GsmDataConnectionTracker)) {
+ log("GsmDataConnectionTracker disposed");
+ phone.mDataConnection.dispose();
+ phone.mDataConnection = new CdmaDataConnectionTracker((CDMAPhone)phone);
+ }
+
+ CdmaCellLocation tcl = cellLoc;
+ cellLoc = newCellLoc;
+ newCellLoc = tcl;
+
+ cdmaDataConnectionState = newCdmaDataConnectionState;
+ networkType = newNetworkType;
+
+ gprsState = newCdmaDataConnectionState;
+
+ newSS.setStateOutOfService(); // clean slate for next time
+
+ if (hasNetworkTypeChanged) {
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
+ networkTypeToString(networkType));
+ }
+
+ if (hasRegistered) {
+ mNetworkAttachedRegistrants.notifyRegistrants();
+ }
+
+ if (hasChanged) {
+ if (cm.getNvState().isNVReady()) {
+ String eriText;
+ // Now the CDMAPhone sees the new ServiceState so it can get the
+ // new ERI text
+ if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
+ eriText = phone.getCdmaEriText();
+ } else {
+ // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
+ // for
+ // mRegistrationState 0,2,3 and 4
+ eriText = phone.getContext()
+ .getText(com.android.internal.R.string.roamingTextSearching).toString();
+ }
+ ss.setCdmaEriText(eriText);
+ }
+
+ String operatorNumeric;
+
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
+ ss.getOperatorAlphaLong());
+
+ operatorNumeric = ss.getOperatorNumeric();
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
+
+ if (operatorNumeric == null) {
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
+ } else {
+ String isoCountryCode = "";
+ try {
+ isoCountryCode = MccTable.countryCodeForMcc(Integer.parseInt(operatorNumeric
+ .substring(0, 3)));
+ } catch (NumberFormatException ex) {
+ Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
+ } catch (StringIndexOutOfBoundsException ex) {
+ Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
+ }
+
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
+ isoCountryCode);
+ mGotCountryCode = true;
+ if (mNeedFixZone) {
+ fixTimeZone(isoCountryCode);
+ }
+ }
+
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
+ ss.getRoaming() ? "true" : "false");
+
+ updateSpnDisplay();
+ phone.notifyServiceStateChanged(ss);
+ }
+
+ if (hasCdmaDataConnectionAttached) {
+ mAttachedRegistrants.notifyRegistrants();
+ }
+
+ if (hasCdmaDataConnectionDetached) {
+ mDetachedRegistrants.notifyRegistrants();
+ }
+
+ if ((hasCdmaDataConnectionChanged || hasNetworkTypeChanged)
+ && (phone.mDataConnection instanceof CdmaDataConnectionTracker)) {
+ phone.notifyDataConnection();
+ }
+
+ if (hasRoamingOn) {
+ mRoamingOnRegistrants.notifyRegistrants();
+ }
+
+ if (hasRoamingOff) {
+ mRoamingOffRegistrants.notifyRegistrants();
+ }
+
+ if (hasLocationChanged) {
+ phone.notifyLocationChanged();
+ }
+ }
+
+ protected void onSignalStrengthResult(AsyncResult ar) {
+ SignalStrength oldSignalStrength = mSignalStrength;
+
+ if (ar.exception != null) {
+ // Most likely radio is resetting/disconnected change to default
+ // values.
+ setSignalStrengthDefaultValues();
+ } else {
+ int[] ints = (int[])ar.result;
+ int lteCqi = 99, lteRsrp = -1;
+ int lteRssi = 99;
+ int offset = 2;
+ int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
+ int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160;
+ int evdoRssi = (ints[offset + 2] > 0) ? -ints[offset + 2] : -120;
+ 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 + 7] : -1;
+ lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 6] : 99;
+ }
+
+ if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
+ mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
+ evdoSnr, false);
+ } else {
+ mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
+ evdoSnr, lteRssi, lteRsrp, -1, -1, lteCqi, true);
+ }
+ }
+
+ try {
+ phone.notifySignalStrength();
+ } catch (NullPointerException ex) {
+ log("onSignalStrengthResult() Phone already destroyed: " + ex
+ + "SignalStrength not notified");
+ }
+ }
+
+ public boolean isConcurrentVoiceAndDataAllowed() {
+ // Note: it needs to be confirmed which CDMA network types
+ // can support voice and data calls concurrently.
+ // For the time-being, the return value will be false.
+ // return (networkType >= ServiceState.RADIO_TECHNOLOGY_LTE);
+ return false;
+ }
+
+ @Override
+ protected void log(String s) {
+ if (DBG)
+ Log.d(LOG_TAG, "[CdmaLteServiceStateTracker] " + s);
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 6bd2d09..c0bfd23 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -94,7 +94,7 @@
/** {@inheritDoc} */
@Override
- protected int dispatchMessage(SmsMessageBase smsb) {
+ public int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
if (smsb == null) {
@@ -485,19 +485,19 @@
/** {@inheritDoc} */
@Override
- protected void activateCellBroadcastSms(int activate, Message response) {
+ public void activateCellBroadcastSms(int activate, Message response) {
mCm.setCdmaBroadcastActivation((activate == 0), response);
}
/** {@inheritDoc} */
@Override
- protected void getCellBroadcastSmsConfig(Message response) {
+ public void getCellBroadcastSmsConfig(Message response) {
mCm.getCdmaBroadcastConfig(response);
}
/** {@inheritDoc} */
@Override
- protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
+ public void setCellBroadcastConfig(int[] configValuesArray, Message response) {
mCm.setCdmaBroadcastConfig(configValuesArray, response);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 0debb42..658de84 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -16,8 +16,6 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
@@ -61,7 +59,7 @@
/**
* {@hide}
*/
-final class CdmaServiceStateTracker extends ServiceStateTracker {
+public class CdmaServiceStateTracker extends ServiceStateTracker {
static final String LOG_TAG = "CDMA";
CDMAPhone phone;
@@ -86,10 +84,10 @@
NITZ_UPDATE_DIFF_DEFAULT);
/**
- * Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
+ * Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
*/
- private int networkType = 0;
- private int newNetworkType = 0;
+ protected int networkType = 0;
+ protected int newNetworkType = 0;
private boolean mCdmaRoaming = false;
private int mRoamingIndicator;
@@ -99,23 +97,21 @@
/**
* Initially assume no data connection.
*/
- private int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
- private int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
- private int mRegistrationState = -1;
- private RegistrantList cdmaDataConnectionAttachedRegistrants = new RegistrantList();
- private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
- private RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
+ protected int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+ protected int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
+ protected int mRegistrationState = -1;
+ protected RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
/**
* Sometimes we get the NITZ time before we know what country we
* are in. Keep the time zone information from the NITZ string so
* we can fix the time zone once know the country.
*/
- private boolean mNeedFixZone = false;
+ protected boolean mNeedFixZone = false;
private int mZoneOffset;
private boolean mZoneDst;
private long mZoneTime;
- private boolean mGotCountryCode = false;
+ protected boolean mGotCountryCode = false;
String mSavedTimeZone;
long mSavedTime;
long mSavedAtTime;
@@ -232,57 +228,6 @@
if (DBG) log("CdmaServiceStateTracker finalized");
}
- void registerForNetworkAttach(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- networkAttachedRegistrants.add(r);
-
- if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForNetworkAttach(Handler h) {
- networkAttachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into Data attached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForCdmaDataConnectionAttached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- cdmaDataConnectionAttachedRegistrants.add(r);
-
- if (cdmaDataConnectionState == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForCdmaDataConnectionAttached(Handler h) {
- cdmaDataConnectionAttachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into Data detached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForCdmaDataConnectionDetached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- cdmaDataConnectionDetachedRegistrants.add(r);
-
- if (cdmaDataConnectionState != ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForCdmaDataConnectionDetached(Handler h) {
- cdmaDataConnectionDetachedRegistrants.remove(h);
- }
-
/**
* Registration point for subscription info ready
* @param h handler to notify
@@ -566,37 +511,21 @@
cm.setRadioPower(true, null);
} else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
DataConnectionTracker dcTracker = phone.mDataConnection;
- if (! dcTracker.isDataConnectionAsDesired()) {
- EventLog.writeEvent(EventLogTags.DATA_NETWORK_STATUS_ON_RADIO_OFF,
- dcTracker.getStateInString(),
- dcTracker.getAnyDataEnabled() ? 1 : 0);
- }
// If it's on and available and we want it off gracefully
powerOffRadioSafely();
} // Otherwise, we're in the desired state
}
+ // TODO: Consider moving this method to DataConnectionTracker
@Override
- protected void powerOffRadioSafely() {
+ public void powerOffRadioSafely() {
DataConnectionTracker dcTracker = phone.mDataConnection;
- Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
- msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
-
synchronized (this) {
if (!mPendingRadioPowerOffAfterDataOff) {
- DataConnectionTracker.State currentState = dcTracker.getState();
- if (currentState != DataConnectionTracker.State.CONNECTED
- && currentState != DataConnectionTracker.State.DISCONNECTING
- && currentState != DataConnectionTracker.State.INITING) {
- msg.arg1 = 0; // tearDown is false as it is not needed.
- dcTracker.sendMessage(msg);
- if (DBG) log("Data disconnected, turn off radio right away.");
- hangupAndPowerOff();
- } else {
- msg.arg1 = 1; // tearDown is true
- dcTracker.sendMessage(msg);
+ if (dcTracker.isAnyActiveDataConnections()) {
+ dcTracker.cleanUpAllConnections();
if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio.");
mPendingRadioPowerOffAfterDataOff = true;
@@ -604,6 +533,10 @@
Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
hangupAndPowerOff();
}
+ } else {
+ dcTracker.cleanUpAllConnections();
+ if (DBG) log("Data disconnected, turn off radio right away.");
+ hangupAndPowerOff();
}
}
}
@@ -647,14 +580,167 @@
}
/**
- * Handle the result of one of the pollState()-related requests
- */
+ * The LTE data connection state, only return true here
+ */
+ protected boolean checkAdditionalDataAvaiable(){
+ return true;
+ }
- @Override
- protected void handlePollStateResult (int what, AsyncResult ar) {
+ /**
+ * Hanlde the PollStateResult message
+ */
+ protected void handlePollStateResultMessage(int what, AsyncResult ar){
int ints[];
String states[];
+ switch (what) {
+ case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
+ states = (String[])ar.result;
+ int registrationState = 4; //[0] registrationState
+ int radioTechnology = -1; //[3] radioTechnology
+ int baseStationId = -1; //[4] baseStationId
+ //[5] baseStationLatitude
+ int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
+ //[6] baseStationLongitude
+ int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
+ int cssIndicator = 0; //[7] init with 0, because it is treated as a boolean
+ int systemId = 0; //[8] systemId
+ int networkId = 0; //[9] networkId
+ int roamingIndicator = -1; //[10] Roaming indicator
+ int systemIsInPrl = 0; //[11] Indicates if current system is in PRL
+ int defaultRoamingIndicator = 0; //[12] Is default roaming indicator from PRL
+ int reasonForDenial = 0; //[13] Denial reason if registrationState = 3
+
+ if (states.length == 14) {
+ try {
+ if (states[0] != null) {
+ registrationState = Integer.parseInt(states[0]);
+ }
+ if (states[3] != null) {
+ radioTechnology = Integer.parseInt(states[3]);
+ }
+ if (states[4] != null) {
+ baseStationId = Integer.parseInt(states[4]);
+ }
+ if (states[5] != null) {
+ baseStationLatitude = Integer.parseInt(states[5]);
+ }
+ if (states[6] != null) {
+ baseStationLongitude = Integer.parseInt(states[6]);
+ }
+ // Some carriers only return lat-lngs of 0,0
+ if (baseStationLatitude == 0 && baseStationLongitude == 0) {
+ baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
+ baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
+ }
+ if (states[7] != null) {
+ cssIndicator = Integer.parseInt(states[7]);
+ }
+ if (states[8] != null) {
+ systemId = Integer.parseInt(states[8]);
+ }
+ if (states[9] != null) {
+ networkId = Integer.parseInt(states[9]);
+ }
+ if (states[10] != null) {
+ roamingIndicator = Integer.parseInt(states[10]);
+ }
+ if (states[11] != null) {
+ systemIsInPrl = Integer.parseInt(states[11]);
+ }
+ if (states[12] != null) {
+ defaultRoamingIndicator = Integer.parseInt(states[12]);
+ }
+ if (states[13] != null) {
+ reasonForDenial = Integer.parseInt(states[13]);
+ }
+ } catch (NumberFormatException ex) {
+ Log.w(LOG_TAG, "error parsing RegistrationState: " + ex);
+ }
+ } else {
+ throw new RuntimeException("Warning! Wrong number of parameters returned from "
+ + "RIL_REQUEST_REGISTRATION_STATE: expected 14 got "
+ + states.length);
+ }
+
+ mRegistrationState = registrationState;
+ // When registration state is roaming and TSB58
+ // roaming indicator is not in the carrier-specified
+ // list of ERIs for home system, mCdmaRoaming is true.
+ mCdmaRoaming =
+ regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
+ newSS.setState (regCodeToServiceState(registrationState));
+
+ if(checkAdditionalDataAvaiable()) {
+ this.newCdmaDataConnectionState =
+ radioTechnologyToDataServiceState(radioTechnology);
+ newSS.setRadioTechnology(radioTechnology);
+ newNetworkType = radioTechnology;
+ }
+
+ newSS.setCssIndicator(cssIndicator);
+ newSS.setSystemAndNetworkId(systemId, networkId);
+ mRoamingIndicator = roamingIndicator;
+ mIsInPrl = (systemIsInPrl == 0) ? false : true;
+ mDefaultRoamingIndicator = defaultRoamingIndicator;
+
+
+ // Values are -1 if not available.
+ newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
+ baseStationLongitude, systemId, networkId);
+
+ if (reasonForDenial == 0) {
+ mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
+ } else if (reasonForDenial == 1) {
+ mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
+ } else {
+ mRegistrationDeniedReason = "";
+ }
+
+ if (mRegistrationState == 3) {
+ if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
+ }
+ break;
+
+ case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
+ String opNames[] = (String[])ar.result;
+
+ if (opNames != null && opNames.length >= 3) {
+ // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC
+ if ((opNames[2] == null) || (opNames[2].length() < 5)
+ || ("00000".equals(opNames[2]))) {
+ opNames[2] = SystemProperties.get(
+ CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000");
+ if (DBG) {
+ log("RIL_REQUEST_OPERATOR.response[2], the numeric, " +
+ " is bad. Using SystemProperties '" +
+ CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC +
+ "'= " + opNames[2]);
+ }
+ }
+ if (cm.getNvState().isNVReady()) {
+ // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
+ // ERI text, so here it is ignored what is coming from the modem.
+ newSS.setOperatorName(null, opNames[1], opNames[2]);
+ } else {
+ newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
+ }
+ } else {
+ Log.w(LOG_TAG, "error parsing opNames");
+ }
+ break;
+ default:
+ Log.e(LOG_TAG, "RIL response handle in wrong phone!"
+ + " Expected CDMA RIL request and get GSM RIL request.");
+ break;
+ }
+ }
+
+ /**
+ * Handle the result of one of the pollState() - related requests
+ */
+ @Override
+ protected void handlePollStateResult (int what, AsyncResult ar) {
// Ignore stale requests from last poll.
if (ar.userObj != pollingContext) return;
@@ -677,155 +763,13 @@
return;
}
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
- err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
+ if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
Log.e(LOG_TAG,
"RIL implementation has returned an error where it must succeed",
ar.exception);
}
} else try {
- switch (what) {
- case EVENT_POLL_STATE_REGISTRATION_CDMA: // Handle RIL_REQUEST_REGISTRATION_STATE.
- states = (String[])ar.result;
-
- int registrationState = 4; //[0] registrationState
- int radioTechnology = -1; //[3] radioTechnology
- int baseStationId = -1; //[4] baseStationId
- //[5] baseStationLatitude
- int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- //[6] baseStationLongitude
- int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- int cssIndicator = 0; //[7] init with 0, because it is treated as a boolean
- int systemId = 0; //[8] systemId
- int networkId = 0; //[9] networkId
- int roamingIndicator = -1; //[10] Roaming indicator
- int systemIsInPrl = 0; //[11] Indicates if current system is in PRL
- int defaultRoamingIndicator = 0; //[12] Is default roaming indicator from PRL
- int reasonForDenial = 0; //[13] Denial reason if registrationState = 3
-
- if (states.length == 14) {
- try {
- if (states[0] != null) {
- registrationState = Integer.parseInt(states[0]);
- }
- if (states[3] != null) {
- radioTechnology = Integer.parseInt(states[3]);
- }
- if (states[4] != null) {
- baseStationId = Integer.parseInt(states[4]);
- }
- if (states[5] != null) {
- baseStationLatitude = Integer.parseInt(states[5]);
- }
- if (states[6] != null) {
- baseStationLongitude = Integer.parseInt(states[6]);
- }
- // Some carriers only return lat-lngs of 0,0
- if (baseStationLatitude == 0 && baseStationLongitude == 0) {
- baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
- baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
- }
- if (states[7] != null) {
- cssIndicator = Integer.parseInt(states[7]);
- }
- if (states[8] != null) {
- systemId = Integer.parseInt(states[8]);
- }
- if (states[9] != null) {
- networkId = Integer.parseInt(states[9]);
- }
- if (states[10] != null) {
- roamingIndicator = Integer.parseInt(states[10]);
- }
- if (states[11] != null) {
- systemIsInPrl = Integer.parseInt(states[11]);
- }
- if (states[12] != null) {
- defaultRoamingIndicator = Integer.parseInt(states[12]);
- }
- if (states[13] != null) {
- reasonForDenial = Integer.parseInt(states[13]);
- }
- } catch (NumberFormatException ex) {
- Log.w(LOG_TAG, "error parsing RegistrationState: " + ex);
- }
- } else {
- throw new RuntimeException("Warning! Wrong number of parameters returned from "
- + "RIL_REQUEST_REGISTRATION_STATE: expected 14 got "
- + states.length);
- }
-
- mRegistrationState = registrationState;
- // When registration state is roaming and TSB58
- // roaming indicator is not in the carrier-specified
- // list of ERIs for home system, mCdmaRoaming is true.
- mCdmaRoaming =
- regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
- newSS.setState (regCodeToServiceState(registrationState));
-
- this.newCdmaDataConnectionState =
- radioTechnologyToDataServiceState(radioTechnology);
- newSS.setRadioTechnology(radioTechnology);
- newNetworkType = radioTechnology;
-
- newSS.setCssIndicator(cssIndicator);
- newSS.setSystemAndNetworkId(systemId, networkId);
- mRoamingIndicator = roamingIndicator;
- mIsInPrl = (systemIsInPrl == 0) ? false : true;
- mDefaultRoamingIndicator = defaultRoamingIndicator;
-
-
- // Values are -1 if not available.
- newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
- baseStationLongitude, systemId, networkId);
-
- if (reasonForDenial == 0) {
- mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN;
- } else if (reasonForDenial == 1) {
- mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH;
- } else {
- mRegistrationDeniedReason = "";
- }
-
- if (mRegistrationState == 3) {
- if (DBG) log("Registration denied, " + mRegistrationDeniedReason);
- }
- break;
-
- case EVENT_POLL_STATE_OPERATOR_CDMA: // Handle RIL_REQUEST_OPERATOR
- String opNames[] = (String[])ar.result;
-
- if (opNames != null && opNames.length >= 3) {
- // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC
- if ((opNames[2] == null) || (opNames[2].length() < 5)
- || ("00000".equals(opNames[2]))) {
- opNames[2] = SystemProperties.get(
- CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000");
- if (DBG) {
- log("RIL_REQUEST_OPERATOR.response[2], the numeric, " +
- " is bad. Using SystemProperties '" +
- CDMAPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC +
- "'= " + opNames[2]);
- }
- }
- if (cm.getRadioState().isNVReady()) {
- // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
- // ERI text, so here it is ignored what is coming from the modem.
- newSS.setOperatorName(null, opNames[1], opNames[2]);
- } else {
- newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
- }
- } else {
- Log.w(LOG_TAG, "error parsing opNames");
- }
- break;
-
- default:
- Log.e(LOG_TAG, "RIL response handle in wrong phone!"
- + " Expected CDMA RIL request and get GSM RIL request.");
- break;
- }
-
+ handlePollStateResultMessage(what, ar);
} catch (RuntimeException ex) {
Log.e(LOG_TAG, "Exception while polling service state. "
+ "Probably malformed RIL response.", ex);
@@ -896,9 +840,8 @@
}
- private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, false);
+ protected void setSignalStrengthDefaultValues() {
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
}
/**
@@ -909,7 +852,7 @@
* and start over again if the radio notifies us that some
* event has changed
*/
- private void
+ protected void
pollState() {
pollingContext = new int[1];
pollingContext[0] = 0;
@@ -964,24 +907,24 @@
}
}
- private static String networkTypeToString(int type) {
+ protected static String networkTypeToString(int type) {
String ret = "unknown";
switch (type) {
- case DATA_ACCESS_CDMA_IS95A:
- case DATA_ACCESS_CDMA_IS95B:
+ case ServiceState.RADIO_TECHNOLOGY_IS95A:
+ case ServiceState.RADIO_TECHNOLOGY_IS95B:
ret = "CDMA";
break;
- case DATA_ACCESS_CDMA_1xRTT:
+ case ServiceState.RADIO_TECHNOLOGY_1xRTT:
ret = "CDMA - 1xRTT";
break;
- case DATA_ACCESS_CDMA_EvDo_0:
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_0:
ret = "CDMA - EvDo rev. 0";
break;
- case DATA_ACCESS_CDMA_EvDo_A:
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_A:
ret = "CDMA - EvDo rev. A";
break;
- case DATA_ACCESS_CDMA_EvDo_B:
+ case ServiceState.RADIO_TECHNOLOGY_EVDO_B:
ret = "CDMA - EvDo rev. B";
break;
default:
@@ -994,7 +937,7 @@
return ret;
}
- private void fixTimeZone(String isoCountryCode) {
+ protected void fixTimeZone(String isoCountryCode) {
TimeZone zone = null;
// If the offset is (0, false) and the time zone property
// is set, use the time zone property rather than GMT.
@@ -1031,7 +974,7 @@
}
}
- private void pollStateDone() {
+ protected void pollStateDone() {
if (DBG) log("Poll ServiceState done: oldSS=[" + ss + "] newSS=[" + newSS + "]");
boolean hasRegistered =
@@ -1095,7 +1038,7 @@
}
if (hasRegistered) {
- networkAttachedRegistrants.notifyRegistrants();
+ mNetworkAttachedRegistrants.notifyRegistrants();
}
if (hasChanged) {
@@ -1150,11 +1093,11 @@
}
if (hasCdmaDataConnectionAttached) {
- cdmaDataConnectionAttachedRegistrants.notifyRegistrants();
+ mAttachedRegistrants.notifyRegistrants();
}
if (hasCdmaDataConnectionDetached) {
- cdmaDataConnectionDetachedRegistrants.notifyRegistrants();
+ mDetachedRegistrants.notifyRegistrants();
}
if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
@@ -1162,11 +1105,11 @@
}
if (hasRoamingOn) {
- roamingOnRegistrants.notifyRegistrants();
+ mRoamingOnRegistrants.notifyRegistrants();
}
if (hasRoamingOff) {
- roamingOffRegistrants.notifyRegistrants();
+ mRoamingOffRegistrants.notifyRegistrants();
}
if (hasLocationChanged) {
@@ -1234,7 +1177,7 @@
* send signal-strength-changed notification if changed
* Called both for solicited and unsolicited signal strength updates
*/
- private void
+ protected void
onSignalStrengthResult(AsyncResult ar) {
SignalStrength oldSignalStrength = mSignalStrength;
@@ -1253,7 +1196,7 @@
//log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
// cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
- evdoRssi, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, false);
+ evdoRssi, evdoEcio, evdoSnr, false);
}
try {
@@ -1279,6 +1222,7 @@
case 7: // RADIO_TECHNOLOGY_EVDO_0
case 8: // RADIO_TECHNOLOGY_EVDO_A
case 12: // RADIO_TECHNOLOGY_EVDO_B
+ case 13: // RADIO_TECHNOLOGY_EHRPD
retVal = ServiceState.STATE_IN_SERVICE;
break;
default:
@@ -1289,7 +1233,7 @@
}
/** code is registration state 0-5 from TS 27.007 7.2 */
- private int
+ protected int
regCodeToServiceState(int code) {
switch (code) {
case 0: // Not searching and not registered
@@ -1319,6 +1263,13 @@
}
/**
+ * TODO: In the future, we need remove getCurrentCdmaDataConnectionState
+ */
+ public int getCurrentDataConnectionState() {
+ return cdmaDataConnectionState;
+ }
+
+ /**
* code is registration state 0-5 from TS 27.007 7.2
* returns true if registered roam, false otherwise
*/
@@ -1662,7 +1613,7 @@
* @return true if phone is camping on a technology
* that could support voice and data simultaneously.
*/
- boolean isConcurrentVoiceAndData() {
+ public boolean isConcurrentVoiceAndDataAllowed() {
// Note: it needs to be confirmed which CDMA network types
// can support voice and data calls concurrently.
// For the time-being, the return value will be false.
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
old mode 100644
new mode 100755
index cf06dab..7a45e15
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -34,6 +34,9 @@
import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.BitwiseOutputStream;
+import android.content.res.Resources;
+
+
/**
* An object to encode and decode CDMA SMS bearer data.
@@ -582,7 +585,6 @@
uData.payload = new byte[0];
uData.numFields = 0;
} else {
- uData.payload = uData.payload;
uData.numFields = uData.payload.length;
}
} else {
@@ -910,6 +912,16 @@
return true;
}
+ private static String decodeUtf8(byte[] data, int offset, int numFields)
+ throws CodingException
+ {
+ try {
+ return new String(data, offset, numFields, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException ex) {
+ throw new CodingException("UTF-8 decode failed: " + ex);
+ }
+ }
+
private static String decodeUtf16(byte[] data, int offset, int numFields)
throws CodingException
{
@@ -994,9 +1006,15 @@
}
switch (userData.msgEncoding) {
case UserData.ENCODING_OCTET:
+ /*
+ * Octet decoding depends on the carrier service.
+ */
+ boolean decodingtypeUTF8 = Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_sms_utf8_support);
+
// Strip off any padding bytes, meaning any differences between the length of the
- // array and the target length specified by numFields. This is to avoid any confusion
- // by code elsewhere that only considers the payload array length.
+ // array and the target length specified by numFields. This is to avoid any
+ // confusion by code elsewhere that only considers the payload array length.
byte[] payload = new byte[userData.numFields];
int copyLen = userData.numFields < userData.payload.length
? userData.numFields : userData.payload.length;
@@ -1004,9 +1022,13 @@
System.arraycopy(userData.payload, 0, payload, 0, copyLen);
userData.payload = payload;
- // There are many devices in the market that send 8bit text sms (latin encoded) as
- // octet encoded.
- userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
+ if (!decodingtypeUTF8) {
+ // There are many devices in the market that send 8bit text sms (latin encoded) as
+ // octet encoded.
+ userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
+ } else {
+ userData.payloadStr = decodeUtf8(userData.payload, offset, userData.numFields);
+ }
break;
case UserData.ENCODING_IA5:
case UserData.ENCODING_7BIT_ASCII:
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index c17197e..36094a1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -33,6 +33,7 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import com.android.internal.telephony.CallTracker;
import android.text.TextUtils;
import android.util.Log;
@@ -72,6 +73,7 @@
import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.IccVmNotSupportedException;
+import com.android.internal.telephony.ServiceStateTracker;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -100,9 +102,6 @@
// Instance Variables
GsmCallTracker mCT;
GsmServiceStateTracker mSST;
- GsmSMSDispatcher mSMS;
- SIMRecords mSIMRecords;
- SimCard mSimCard;
CatService mStkService;
ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
@@ -160,7 +159,7 @@
mCM.registerForOn(this, EVENT_RADIO_ON, null);
mCM.setOnUSSD(this, EVENT_USSD, null);
mCM.setOnSuppServiceNotification(this, EVENT_SSN, null);
- mSST.registerForNetworkAttach(this, EVENT_REGISTERED_TO_NETWORK, null);
+ mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
if (false) {
try {
@@ -210,7 +209,7 @@
mSIMRecords.unregisterForRecordsLoaded(this); //EVENT_SIM_RECORDS_LOADED
mCM.unregisterForOffOrNotAvailable(this); //EVENT_RADIO_OFF_OR_NOT_AVAILABLE
mCM.unregisterForOn(this); //EVENT_RADIO_ON
- mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK
+ mSST.unregisterForNetworkAttached(this); //EVENT_REGISTERED_TO_NETWORK
mCM.unSetOnUSSD(this);
mCM.unSetOnSuppServiceNotification(this);
@@ -283,6 +282,14 @@
return mSIMRecords.getVoiceCallForwardingFlag();
}
+ public CallTracker getCallTracker() {
+ return mCT;
+ }
+
+ public ServiceStateTracker getServiceStateTracker() {
+ return mSST;
+ }
+
public List<? extends MmiCode>
getPendingMmiCodes() {
return mPendingMMIs;
@@ -305,7 +312,7 @@
mDataConnection.isApnTypeActive(apnType) == false) {
ret = DataState.DISCONNECTED;
} else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
- switch (mDataConnection.getState()) {
+ switch (mDataConnection.getState(apnType)) {
case FAILED:
case IDLE:
ret = DataState.DISCONNECTED;
@@ -314,7 +321,7 @@
case CONNECTED:
case DISCONNECTING:
if ( mCT.state != Phone.State.IDLE
- && !mSST.isConcurrentVoiceAndData()) {
+ && !mSST.isConcurrentVoiceAndDataAllowed()) {
ret = DataState.SUSPENDED;
} else {
ret = DataState.CONNECTED;
@@ -404,7 +411,7 @@
mNotifier.notifySignalStrength(this);
}
- /*package*/ void
+ public void
notifyDataConnectionFailed(String reason, String apnType) {
mNotifier.notifyDataConnectionFailed(this, reason, apnType);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 7dc2504..0870d5b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -374,11 +374,11 @@
} else if (phone.getIccCard().getState() != SimCard.State.READY) {
return DisconnectCause.ICC_ERROR;
} else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
- if (phone.mSST.rs.isCsRestricted()) {
+ if (phone.mSST.mRestrictedState.isCsRestricted()) {
return DisconnectCause.CS_RESTRICTED;
- } else if (phone.mSST.rs.isCsEmergencyRestricted()) {
+ } else if (phone.mSST.mRestrictedState.isCsEmergencyRestricted()) {
return DisconnectCause.CS_RESTRICTED_EMERGENCY;
- } else if (phone.mSST.rs.isCsNormalRestricted()) {
+ } else if (phone.mSST.mRestrictedState.isCsNormalRestricted()) {
return DisconnectCause.CS_RESTRICTED_NORMAL;
} else {
return DisconnectCause.ERROR_UNSPECIFIED;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 4689b2d..b0b2ac5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -19,10 +19,12 @@
import android.os.Message;
import android.util.Log;
import android.util.Patterns;
+import android.text.TextUtils;
import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.RetryManager;
@@ -34,11 +36,11 @@
private static final String LOG_TAG = "GSM";
//***** Instance Variables
- private ApnSetting apn;
-
+ protected int mProfileId = RILConstants.DATA_PROFILE_DEFAULT;
+ protected String mActiveApnType = Phone.APN_TYPE_DEFAULT;
//***** Constructor
- private GsmDataConnection(GSMPhone phone, String name, RetryManager rm) {
- super(phone, name, rm);
+ private GsmDataConnection(PhoneBase phone, String name, int id, RetryManager rm) {
+ super(phone, name, id, rm);
}
/**
@@ -49,15 +51,14 @@
* @param rm the RetryManager
* @return GsmDataConnection that was created.
*/
- static GsmDataConnection makeDataConnection(GSMPhone phone, int id, RetryManager rm) {
+ static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm) {
synchronized (mCountLock) {
mCount += 1;
}
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount, rm);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount,
+ id, rm);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
- gsmDc.mId = id;
- gsmDc.mRetryMgr = rm;
return gsmDc;
}
@@ -71,13 +72,13 @@
@Override
protected
void onConnect(ConnectionParams cp) {
- apn = cp.apn;
+ mApn = cp.apn;
- if (DBG) log("Connecting to carrier: '" + apn.carrier
- + "' APN: '" + apn.apn
- + "' proxy: '" + apn.proxy + "' port: '" + apn.port);
+ if (DBG) log("Connecting to carrier: '" + mApn.carrier
+ + "' APN: '" + mApn.apn
+ + "' proxy: '" + mApn.proxy + "' port: '" + mApn.port);
- setHttpProxy (apn.proxy, apn.port);
+ setHttpProxy (mApn.proxy, mApn.port);
createTime = -1;
lastFailTime = -1;
@@ -87,35 +88,47 @@
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
msg.obj = cp;
- int authType = apn.authType;
+ int authType = mApn.authType;
if (authType == -1) {
- authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
+ authType = (mApn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
RILConstants.SETUP_DATA_AUTH_NONE;
}
String protocol;
if (phone.getServiceState().getRoaming()) {
- protocol = apn.roamingProtocol;
+ protocol = mApn.roamingProtocol;
} else {
- protocol = apn.protocol;
+ protocol = mApn.protocol;
}
phone.mCM.setupDataCall(
Integer.toString(RILConstants.SETUP_DATA_TECH_GSM),
- Integer.toString(RILConstants.DATA_PROFILE_DEFAULT),
- apn.apn, apn.user, apn.password, Integer.toString(authType),
+ Integer.toString(mProfileId),
+ mApn.apn, mApn.user, mApn.password,
+ Integer.toString(authType),
protocol, msg);
}
- @Override
- protected void clearSettings() {
- super.clearSettings();
- apn = null;
+ public void setProfileId(int profileId) {
+ mProfileId = profileId;
+ }
+
+ public int getProfileId() {
+ return mProfileId;
+ }
+
+ public int getCid() {
+ // 'cid' has been defined in parent class
+ return cid;
+ }
+
+ public void setActiveApnType(String apnType) {
+ mActiveApnType = apnType;
}
@Override
public String toString() {
- return "State=" + getCurrentState().getName() + " Apn=" + apn +
+ return "State=" + getCurrentState().getName() + " Apn=" + mApn +
" create=" + createTime + " lastFail=" + lastFailTime +
" lastFailCause=" + lastFailCause;
}
@@ -129,11 +142,12 @@
// Do not apply the race condition workaround for MMS APN
// if Proxy is an IP-address.
// Otherwise, the default APN will not be restored anymore.
- if (!apn.types[0].equals(Phone.APN_TYPE_MMS)
- || !isIpAddress(apn.mmsProxy)) {
+ if (!mApn.types[0].equals(Phone.APN_TYPE_MMS)
+ || !isIpAddress(mApn.mmsProxy)) {
log(String.format(
"isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s",
- apn.types[0], Phone.APN_TYPE_MMS, apn.mmsProxy, isIpAddress(apn.mmsProxy)));
+ mApn.types[0], Phone.APN_TYPE_MMS, mApn.mmsProxy,
+ isIpAddress(mApn.mmsProxy)));
return false;
}
}
@@ -145,27 +159,41 @@
Log.d(LOG_TAG, "[" + getName() + "] " + s);
}
- public ApnSetting getApn() {
- return this.apn;
- }
-
private void setHttpProxy(String httpProxy, String httpPort) {
- if (httpProxy == null || httpProxy.length() == 0) {
- phone.setSystemProperty("net.gprs.http-proxy", null);
- return;
- }
- if (httpPort == null || httpPort.length() == 0) {
- httpPort = "8080"; // Default to port 8080
- }
+ if (DBG) log("set http proxy for"
+ + "' APN: '" + mActiveApnType
+ + "' proxy: '" + mApn.proxy + "' port: '" + mApn.port);
+ if(TextUtils.equals(mActiveApnType, Phone.APN_TYPE_DEFAULT)) {
+ if (httpProxy == null || httpProxy.length() == 0) {
+ phone.setSystemProperty("net.gprs.http-proxy", null);
+ return;
+ }
- phone.setSystemProperty("net.gprs.http-proxy",
- "http://" + httpProxy + ":" + httpPort + "/");
+ if (httpPort == null || httpPort.length() == 0) {
+ httpPort = "8080"; // Default to port 8080
+ }
+
+ phone.setSystemProperty("net.gprs.http-proxy",
+ "http://" + httpProxy + ":" + httpPort + "/");
+ } else {
+ if (httpProxy == null || httpProxy.length() == 0) {
+ phone.setSystemProperty("net.gprs.http-proxy." + mActiveApnType, null);
+ return;
+ }
+
+ if (httpPort == null || httpPort.length() == 0) {
+ httpPort = "8080"; // Default to port 8080
+ }
+
+ phone.setSystemProperty("net.gprs.http-proxy." + mActiveApnType,
+ "http://" + httpProxy + ":" + httpPort + "/");
+ }
}
private boolean isIpAddress(String address) {
if (address == null) return false;
- return Patterns.IP_ADDRESS.matcher(apn.mmsProxy).matches();
+ return Patterns.IP_ADDRESS.matcher(address).matches();
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index c57f2f1..22c4640 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -22,11 +22,14 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemClock;
@@ -36,24 +39,32 @@
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
+import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
+import android.preference.PreferenceManager;
import com.android.internal.R;
+import com.android.internal.telephony.ApnContext;
import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataCallState;
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.RetryManager;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.DataConnection.FailCause;
+import com.android.internal.telephony.RILConstants;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.HashMap;
/**
@@ -62,7 +73,6 @@
public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected final String LOG_TAG = "GSM";
- private GSMPhone mGsmPhone;
/**
* Handles changes to the APN db.
*/
@@ -92,64 +102,60 @@
//useful for debugging
boolean mFailNextConnect = false;
- /**
- * allApns holds all apns for this sim spn, retrieved from
- * the Carrier DB.
- *
- * Create once after simcard info is loaded
- */
- private ArrayList<ApnSetting> mAllApns = null;
-
- /**
- * waitingApns holds all apns that are waiting to be connected
- *
- * It is a subset of allApns and has the same format
- */
- private ArrayList<ApnSetting> mWaitingApns = null;
- private int mWaitingApnsPermanentFailureCountDown = 0;
- private ApnSetting mPreferredApn = null;
-
- /** The DataConnection being setup */
- private GsmDataConnection mPendingDataConnection;
-
- /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
- private HashMap<String, Integer> mApnToDataConnectionId =
- new HashMap<String, Integer>();
-
- /** Is packet service restricted by network */
- private boolean mIsPsRestricted = false;
-
//***** Constants
private static final int POLL_PDP_MILLIS = 5 * 1000;
private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
+ private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "type";
static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
static final String APN_ID = "apn_id";
private boolean canSetPreferApn = false;
+ @Override
+ protected void onActionIntentReconnectAlarm(Intent intent) {
+ log("GPRS reconnect alarm. Previous state was " + mState);
+
+ String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
+ String type = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
+ ApnContext apnContext = mApnContexts.get(type);
+ if (apnContext != null) {
+ apnContext.setReason(reason);
+ if (apnContext.getState() == State.FAILED) {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 0; // tearDown is false
+ msg.obj = (ApnContext)apnContext;
+ sendMessage(msg);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext));
+ }
+ }
+
/** Watches for changes to the APN db. */
private ApnChangeObserver mApnObserver;
//***** Constructor
- GsmDataConnectionTracker(GSMPhone p) {
+ public GsmDataConnectionTracker(PhoneBase p) {
super(p);
- mGsmPhone = p;
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
- p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
- p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
- p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
- p.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null);
- p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
- p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
- p.mSST.registerForPsRestrictedEnabled(this, EVENT_PS_RESTRICT_ENABLED, null);
- p.mSST.registerForPsRestrictedDisabled(this, EVENT_PS_RESTRICT_DISABLED, null);
+ p.getCallTracker().registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
+ p.getCallTracker().registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
+ p.getServiceStateTracker().registerForDataConnectionAttached(this,
+ EVENT_DATA_CONNECTION_ATTACHED, null);
+ p.getServiceStateTracker().registerForDataConnectionDetached(this,
+ EVENT_DATA_CONNECTION_DETACHED, null);
+ p.getServiceStateTracker().registerForRoamingOn(this, EVENT_ROAMING_ON, null);
+ p.getServiceStateTracker().registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
+ p.getServiceStateTracker().registerForPsRestrictedEnabled(this,
+ EVENT_PS_RESTRICT_ENABLED, null);
+ p.getServiceStateTracker().registerForPsRestrictedDisabled(this,
+ EVENT_PS_RESTRICT_DISABLED, null);
mDataConnectionTracker = this;
mResolver = mPhone.getContext().getContentResolver();
@@ -159,33 +165,58 @@
Telephony.Carriers.CONTENT_URI, true, mApnObserver);
/** Create the default connection */
- createDataConnection(Phone.APN_TYPE_DEFAULT);
+ mApnContexts = new ConcurrentHashMap<String, ApnContext>();
+ initApncontextsAndDataConnection();
broadcastMessenger();
}
@Override
public void dispose() {
+ cleanUpAllConnections(false, null);
+
super.dispose();
//Unregister for all events
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
- mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
+ mPhone.mSIMRecords.unregisterForRecordsLoaded(this);
mPhone.mCM.unregisterForDataNetworkStateChanged(this);
- mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
- mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
- mGsmPhone.mSST.unregisterForGprsAttached(this);
- mGsmPhone.mSST.unregisterForGprsDetached(this);
- mGsmPhone.mSST.unregisterForRoamingOn(this);
- mGsmPhone.mSST.unregisterForRoamingOff(this);
- mGsmPhone.mSST.unregisterForPsRestrictedEnabled(this);
- mGsmPhone.mSST.unregisterForPsRestrictedDisabled(this);
+ mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
+ mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
+ mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
+ mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
+ mPhone.getServiceStateTracker().unregisterForRoamingOn(this);
+ mPhone.getServiceStateTracker().unregisterForRoamingOff(this);
+ mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
+ mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
+ mApnContexts.clear();
destroyDataConnections();
}
+ /**
+ * 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.
+ */
+ @Override
+ protected boolean isDataPossible() {
+ boolean possible = (isDataAllowed()
+ && getAnyDataEnabled() && (getOverallState() == State.CONNECTED));
+ if (!possible && DBG && isDataAllowed()) {
+ log("Data not possible. No coverage: dataState = " + getOverallState());
+ }
+ return possible;
+ }
+
@Override
protected void finalize() {
if(DBG) log("finalize");
@@ -196,41 +227,231 @@
return INTENT_RECONNECT_ALARM;
}
+ protected void initApncontextsAndDataConnection() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
+ boolean defaultEnabled = !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false);
+ // create default type context only if enabled
+ if (defaultEnabled) {
+ ApnContext apnContext = new ApnContext(Phone.APN_TYPE_DEFAULT, LOG_TAG);
+ mApnContexts.put(apnContext.getApnType(), apnContext);
+ createDataConnection(Phone.APN_TYPE_DEFAULT);
+ }
+ }
+
@Override
- protected void setState(State s) {
- if (DBG) log ("setState: " + s);
- if (mState != s) {
- EventLog.writeEvent(EventLogTags.GSM_DATA_STATE_CHANGE, mState.toString(), s.toString());
- mState = s;
+ protected LinkProperties getLinkProperties(String apnType) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext != null && apnContext.getDataConnection() != null) {
+ if (DBG) log("get active pdp is not null, return link properites for " + apnType);
+ return apnContext.getDataConnection().getLinkProperties();
+ } else {
+ if (DBG) log("return new LinkProperties");
+ return new LinkProperties();
+ }
+ }
+
+ @Override
+ protected LinkCapabilities getLinkCapabilities(String apnType) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext!=null && apnContext.getDataConnection() != null) {
+ if (DBG) log("get active pdp is not null, return link Capabilities for " + apnType);
+ return apnContext.getDataConnection().getLinkCapabilities();
+ } else {
+ if (DBG) log("return new LinkCapabilities");
+ return new LinkCapabilities();
+ }
+ }
+
+ @Override
+ // Return all active apn types
+ public synchronized String[] getActiveApnTypes() {
+ if (DBG) log("get all active apn types");
+ ArrayList<String> result = new ArrayList<String>();
+
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ result.add(apnContext.getApnType());
}
- if (mState == State.FAILED) {
- if (mWaitingApns != null)
- mWaitingApns.clear(); // when tear down the connection and set to IDLE
+ return (String[])result.toArray(new String[0]);
+ }
+
+ @Override
+ /**
+ * Return DEFAULT APN due to the limit of the interface
+ */
+ public synchronized String getActiveApnString() {
+ if (DBG) log( "get default active apn string");
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ if (defaultApnContext != null && defaultApnContext.getApnSetting() != null) {
+ return defaultApnContext.getApnSetting().apn;
+ }
+ return null;
+ }
+
+ // Return active apn of specific apn type
+ public synchronized String getActiveApnString(String apnType) {
+ if (DBG) log( "get active apn string for type:" + apnType);
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext != null && apnContext.getApnSetting() != null) {
+ return apnContext.getApnSetting().apn;
+ }
+ return null;
+ }
+
+ @Override
+ protected void setState(State s) {
+ if (DBG) log("setState should not be used in GSM" + s);
+ }
+
+ // Return state of specific apn type
+ @Override
+ public synchronized State getState(String apnType) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext != null) {
+ return apnContext.getState();
+ }
+ return State.FAILED;
+ }
+
+ // Return state of overall
+ public State getOverallState() {
+ boolean isConnecting = false;
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ if (apnContext.getState() == State.CONNECTED ||
+ apnContext.getState() == State.DISCONNECTING) {
+ if (DBG) log("overall state is CONNECTED");
+ return State.CONNECTED;
+ }
+ else if (apnContext.getState() == State.CONNECTING
+ || apnContext.getState() == State.INITING) {
+ isConnecting = true;
+ }
+ }
+ if (isConnecting) {
+ if (DBG) log( "overall state is CONNECTING");
+ return State.CONNECTING;
+ } else {
+ if (DBG) log( "overall state is IDLE");
+ return State.IDLE;
}
}
/**
- * The data connection is expected to be setup while device
- * 1. has sim card
- * 2. registered to gprs service
- * 3. user doesn't explicitly disable data service
- * 4. wifi is not on
+ * Ensure that we are connected to an APN of the specified type.
*
- * @return false while no data connection if all above requirements are met.
+ * @param type the APN type
+ * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
+ * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
+ * broadcast will be sent by the ConnectivityManager when a
+ * connection to the APN has been established.
*/
@Override
- public boolean isDataConnectionAsDesired() {
- boolean roaming = mPhone.getServiceState().getRoaming();
+ public synchronized int enableApnType(String apnType) {
+ if (DBG) log("calling enableApnType with type:" + apnType);
- if (mGsmPhone.mSIMRecords.getRecordsLoaded() &&
- mGsmPhone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
- (!roaming || getDataOnRoamingEnabled()) &&
- !mIsWifiConnected &&
- !mIsPsRestricted ) {
- return (mState == State.CONNECTED);
+ if (!isApnTypeAvailable(apnType)) {
+ if (DBG) log("type not available");
+ return Phone.APN_TYPE_NOT_AVAILABLE;
}
- return true;
+
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext==null) {
+ // Is there a Proxy type for this?
+ apnContext = getProxyActiveApnType(apnType);
+ if (apnContext != null ) {
+ notifyApnIdUpToCurrent(Phone.REASON_APN_SWITCHED, apnContext, apnType);
+ return Phone.APN_REQUEST_STARTED;
+ }
+ apnContext = new ApnContext(apnType, LOG_TAG);
+ if (DBG) log("New apn type context for type "+apnType);
+ mApnContexts.put(apnType, apnContext);
+ }
+
+ // If already active, return
+ log("enableApnType(" + apnType + ")" + ", mState(" + apnContext.getState() + ")");
+
+ if (apnContext.getState() == State.INITING) {
+ if (DBG) log("return APN_REQUEST_STARTED");
+ return Phone.APN_REQUEST_STARTED;
+ }
+ else if (apnContext.getState() == State.CONNECTED) {
+ if (DBG) log("return APN_ALREADY_ACTIVE");
+ return Phone.APN_ALREADY_ACTIVE;
+ }
+ else if (apnContext.getState() == State.DISCONNECTING) {
+ if (DBG) log("requested APN while disconnecting");
+ apnContext.setPendingAction(ApnContext.PENDING_ACTION_RECONNECT);
+ return Phone.APN_REQUEST_STARTED;
+ }
+
+ if (DBG) log("new apn request for type " + apnType + " is to be handled");
+ sendMessage(obtainMessage(EVENT_ENABLE_NEW_APN, apnContext));
+ if (DBG) log("return APN_REQUEST_STARTED");
+ return Phone.APN_REQUEST_STARTED;
+ }
+
+ // Returns for ex: if HIGHPRI is supported by DEFAULT
+ public ApnContext getProxyActiveApnType(String type) {
+
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+
+ while(it.hasNext()) {
+ ApnContext apnContext = it.next();
+ if (apnContext.getApnSetting() != null && mActiveApn.canHandleType(type))
+ return apnContext;
+ }
+ return null;
+ }
+
+ // A new APN has gone active and needs to send events to catch up with the
+ // current condition
+ private void notifyApnIdUpToCurrent(String reason, ApnContext apnContext, String type) {
+ switch (apnContext.getState()) {
+ case IDLE:
+ case INITING:
+ break;
+ case CONNECTING:
+ case SCANNING:
+ mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
+ break;
+ case CONNECTED:
+ case DISCONNECTING:
+ mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTING);
+ mPhone.notifyDataConnection(reason, type, Phone.DataState.CONNECTED);
+ break;
+ }
+ }
+
+ @Override
+ public synchronized int disableApnType(String type) {
+ if (DBG) log("calling disableApnType with type:" + type);
+ ApnContext apnContext = mApnContexts.get(type);
+
+ if (apnContext != null) {
+ apnContext.setPendingAction(ApnContext.PENDING_ACTION_APN_DISABLE);
+
+ if (apnContext.getState() != State.IDLE && apnContext.getState() != State.FAILED) {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true;
+ apnContext.setReason(Phone.REASON_DATA_DISABLED);
+ msg.obj = apnContext;
+ sendMessage(msg);
+ if (DBG) log("return APN_REQUEST_STARTED");
+ return Phone.APN_REQUEST_STARTED;
+ } else {
+ if (DBG) log("return APN_ALREADY_INACTIVE");
+ return Phone.APN_ALREADY_INACTIVE;
+ }
+
+ } else {
+ if (DBG)
+ log("no apn context was found, return APN_REQUEST_FAILED");
+ return Phone.APN_REQUEST_FAILED;
+ }
}
@Override
@@ -249,12 +470,53 @@
return false;
}
+ protected boolean isEnabled(String apnType) {
+ ApnContext apnContext = mApnContexts.get(apnType);
+ if (apnContext == null) return false;
+ if (apnContext.getState() == State.DISCONNECTING
+ && apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Report on whether data connectivity is enabled for any APN.
+ * @return {@code false} if data connectivity has been explicitly disabled,
+ * {@code true} otherwise.
+ */
+ @Override
+ public synchronized boolean getAnyDataEnabled() {
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+
+ if (!(mInternalDataEnabled && mDataEnabled)) return false;
+ if (mApnContexts.isEmpty()) return false;
+ while (it.hasNext()) {
+ ApnContext apnContext= it.next();
+ // Make sure we dont have a context that going down
+ // and is explicitly disabled.
+ if (!(apnContext.getState() == State.DISCONNECTING
+ && apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isDataAllowed(ApnContext apnContext) {
+ if(apnContext.getState() == State.DISCONNECTING
+ && apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
+ return false;
+ }
+ return isDataAllowed();
+ }
+
//****** Called from ServiceStateTracker
/**
* Invoked when ServiceStateTracker observes a transition from GPRS
* attach to detach.
*/
- protected void onGprsDetached() {
+ protected void onDataConnectionDetached() {
/*
* We presently believe it is unnecessary to tear down the PDP context
* when GPRS detaches, but we should stop the network polling.
@@ -263,27 +525,29 @@
notifyDataConnection(Phone.REASON_GPRS_DETACHED);
}
- private void onGprsAttached() {
- if (mState == State.CONNECTED) {
+ private void onDataConnectionAttached() {
+ if (getOverallState() == State.CONNECTED) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
- if (mState == State.FAILED) {
- cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
- mRetryMgr.resetRetryCount();
+ // Only check for default APN state
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ if (defaultApnContext.getState() == State.FAILED) {
+ cleanUpConnection(false, defaultApnContext);
+ defaultApnContext.getDataConnection().resetRetryCount();
}
- trySetupData(Phone.REASON_GPRS_ATTACHED);
+ trySetupData(Phone.REASON_GPRS_ATTACHED, Phone.APN_TYPE_DEFAULT);
}
}
@Override
protected boolean isDataAllowed() {
- int gprsState = mGsmPhone.mSST.getCurrentGprsState();
- boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
+ int gprsState = mPhone.getServiceStateTracker().getCurrentDataConnectionState();
+ boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
boolean allowed =
(gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
- mGsmPhone.mSIMRecords.getRecordsLoaded() &&
+ mPhone.mSIMRecords.getRecordsLoaded() &&
mPhone.getState() == Phone.State.IDLE &&
mInternalDataEnabled &&
(!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
@@ -294,7 +558,7 @@
if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
reason += " - gprs= " + gprsState;
}
- if (!mGsmPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded";
+ if (!mPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded";
if (mPhone.getState() != Phone.State.IDLE) {
reason += " - PhoneState= " + mPhone.getState();
}
@@ -309,94 +573,192 @@
return allowed;
}
- private boolean trySetupData(String reason) {
- if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
+ private boolean trySetupData(String reason, String type) {
+ if (DBG)
+ log("***trySetupData for type:" + type+" due to " + (reason == null ? "(unspecified)" : reason));
+ log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
+ if (type == null) {
+ type = Phone.APN_TYPE_DEFAULT;
+ }
+
+ ApnContext apnContext = mApnContexts.get(type);
+
+ if (apnContext == null ){
+ if (DBG) log("***new apn context for type:" + type);
+ apnContext = new ApnContext(type, LOG_TAG);
+ if (apnContext == null) {
+ if (DBG) log("***new apn context failed ");
+ return false;
+ }
+ mApnContexts.put(type, apnContext);
+ }
+ apnContext.setReason(reason);
+
+ return trySetupData(apnContext);
+
+ }
+
+ private boolean trySetupData(ApnContext apnContext) {
+
+ if (DBG)
+ log("trySetupData for type:" + apnContext.getApnType() +
+ " due to " + apnContext.getReason());
log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- setState(State.CONNECTED);
- notifyDataConnection(reason);
+ apnContext.setState(State.CONNECTED);
+ mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
log("(fix?) We're on the simulator; assuming data is connected");
return true;
}
- int gprsState = mGsmPhone.mSST.getCurrentGprsState();
- boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
+ boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
- if (((mState == State.IDLE) || (mState == State.SCANNING)) &&
- isDataAllowed() && getAnyDataEnabled()) {
+ if ((apnContext.getState() == State.IDLE || apnContext.getState() == State.SCANNING) &&
+ isDataAllowed(apnContext) && getAnyDataEnabled()) {
- if (mState == State.IDLE) {
- mWaitingApns = buildWaitingApns(mRequestedApnType);
- mWaitingApnsPermanentFailureCountDown = mWaitingApns.size();
- if (mWaitingApns.isEmpty()) {
+ if (apnContext.getState() == State.IDLE) {
+ ArrayList<ApnSetting> waitingApns = buildWaitingApns(apnContext.getApnType());
+ if (waitingApns.isEmpty()) {
if (DBG) log("No APN found");
- notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
- notifyOffApnsOfAvailability(reason, false);
+ notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN, apnContext);
+ notifyOffApnsOfAvailability(apnContext.getReason(), false);
return false;
} else {
- log ("Create from allApns : " + apnListToString(mAllApns));
+ apnContext.setWaitingApns(waitingApns);
+ log ("Create from mAllApns : " + apnListToString(mAllApns));
}
}
if (DBG) {
- log ("Setup waitngApns : " + apnListToString(mWaitingApns));
+ log ("Setup watingApns : " + apnListToString(apnContext.getWaitingApns()));
}
- boolean retValue = setupData(reason);
- notifyOffApnsOfAvailability(reason, retValue);
+ // apnContext.setReason(apnContext.getReason());
+ boolean retValue = setupData(apnContext);
+ notifyOffApnsOfAvailability(apnContext.getReason(), retValue);
return retValue;
} else {
- notifyOffApnsOfAvailability(reason, false);
+ // TODO: check the condition.
+ if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)
+ && (apnContext.getState() == State.IDLE
+ || apnContext.getState() == State.SCANNING))
+ mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
+ notifyOffApnsOfAvailability(apnContext.getReason(), false);
return false;
}
}
+ @Override
+ // Disabled apn's still need avail/unavail notificiations - send them out
+ protected void notifyOffApnsOfAvailability(String reason, boolean availability) {
+ if (mAvailability == availability) return;
+ mAvailability = availability;
+
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ // FIXME: Dont understand why this needs to be done!!
+ // This information is not available (DISABLED APNS)
+ if (false) {
+ if (DBG) log("notify disconnected for type:" + apnContext.getApnType());
+ mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
+ apnContext.getApnType(),
+ Phone.DataState.DISCONNECTED);
+ }
+ }
+ }
+
+ /**
+ * If tearDown is true, this only tears down a CONNECTED session. Presently,
+ * there is no mechanism for abandoning an INITING/CONNECTING session,
+ * but would likely involve cancelling pending async requests or
+ * setting a flag or new state to ignore them when they came in
+ * @param tearDown true if the underlying GsmDataConnection should be
+ * disconnected.
+ * @param reason reason for the clean up.
+ */
+ protected void cleanUpAllConnections(boolean tearDown, String reason) {
+ if (DBG) log("Clean up all connections due to " + reason);
+
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ apnContext.setReason(reason);
+ cleanUpConnection(tearDown, apnContext);
+ }
+
+ stopNetStatPoll();
+ // TODO: Do we need mRequestedApnType?
+ mRequestedApnType = Phone.APN_TYPE_DEFAULT;
+ }
+
/**
* Cleanup all connections.
*
* TODO: Cleanup only a specified connection passed as a parameter.
+ * Also, make sure when you clean up a conn, if it is last apply
+ * logic as though it is cleanupAllConnections
*
* @param tearDown true if the underlying DataConnection should be disconnected.
* @param reason for the clean up.
*/
- private void cleanUpConnection(boolean tearDown, String reason) {
- if (DBG) log("Clean up connection due to " + reason);
+
+ @Override
+ protected void onCleanUpAllConnections() {
+ cleanUpAllConnections(true, null);
+ }
+
+ private void cleanUpConnection(boolean tearDown, ApnContext apnContext) {
+
+ if (apnContext == null) {
+ if (DBG) log("apn context is null");
+ return;
+ }
+
+ if (DBG) log("Clean up connection due to " + apnContext.getReason());
// Clear the reconnect alarm, if set.
- if (mReconnectIntent != null) {
+ if (apnContext.getReconnectIntent() != null) {
AlarmManager am =
(AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- am.cancel(mReconnectIntent);
- mReconnectIntent = null;
+ am.cancel(apnContext.getReconnectIntent());
+ apnContext.setReconnectIntent(null);
}
- setState(State.DISCONNECTING);
+ if (apnContext.getState() == State.IDLE || apnContext.getState() == State.DISCONNECTING) {
+ if (DBG) log("state is in " + apnContext.getState());
+ return;
+ }
- boolean notificationDeferred = false;
- for (DataConnection conn : mDataConnections.values()) {
- if (tearDown) {
- if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE,
- conn.getDataConnectionId(), 0, reason));
- notificationDeferred = true;
+ if (apnContext.getState() == State.FAILED) {
+ if (DBG) log("state is in FAILED");
+ apnContext.setState(State.IDLE);
+ return;
+ }
+
+ GsmDataConnection conn = apnContext.getDataConnection();
+ if (conn != null) {
+ apnContext.setState(State.DISCONNECTING);
+ if (tearDown ) {
+ Message msg = obtainMessage(EVENT_DISCONNECT_DONE, apnContext);
+ conn.disconnect(msg);
} else {
- if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
conn.resetSynchronously();
- notificationDeferred = false;
+ apnContext.setState(State.IDLE);
+ mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
}
}
- stopNetStatPoll();
- if (!notificationDeferred) {
- if (DBG) log("cleanupConnection: !notificationDeferred");
- gotoIdleAndNotifyDataConnection(reason);
+ if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
+ mApnContexts.remove(apnContext.getApnType());
}
}
+
/**
* @param types comma delimited list of APN types
* @return array of APN types
@@ -439,6 +801,7 @@
result.add(apn);
} while (cursor.moveToNext());
}
+ if (DBG) log("createApnList: X result=" + result);
return result;
}
@@ -453,27 +816,64 @@
return null;
}
- private boolean setupData(String reason) {
- ApnSetting apn;
- GsmDataConnection gdc;
+ protected GsmDataConnection findReadyDataConnection(ApnSetting apn) {
+ if (DBG)
+ log("findReadyDataConnection for apn string <" +
+ (apn!=null?(apn.toString()):"null") +">");
+ for (DataConnection conn : mDataConnections.values()) {
+ GsmDataConnection dc = (GsmDataConnection) conn;
+ if (DBG) log("dc apn string <" +
+ (dc.getApn() != null ? (dc.getApn().toString()) : "null") + ">");
+ if (dc.getApn() != null && apn != null
+ && dc.getApn().toString().equals(apn.toString())) {
+ return dc;
+ }
+ }
+ return null;
+ }
- apn = getNextApn();
- if (apn == null) return false;
- gdc = findFreeDataConnection();
- if (gdc == null) {
+
+ private boolean setupData(ApnContext apnContext) {
+ if (DBG) log("enter setupData!");
+ ApnSetting apn;
+ GsmDataConnection dc;
+
+ int profileId = getApnProfileID(apnContext.getApnType());
+ apn = apnContext.getNextApn();
+ if (apn == null) {
+ if (DBG) log("setupData: return for no apn found!");
+ return false;
+ }
+
+ dc = findReadyDataConnection(apn);
+
+ if (dc == null) {
+ if (DBG) log("setupData: No ready GsmDataConnection found!");
+ // TODO: When allocating you are mapping type to id. If more than 1 free,
+ // then could findFreeDataConnection get the wrong one??
+ dc = findFreeDataConnection();
+ }
+
+ if (dc == null) {
if (DBG) log("setupData: No free GsmDataConnection found!");
return false;
}
- mActiveApn = apn;
- mPendingDataConnection = gdc;
+
+ apnContext.setApnSetting(apn);
+ apnContext.setDataConnection(dc);
+ dc.setProfileId( profileId );
+ dc.setActiveApnType(apnContext.getApnType());
Message msg = obtainMessage();
msg.what = EVENT_DATA_SETUP_COMPLETE;
- msg.obj = reason;
- gdc.connect(msg, apn);
+ msg.obj = apnContext;
- setState(State.INITING);
- notifyDataConnection(reason);
+ if (DBG) log("dc connect!");
+ dc.connect(msg, apn);
+
+ apnContext.setState(State.INITING);
+ mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+ if (DBG) log("setupData: initing!");
return true;
}
@@ -498,24 +898,28 @@
* Handles changes to the APN database.
*/
private void onApnChanged() {
+ // TODO: How to handle when multiple APNs are active?
boolean isConnected;
- isConnected = (mState != State.IDLE && mState != State.FAILED);
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ isConnected = (defaultApnContext.getState() != State.IDLE
+ && defaultApnContext.getState() != State.FAILED);
- // The "current" may no longer be valid. MMS depends on this to send properly.
- mGsmPhone.updateCurrentCarrierInProvider();
+ if (mPhone instanceof GSMPhone) {
+ // The "current" may no longer be valid. MMS depends on this to send properly. TBD
+ ((GSMPhone)mPhone).updateCurrentCarrierInProvider();
+ }
// TODO: It'd be nice to only do this if the changed entrie(s)
// match the current operator.
createAllApnList();
- if (mState != State.DISCONNECTING) {
- cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED);
- if (!isConnected) {
- // reset reconnect timer
- mRetryMgr.resetRetryCount();
- mReregisterOnReconnectFailure = false;
- trySetupData(Phone.REASON_APN_CHANGED);
- }
+ if (DBG) log("onApnChanged clean all connections");
+ cleanUpAllConnections(isConnected, Phone.REASON_APN_CHANGED);
+ if (!isConnected) {
+ // TODO: Won't work for multiple connections!!!!
+ defaultApnContext.getDataConnection().resetRetryCount();
+ defaultApnContext.setReason(Phone.REASON_APN_CHANGED);
+ trySetupData(defaultApnContext);
}
}
@@ -537,28 +941,46 @@
return;
}
- if (mState == State.CONNECTED) {
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ onDataStateChanged(dataCallStates, explicitPoll, apnContext);
+ }
+ }
+
+ private void onDataStateChanged (ArrayList<DataCallState> dataCallStates,
+ boolean explicitPoll,
+ ApnContext apnContext) {
+
+ if (apnContext == null) {
+ // Should not happen
+ return;
+ }
+
+ if (apnContext.getState() == State.CONNECTED) {
// The way things are supposed to work, the PDP list
// should not contain the CID after it disconnects.
// However, the way things really work, sometimes the PDP
// context is still listed with active = false, which
// makes it hard to distinguish an activating context from
// an activated-and-then deactivated one.
- if (!dataCallStatesHasCID(dataCallStates, mCidActive)) {
+ if (!dataCallStatesHasCID(dataCallStates, apnContext.getDataConnection().getCid())) {
// It looks like the PDP context has deactivated.
// Tear everything down and try to reconnect.
- log("PDP connection has dropped. Reconnecting");
+ Log.i(LOG_TAG, "PDP connection has dropped. Reconnecting");
// Add an event log when the network drops PDP
+ int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
- EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
- loc != null ? loc.getCid() : -1,
+ if (loc != null) cid = loc.getCid();
+ EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
TelephonyManager.getDefault().getNetworkType());
- cleanUpConnection(true, null);
+ cleanUpConnection(true, apnContext);
return;
- } else if (!dataCallStatesHasActiveCID(dataCallStates, mCidActive)) {
+ } else if (!dataCallStatesHasActiveCID(dataCallStates,
+ apnContext.getDataConnection().getCid())) {
// Here, we only consider this authoritative if we asked for the
// PDP list. If it was an unsolicited response, we poll again
// to make sure everyone agrees on the initial state.
@@ -568,33 +990,37 @@
mPhone.mCM.getPDPContextList(
this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
} else {
- log("PDP connection has dropped (active=false case). "
+ Log.i(LOG_TAG, "PDP connection has dropped (active=false case). "
+ " Reconnecting");
// Log the network drop on the event log.
+ int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
- EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
- loc != null ? loc.getCid() : -1,
+ if (loc != null) cid = loc.getCid();
+ EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP, cid,
TelephonyManager.getDefault().getNetworkType());
- cleanUpConnection(true, null);
+ cleanUpConnection(true, apnContext);
}
}
}
}
- private void notifyDefaultData(String reason) {
- setState(State.CONNECTED);
- notifyDataConnection(reason);
+ private void notifyDefaultData(ApnContext apnContext) {
+ if (DBG)
+ log("notifyDefaultData for type: " + apnContext.getApnType()
+ + ", reason:" + apnContext.getReason());
+ apnContext.setState(State.CONNECTED);
+ // setState(State.CONNECTED);
+ mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
startNetStatPoll();
// reset reconnect timer
- mRetryMgr.resetRetryCount();
- mReregisterOnReconnectFailure = false;
+ apnContext.getDataConnection().resetRetryCount();
}
- private void gotoIdleAndNotifyDataConnection(String reason) {
+ // TODO: For multiple Active APNs not exactly sure how to do this.
+ protected void gotoIdleAndNotifyDataConnection(String reason) {
if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
- setState(State.IDLE);
notifyDataConnection(reason);
mActiveApn = null;
}
@@ -608,18 +1034,18 @@
}
private void doRecovery() {
- if (mState == State.CONNECTED) {
+ if (getOverallState() == State.CONNECTED) {
int maxPdpReset = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT,
DEFAULT_MAX_PDP_RESET_FAIL);
if (mPdpResetCount < maxPdpReset) {
mPdpResetCount++;
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
- cleanUpConnection(true, Phone.REASON_PDP_RESET);
+ cleanUpAllConnections(true, Phone.REASON_PDP_RESET);
} else {
mPdpResetCount = 0;
EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, mSentSinceLastRecv);
- mGsmPhone.mSST.reRegisterNetwork(null);
+ mPhone.getServiceStateTracker().reRegisterNetwork(null);
}
// TODO: Add increasingly drastic recovery steps, eg,
// reset the radio, reset the device.
@@ -628,7 +1054,7 @@
@Override
protected void startNetStatPoll() {
- if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
+ if (getOverallState() == State.CONNECTED && mNetStatPollEnabled == false) {
log("[DataConnection] Start poll NetStat");
resetPollStats();
mNetStatPollEnabled = true;
@@ -646,8 +1072,8 @@
@Override
protected void restartRadio() {
log("************TURN OFF RADIO**************");
- cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
- mGsmPhone.mSST.powerOffRadioSafely();
+ cleanUpAllConnections(true, Phone.REASON_RADIO_TURNED_OFF);
+ mPhone.getServiceStateTracker().powerOffRadioSafely();
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
* ServiceStateTracker will call setRadioPower when it receives the
@@ -784,107 +1210,132 @@
return retry;
}
- private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
- if (mState == State.FAILED) {
- /** TODO: Retrieve retry manager from connection itself */
- if (!mRetryMgr.isRetryNeeded()) {
- if (!mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ private void reconnectAfterFail(FailCause lastFailCauseCode, ApnContext apnContext) {
+ if (apnContext == null) {
+ Log.d(LOG_TAG, "It is impossible");
+ return;
+ }
+ if (apnContext.getState() == State.FAILED) {
+ if (!apnContext.getDataConnection().isRetryNeeded()) {
+ if (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)){
// if no more retries on a secondary APN attempt, tell the world and revert.
notifyDataConnection(Phone.REASON_APN_FAILED);
- onEnableApn(apnTypeToId(mRequestedApnType), DISABLED);
return;
}
if (mReregisterOnReconnectFailure) {
- // We've re-registered once now just retry forever.
- mRetryMgr.retryForeverUsingLastTimeout();
+ // We've re-registerd once now just retry forever.
+ apnContext.getDataConnection().retryForeverUsingLastTimeout();
} else {
- // Try to re-register to the network.
+ // Try to Re-register to the network.
log("PDP activate failed, Reregistering to the network");
mReregisterOnReconnectFailure = true;
- mGsmPhone.mSST.reRegisterNetwork(null);
- mRetryMgr.resetRetryCount();
+ mPhone.getServiceStateTracker().reRegisterNetwork(null);
+ apnContext.getDataConnection().resetRetryCount();
return;
}
}
- int nextReconnectDelay = mRetryMgr.getRetryTimer();
+ int nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
log("PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
AlarmManager am =
(AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(INTENT_RECONNECT_ALARM);
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
- mReconnectIntent = PendingIntent.getBroadcast(
- mPhone.getContext(), 0, intent, 0);
+ intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
+ // Should put an extra of apn type?
+ intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnContext.getApnType());
+ apnContext.setReconnectIntent(PendingIntent.getBroadcast (
+ mPhone.getContext(), 0, intent, 0));
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + nextReconnectDelay,
- mReconnectIntent);
+ apnContext.getReconnectIntent());
- mRetryMgr.increaseRetryCount();
+ apnContext.getDataConnection().increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
- log("NOT Posting GPRS Unavailable notification "
+ Log.d(LOG_TAG, "NOT Posting GPRS Unavailable notification "
+ "-- likely transient error");
} else {
- notifyNoData(lastFailCauseCode);
+ notifyNoData(lastFailCauseCode, apnContext);
}
}
}
- private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode) {
- setState(State.FAILED);
+ private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode,
+ ApnContext apnContext) {
+ if (DBG) log( "notifyNoData for type:" + apnContext.getApnType());
+ apnContext.setState(State.FAILED);
+ if (lastFailCauseCode.isPermanentFail()
+ && (!apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT))) {
+ mPhone.notifyDataConnectionFailed(apnContext.getReason(), apnContext.getApnType());
+ }
}
private void onRecordsLoaded() {
createAllApnList();
- if (mState == State.FAILED) {
- cleanUpConnection(false, null);
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ if (defaultApnContext!=null ) {
+ defaultApnContext.setReason(Phone.REASON_SIM_LOADED);
+ if (defaultApnContext.getState() == State.FAILED) {
+ if (DBG) log("onRecordsLoaded clean connection");
+ cleanUpConnection(false, defaultApnContext);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA,defaultApnContext ));
}
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
- @Override
- protected void onEnableNewApn() {
- log("onEnableNewApn E");
+ protected void onEnableNewApn(ApnContext apnContext ) {
// change our retry manager to use the appropriate numbers for the new APN
- if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ log("onEnableNewApn with ApnContext E");
+ if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
log("onEnableNewApn default type");
- mRetryMgr = mPendingDataConnection.getRetryMgr();
- mRetryMgr.resetRetryCount();
- } else if (mApnToDataConnectionId.get(mRequestedApnType) == null) {
- log("onEnableNewApn mRequestedApnType=" + mRequestedApnType +
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ defaultApnContext.getDataConnection().resetRetryCount();
+ } else if (mApnToDataConnectionId.get(apnContext.getApnType()) == null) {
+ log("onEnableNewApn ApnType=" + apnContext.getApnType() +
" missing, make a new connection");
- int id = createDataConnection(mRequestedApnType);
- mRetryMgr = mDataConnections.get(id).getRetryMgr();
- mRetryMgr.resetRetryCount();
+ int id = createDataConnection(apnContext.getApnType());
+ mDataConnections.get(id).resetRetryCount();
} else {
log("oneEnableNewApn connection already exists, nothing to setup");
}
// TODO: To support simultaneous PDP contexts, this should really only call
// cleanUpConnection if it needs to free up a GsmDataConnection.
- cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
- log("onEnableNewApn X");
+ if (DBG) log("onEnableNewApn setup data");
+ if (apnContext.getState() == State.FAILED) {
+ if (DBG) log("previous state is FAILED, reset to IDLE");
+ apnContext.setState(State.IDLE);
+ }
+ trySetupData(apnContext);
+ log("onEnableNewApn with ApnContext X");
}
@Override
+ // TODO: We shouldnt need this.
protected boolean onTrySetupData(String reason) {
- return trySetupData(reason);
+ return trySetupData(reason, Phone.APN_TYPE_DEFAULT);
+ }
+
+ protected boolean onTrySetupData(ApnContext apnContext) {
+ return trySetupData(apnContext);
}
@Override
+ // TODO: Need to understand if more than DEFAULT is impacted?
protected void onRoamingOff() {
- trySetupData(Phone.REASON_ROAMING_OFF);
+ trySetupData(Phone.REASON_ROAMING_OFF, Phone.APN_TYPE_DEFAULT);
}
@Override
+ // TODO: Need to understand if more than DEFAULT is impacted?
protected void onRoamingOn() {
if (getDataOnRoamingEnabled()) {
- trySetupData(Phone.REASON_ROAMING_ON);
+ trySetupData(Phone.REASON_ROAMING_ON, Phone.APN_TYPE_DEFAULT);
} else {
if (DBG) log("Tear down data connection on roaming.");
- cleanUpConnection(true, Phone.REASON_ROAMING_ON);
+ cleanUpAllConnections(true, Phone.REASON_ROAMING_ON);
}
}
@@ -893,13 +1344,13 @@
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- setState(State.CONNECTED);
+ // setState(State.CONNECTED);
notifyDataConnection(null);
log("We're on the simulator; assuming data is connected");
}
- if (mState != State.IDLE) {
+ if (getOverallState() != State.IDLE) {
cleanUpConnection(true, null);
}
}
@@ -908,7 +1359,10 @@
protected void onRadioOffOrNotAvailable() {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
- mRetryMgr.resetRetryCount();
+
+ for (DataConnection dc : mDataConnections.values()) {
+ dc.resetRetryCount();
+ }
mReregisterOnReconnectFailure = false;
if (mPhone.getSimulatedRadioControl() != null) {
@@ -917,28 +1371,30 @@
log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
- // TODO: Should we reset mRequestedApnType to "default"?
- cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
+ cleanUpAllConnections(false, Phone.REASON_RADIO_TURNED_OFF);
}
}
@Override
protected void onDataSetupComplete(AsyncResult ar) {
- /** TODO: Which connection is completing should be a parameter */
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
+
+ ApnContext apnContext = null;
+
+ if(ar.userObj instanceof ApnContext){
+ apnContext = (ApnContext)ar.userObj;
}
if (ar.exception == null) {
- if(DBG) {
- log(String.format("onDataSetupComplete: success apn=%s", mWaitingApns.get(0).apn));
- }
+ // Everything is setup
// TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
- mLinkProperties = getLinkProperties(mPendingDataConnection);
- mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
+ if (DBG) {
+ log(String.format("onDataSetupComplete: success apn=%s",
+ apnContext.getWaitingApns().get(0).apn));
+ }
+ mLinkProperties = getLinkProperties(apnContext.getDataConnection());
+ mLinkCapabilities = getLinkCapabilities(apnContext.getDataConnection());
- ApnSetting apn = mPendingDataConnection.getApn();
+ ApnSetting apn = apnContext.getDataConnection().getApn();
if (apn.proxy != null && apn.proxy.length() != 0) {
try {
ProxyProperties proxy = new ProxyProperties(apn.proxy,
@@ -951,29 +1407,34 @@
}
// everything is setup
- if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
+ if(TextUtils.equals(apnContext.getApnType(),Phone.APN_TYPE_DEFAULT)) {
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- if (canSetPreferApn && mPreferredApn == null) {
- log("PREFERRED APN is null");
- mPreferredApn = mActiveApn;
- setPreferredApn(mPreferredApn.id);
- }
+ if (canSetPreferApn && mPreferredApn == null) {
+ log("PREFERED APN is null");
+ mPreferredApn = apnContext.getApnSetting();
+ if (mPreferredApn != null) {
+ setPreferredApn(mPreferredApn.id);
+ }
+ }
} else {
SystemProperties.set("gsm.defaultpdpcontext.active", "false");
}
- notifyDefaultData(reason);
+ notifyDefaultData(apnContext);
// TODO: For simultaneous PDP support, we need to build another
// trigger another TRY_SETUP_DATA for the next APN type. (Note
// that the existing connection may service that type, in which
// case we should try the next type, etc.
+ // I dont believe for simultaneous PDP you need to trigger. Each
+ // Connection should be independent and they can be setup simultaneously
+ // So, dont have to wait till one is finished.
} else {
GsmDataConnection.FailCause cause;
cause = (GsmDataConnection.FailCause) (ar.result);
if (DBG) {
String apnString;
try {
- apnString = mWaitingApns.get(0).apn;
+ apnString = apnContext.getWaitingApns().get(0).apn;
} catch (Exception e) {
apnString = "<unknown>";
}
@@ -988,28 +1449,31 @@
}
// Count permanent failures and remove the APN we just tried
- mWaitingApnsPermanentFailureCountDown -= cause.isPermanentFail() ? 1 : 0;
- mWaitingApns.remove(0);
+ // TODO: Where is mWaitingApnsPermanentFailureCountDown initialized
+ if (cause.isPermanentFail())
+ apnContext.decPermFailCount();
+
+ apnContext.removeNextApn();
if (DBG) log(String.format("onDataSetupComplete: mWaitingApns.size=%d" +
" mWaitingApnsPermanenatFailureCountDown=%d",
- mWaitingApns.size(), mWaitingApnsPermanentFailureCountDown));
+ apnContext.getWaitingApns().size(), apnContext.getPermFailCount()));
// See if there are more APN's to try
- if (mWaitingApns.isEmpty()) {
- if (mWaitingApnsPermanentFailureCountDown == 0) {
+ if (apnContext.getWaitingApns().isEmpty()) {
+ if (apnContext.getPermFailCount() == 0) {
if (DBG) log("onDataSetupComplete: Permanent failures stop retrying");
- notifyNoData(cause);
+ apnContext.setState(State.FAILED);
notifyDataConnection(Phone.REASON_APN_FAILED);
} else {
if (DBG) log("onDataSetupComplete: Not all permanent failures, retry");
- startDelayedRetry(cause, reason);
+ startDelayedRetry(cause, apnContext);
}
} else {
if (DBG) log("onDataSetupComplete: Try next APN");
- setState(State.SCANNING);
+ apnContext.setState(State.SCANNING);
// Wait a bit before trying the next APN, so that
// we're not tying up the RIL command channel
- sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason), APN_DELAY_MILLIS);
+ sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, apnContext), APN_DELAY_MILLIS);
}
}
}
@@ -1019,34 +1483,36 @@
*/
@Override
protected void onDisconnectDone(int connId, AsyncResult ar) {
- if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
- setState(State.IDLE);
- notifyDataConnection(reason);
- mActiveApn = null;
- if (retryAfterDisconnected(reason)) {
- trySetupData(reason);
- }
- }
+ ApnContext apnContext = null;
- /**
- * Called when EVENT_RESET_DONE is received.
- */
- @Override
- protected void onResetDone(AsyncResult ar) {
- if (DBG) log("EVENT_RESET_DONE");
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
+ if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
+ if (ar.userObj instanceof ApnContext) {
+ apnContext = (ApnContext) ar.userObj;
}
- gotoIdleAndNotifyDataConnection(reason);
+
+ mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
+ // Check if APN disabled.
+ if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_APN_DISABLE) {
+ mApnContexts.remove(apnContext.getApnType());
+ return;
+ }
+
+ apnContext.setState(State.IDLE);
+ apnContext.setApnSetting(null);
+ if (TextUtils.equals(apnContext.getApnType(), Phone.APN_TYPE_DEFAULT)
+ && retryAfterDisconnected(apnContext.getReason())) {
+ SystemProperties.set("gsm.defaultpdpcontext.active", "false");
+ trySetupData(apnContext);
+ }
+ else if (apnContext.getPendingAction() == ApnContext.PENDING_ACTION_RECONNECT)
+ {
+ apnContext.setPendingAction(ApnContext.PENDING_ACTION_NONE);
+ trySetupData(apnContext);
+ }
}
protected void onPollPdp() {
- if (mState == State.CONNECTED) {
+ if (getOverallState() == State.CONNECTED) {
// only poll when connected
mPhone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
@@ -1055,7 +1521,7 @@
@Override
protected void onVoiceCallStarted() {
- if (mState == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
+ if (isConnected() && ! mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
stopNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
}
@@ -1063,8 +1529,8 @@
@Override
protected void onVoiceCallEnded() {
- if (mState == State.CONNECTED) {
- if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) {
+ if (isConnected()) {
+ if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
@@ -1073,16 +1539,43 @@
}
} else {
// reset reconnect timer
- mRetryMgr.resetRetryCount();
+ ApnContext defaultApnContext = mApnContexts.get(Phone.APN_TYPE_DEFAULT);
+ defaultApnContext.getDataConnection().resetRetryCount();
mReregisterOnReconnectFailure = false;
// in case data setup was attempted when we were on a voice call
- trySetupData(Phone.REASON_VOICE_CALL_ENDED);
+ trySetupData(Phone.REASON_VOICE_CALL_ENDED, Phone.APN_TYPE_DEFAULT);
}
}
@Override
- protected void onCleanUpConnection(boolean tearDown, String reason) {
- cleanUpConnection(tearDown, reason);
+ protected void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
+ if (DBG) log("onCleanUpConnection");
+ ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));
+ cleanUpConnection(tearDown, apnContext);
+ }
+
+ protected boolean isConnected() {
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ if (apnContext.getState() == State.CONNECTED) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void notifyDataConnection(String reason) {
+ if (DBG) log("notify all enabled connection for:" + reason);
+ Iterator<ApnContext> it = mApnContexts.values().iterator();
+ while (it.hasNext()) {
+ ApnContext apnContext = it.next();
+ if (DBG) log("notify for type:"+apnContext.getApnType());
+ mPhone.notifyDataConnection(reason != null ? reason : apnContext.getReason(),
+ apnContext.getApnType());
+ }
+ notifyDataAvailability(reason);
}
/**
@@ -1091,10 +1584,11 @@
*/
private void createAllApnList() {
mAllApns = new ArrayList<ApnSetting>();
- String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
+ String operator = mPhone.mSIMRecords.getSIMOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
+ if (DBG) log("createAllApnList: selection=" + selection);
Cursor cursor = mPhone.getContext().getContentResolver().query(
Telephony.Carriers.CONTENT_URI, null, selection, null, null);
@@ -1108,17 +1602,19 @@
}
if (mAllApns.isEmpty()) {
- if (DBG) log("No APN found for carrier: " + operator);
+ if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
mPreferredApn = null;
- notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
+ // TODO: What is the right behaviour?
+ //notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
} else {
mPreferredApn = getPreferredApn();
- log("Get PreferredAPN");
if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
mPreferredApn = null;
setPreferredApn(-1);
}
+ if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
}
+ if (DBG) log("createAllApnList: X mAllApns=" + mAllApns);
}
/** Return the id for a new data connection */
@@ -1147,7 +1643,7 @@
}
int id = mUniqueIdGenerator.getAndIncrement();
- DataConnection conn = GsmDataConnection.makeDataConnection(mGsmPhone, id, rm);
+ DataConnection conn = GsmDataConnection.makeDataConnection(mPhone, id, rm);
mDataConnections.put(id, conn);
mApnToDataConnectionId.put(apnType, id);
@@ -1164,17 +1660,6 @@
}
}
- private ApnSetting fetchDunApn() {
- Context c = mPhone.getContext();
- String apnData = Settings.Secure.getString(c.getContentResolver(),
- Settings.Secure.TETHER_DUN_APN);
- ApnSetting dunSetting = ApnSetting.fromString(apnData);
- if (dunSetting != null) return dunSetting;
-
- apnData = c.getResources().getString(R.string.config_tether_apndata);
- return ApnSetting.fromString(apnData);
- }
-
/**
* Build a list of APNs to be used to create PDP's.
*
@@ -1188,20 +1673,22 @@
if (requestedApnType.equals(Phone.APN_TYPE_DUN)) {
ApnSetting dun = fetchDunApn();
if (dun != null) apnList.add(dun);
+ if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
return apnList;
}
- String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
+ String operator = mPhone.mSIMRecords.getSIMOperatorNumeric();
if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
if (canSetPreferApn && mPreferredApn != null) {
log("Preferred APN:" + operator + ":"
+ mPreferredApn.numeric + ":" + mPreferredApn);
if (mPreferredApn.numeric.equals(operator)) {
- log("Waiting APN set to preferred APN");
apnList.add(mPreferredApn);
+ if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
return apnList;
} else {
+ if (DBG) log("buildWaitingApns: no preferred APN");
setPreferredApn(-1);
mPreferredApn = null;
}
@@ -1215,25 +1702,10 @@
}
}
}
+ if (DBG) log("buildWaitingApns: X apnList=" + apnList);
return apnList;
}
- /**
- * Get next apn in waitingApns
- * @return the first apn found in waitingApns, null if none
- */
- private ApnSetting getNextApn() {
- ArrayList<ApnSetting> list = mWaitingApns;
- ApnSetting apn = null;
-
- if (list != null) {
- if (!list.isEmpty()) {
- apn = list.get(0);
- }
- }
- return apn;
- }
-
private String apnListToString (ArrayList<ApnSetting> apns) {
StringBuilder result = new StringBuilder();
for (int i = 0, size = apns.size(); i < size; i++) {
@@ -1244,9 +1716,9 @@
return result.toString();
}
- private void startDelayedRetry(GsmDataConnection.FailCause cause, String reason) {
- notifyNoData(cause);
- reconnectAfterFail(cause, reason);
+ private void startDelayedRetry(GsmDataConnection.FailCause cause, ApnContext apnContext) {
+ notifyNoData(cause, apnContext);
+ reconnectAfterFail(cause, apnContext);
}
private void setPreferredApn(int pos) {
@@ -1302,7 +1774,7 @@
public void handleMessage (Message msg) {
if (DBG) log("GSMDataConnTrack handleMessage "+msg);
- if (!mGsmPhone.mIsTheCurrentActivePhone) {
+ if (!mPhone.mIsTheCurrentActivePhone || mIsDisposed) {
log("Ignore GSM msgs since GSM phone is inactive");
return;
}
@@ -1312,12 +1784,20 @@
onRecordsLoaded();
break;
- case EVENT_GPRS_DETACHED:
- onGprsDetached();
+ case EVENT_ENABLE_NEW_APN:
+ ApnContext apnContext = null;
+ if (msg.obj instanceof ApnContext) {
+ apnContext = (ApnContext)msg.obj;
+ }
+ onEnableNewApn(apnContext);
break;
- case EVENT_GPRS_ATTACHED:
- onGprsAttached();
+ case EVENT_DATA_CONNECTION_DETACHED:
+ onDataConnectionDetached();
+ break;
+
+ case EVENT_DATA_CONNECTION_ATTACHED:
+ onDataConnectionAttached();
break;
case EVENT_DATA_STATE_CHANGED:
@@ -1363,18 +1843,37 @@
*/
log("[DSAC DEB] " + "EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
mIsPsRestricted = false;
- if (mState == State.CONNECTED) {
+ if (isConnected()) {
startNetStatPoll();
} else {
+ // TODO: Should all PDN states be checked to fail?
if (mState == State.FAILED) {
- cleanUpConnection(false, Phone.REASON_PS_RESTRICT_ENABLED);
- mRetryMgr.resetRetryCount();
+ cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
+ resetAllRetryCounts();
mReregisterOnReconnectFailure = false;
}
- trySetupData(Phone.REASON_PS_RESTRICT_ENABLED);
+ trySetupData(Phone.REASON_PS_RESTRICT_ENABLED, Phone.APN_TYPE_DEFAULT);
+ }
+ break;
+ case EVENT_TRY_SETUP_DATA:
+ if (msg.obj instanceof ApnContext) {
+ onTrySetupData((ApnContext)msg.obj);
+ } else {
+ if (msg.obj instanceof String) {
+ onTrySetupData((String)msg.obj);
+ }
}
break;
+ case EVENT_CLEAN_UP_CONNECTION:
+ boolean tearDown = (msg.arg1 == 0) ? false : true;
+ if (msg.obj instanceof ApnContext) {
+ cleanUpConnection(tearDown, (ApnContext)msg.obj);
+ } else {
+ Log.e(LOG_TAG,
+ "[GsmDataConnectionTracker] connectpion cleanup request w/o apn context");
+ }
+ break;
default:
// handle the message in the super class DataConnectionTracker
super.handleMessage(msg);
@@ -1382,6 +1881,18 @@
}
}
+ protected int getApnProfileID(String apnType) {
+ if (TextUtils.equals(apnType, Phone.APN_TYPE_IMS)) {
+ return RILConstants.DATA_PROFILE_IMS;
+ } else if (TextUtils.equals(apnType, Phone.APN_TYPE_FOTA)) {
+ return RILConstants.DATA_PROFILE_FOTA;
+ } else if (TextUtils.equals(apnType, Phone.APN_TYPE_CBS)) {
+ return RILConstants.DATA_PROFILE_CBS;
+ } else {
+ return RILConstants.DATA_PROFILE_DEFAULT;
+ }
+ }
+
@Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDataConnectionTracker] " + s);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index f576b4e..21a12f1 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -99,7 +99,7 @@
/** {@inheritDoc} */
@Override
- protected int dispatchMessage(SmsMessageBase smsb) {
+ public int dispatchMessage(SmsMessageBase smsb) {
// If sms is null, means there was a parsing error.
if (smsb == null) {
@@ -383,7 +383,7 @@
/** {@inheritDoc} */
@Override
- protected void activateCellBroadcastSms(int activate, Message response) {
+ public void activateCellBroadcastSms(int activate, Message response) {
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
response.recycle();
@@ -391,7 +391,7 @@
/** {@inheritDoc} */
@Override
- protected void getCellBroadcastSmsConfig(Message response){
+ public void getCellBroadcastSmsConfig(Message response){
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
response.recycle();
@@ -399,7 +399,7 @@
/** {@inheritDoc} */
@Override
- protected void setCellBroadcastConfig(int[] configValuesArray, Message response) {
+ public void setCellBroadcastConfig(int[] configValuesArray, Message response) {
// Unless CBS is implemented for GSM, this point should be unreachable.
Log.e(TAG, "Error! The functionality cell broadcast sms is not implemented for GSM.");
response.recycle();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index ac83808..3f521a0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -23,6 +23,7 @@
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.RestrictedState;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
@@ -75,7 +76,6 @@
GsmCellLocation cellLoc;
GsmCellLocation newCellLoc;
int mPreferredNetworkType;
- RestrictedState rs;
private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
@@ -85,7 +85,7 @@
private int mNewReasonDataDenied = -1;
/**
- * Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
+ * Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
*/
private int networkType = 0;
private int newNetworkType = 0;
@@ -107,11 +107,6 @@
*/
private boolean mEmergencyOnly = false;
- private RegistrantList gprsAttachedRegistrants = new RegistrantList();
- private RegistrantList gprsDetachedRegistrants = new RegistrantList();
- private RegistrantList psRestrictEnabledRegistrants = new RegistrantList();
- private RegistrantList psRestrictDisabledRegistrants = new RegistrantList();
-
/**
* Sometimes we get the NITZ time before we know what country we
* are in. Keep the time zone information from the NITZ string so
@@ -206,7 +201,6 @@
newSS = new ServiceState();
cellLoc = new GsmCellLocation();
newCellLoc = new GsmCellLocation();
- rs = new RestrictedState();
mSignalStrength = new SignalStrength();
PowerManager powerManager =
@@ -272,97 +266,6 @@
return phone;
}
- /**
- * Registration point for transition into GPRS attached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForGprsAttached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- gprsAttachedRegistrants.add(r);
-
- if (gprsState == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForGprsAttached(Handler h) {
- gprsAttachedRegistrants.remove(h);
- }
-
- void registerForNetworkAttach(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- networkAttachedRegistrants.add(r);
-
- if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForNetworkAttach(Handler h) {
- networkAttachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into GPRS detached.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForGprsDetached(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- gprsDetachedRegistrants.add(r);
-
- if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForGprsDetached(Handler h) {
- gprsDetachedRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition into packet service restricted zone.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
- Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled ");
- Registrant r = new Registrant(h, what, obj);
- psRestrictEnabledRegistrants.add(r);
-
- if (rs.isPsRestricted()) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForPsRestrictedEnabled(Handler h) {
- psRestrictEnabledRegistrants.remove(h);
- }
-
- /**
- * Registration point for transition out of packet service restricted zone.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- */
- void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
- Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled ");
- Registrant r = new Registrant(h, what, obj);
- psRestrictDisabledRegistrants.add(r);
-
- if (rs.isPsRestricted()) {
- r.notifyRegistrant();
- }
- }
-
- void unregisterForPsRestrictedDisabled(Handler h) {
- psRestrictDisabledRegistrants.remove(h);
- }
-
public void handleMessage (Message msg) {
AsyncResult ar;
int[] ints;
@@ -567,33 +470,21 @@
&& cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
cm.setRadioPower(true, null);
} else if (!mDesiredPowerState && cm.getRadioState().isOn()) {
- DataConnectionTracker dcTracker = phone.mDataConnection;
- if (! dcTracker.isDataConnectionAsDesired()) {
- EventLog.writeEvent(EventLogTags.DATA_NETWORK_STATUS_ON_RADIO_OFF,
- dcTracker.getStateInString(), dcTracker.getAnyDataEnabled() ? 1 : 0);
- }
// If it's on and available and we want it off gracefully
powerOffRadioSafely();
} // Otherwise, we're in the desired state
}
@Override
- protected void powerOffRadioSafely() {
- // clean data connection
+ public void powerOffRadioSafely() {
+ // Cleanup all connections
DataConnectionTracker dcTracker = phone.mDataConnection;
- Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 1; // tearDown is true
- msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
+ Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_ALL_CONNECTIONS);
dcTracker.sendMessage(msg);
// poll data state up to 15 times, with a 100ms delay
// totaling 1.5 sec. Normal data disable action will finish in 100ms.
for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
- if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
- && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
- Log.d(LOG_TAG, "Data shutdown complete.");
- break;
- }
SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
}
@@ -674,8 +565,7 @@
return;
}
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
- err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
+ if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
Log.e(LOG_TAG,
"RIL implementation has returned an error where it must succeed" +
ar.exception);
@@ -877,22 +767,22 @@
String ret = "unknown";
switch (type) {
- case DATA_ACCESS_GPRS:
+ case ServiceState.RADIO_TECHNOLOGY_GPRS:
ret = "GPRS";
break;
- case DATA_ACCESS_EDGE:
+ case ServiceState.RADIO_TECHNOLOGY_EDGE:
ret = "EDGE";
break;
- case DATA_ACCESS_UMTS:
+ case ServiceState.RADIO_TECHNOLOGY_UMTS:
ret = "UMTS";
break;
- case DATA_ACCESS_HSDPA:
+ case ServiceState.RADIO_TECHNOLOGY_HSDPA:
ret = "HSDPA";
break;
- case DATA_ACCESS_HSUPA:
+ case ServiceState.RADIO_TECHNOLOGY_HSUPA:
ret = "HSUPA";
break;
- case DATA_ACCESS_HSPA:
+ case ServiceState.RADIO_TECHNOLOGY_HSPA:
ret = "HSPA";
break;
default:
@@ -988,7 +878,7 @@
}
if (hasRegistered) {
- networkAttachedRegistrants.notifyRegistrants();
+ mNetworkAttachedRegistrants.notifyRegistrants();
}
if (hasChanged) {
@@ -1065,23 +955,23 @@
}
if (hasGprsAttached) {
- gprsAttachedRegistrants.notifyRegistrants();
+ mAttachedRegistrants.notifyRegistrants();
}
if (hasGprsDetached) {
- gprsDetachedRegistrants.notifyRegistrants();
+ mDetachedRegistrants.notifyRegistrants();
}
if (hasNetworkTypeChanged) {
- phone.notifyDataConnection();
+ phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED, Phone.APN_TYPE_ALL);
}
if (hasRoamingOn) {
- roamingOnRegistrants.notifyRegistrants();
+ mRoamingOnRegistrants.notifyRegistrants();
}
if (hasRoamingOff) {
- roamingOffRegistrants.notifyRegistrants();
+ mRoamingOffRegistrants.notifyRegistrants();
}
if (hasLocationChanged) {
@@ -1229,7 +1119,7 @@
Log.d(LOG_TAG, "[DSAC DEB] " + "onRestrictedStateChanged");
RestrictedState newRs = new RestrictedState();
- Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at enter "+ rs);
+ Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at enter "+ mRestrictedState);
if (ar.exception == null) {
int[] ints = (int[])ar.result;
@@ -1249,11 +1139,11 @@
Log.d(LOG_TAG, "[DSAC DEB] " + "new rs "+ newRs);
- if (!rs.isPsRestricted() && newRs.isPsRestricted()) {
- psRestrictEnabledRegistrants.notifyRegistrants();
+ if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) {
+ mPsRestrictEnabledRegistrants.notifyRegistrants();
setNotification(PS_ENABLED);
- } else if (rs.isPsRestricted() && !newRs.isPsRestricted()) {
- psRestrictDisabledRegistrants.notifyRegistrants();
+ } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) {
+ mPsRestrictDisabledRegistrants.notifyRegistrants();
setNotification(PS_DISABLED);
}
@@ -1262,7 +1152,7 @@
* there are 4 x 4 combinations in current and new restricted states
* and we only need to notify when state is changed.
*/
- if (rs.isCsRestricted()) {
+ if (mRestrictedState.isCsRestricted()) {
if (!newRs.isCsRestricted()) {
// remove all restriction
setNotification(CS_DISABLED);
@@ -1273,7 +1163,8 @@
// remove emergency restriction
setNotification(CS_NORMAL_ENABLED);
}
- } else if (rs.isCsEmergencyRestricted() && !rs.isCsNormalRestricted()) {
+ } else if (mRestrictedState.isCsEmergencyRestricted() &&
+ !mRestrictedState.isCsNormalRestricted()) {
if (!newRs.isCsRestricted()) {
// remove all restriction
setNotification(CS_DISABLED);
@@ -1284,7 +1175,8 @@
// remove emergency restriction and enable normal restriction
setNotification(CS_NORMAL_ENABLED);
}
- } else if (!rs.isCsEmergencyRestricted() && rs.isCsNormalRestricted()) {
+ } else if (!mRestrictedState.isCsEmergencyRestricted() &&
+ mRestrictedState.isCsNormalRestricted()) {
if (!newRs.isCsRestricted()) {
// remove all restriction
setNotification(CS_DISABLED);
@@ -1308,9 +1200,9 @@
}
}
- rs = newRs;
+ mRestrictedState = newRs;
}
- Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at return "+ rs);
+ Log.d(LOG_TAG, "[DSAC DEB] " + "current rs at return "+ mRestrictedState);
}
/** code is registration state 0-5 from TS 27.007 7.2 */
@@ -1401,12 +1293,16 @@
return gprsState;
}
+ public int getCurrentDataConnectionState() {
+ return gprsState;
+ }
+
/**
* @return true if phone is camping on a technology (eg UMTS)
* that could support voice and data simultaneously.
*/
- boolean isConcurrentVoiceAndData() {
- return (networkType >= DATA_ACCESS_UMTS);
+ public boolean isConcurrentVoiceAndDataAllowed() {
+ return (networkType >= ServiceState.RADIO_TECHNOLOGY_UMTS);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 3b133da..e69989a 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -35,6 +35,7 @@
import com.android.internal.telephony.IccVmFixedException;
import com.android.internal.telephony.IccVmNotSupportedException;
import com.android.internal.telephony.MccTable;
+import com.android.internal.telephony.PhoneBase;
import java.util.ArrayList;
@@ -165,7 +166,7 @@
// ***** Constructor
- SIMRecords(GSMPhone p) {
+ public SIMRecords(PhoneBase p) {
super(p);
adnCache = new AdnRecordCache(phone);
@@ -364,7 +365,7 @@
countVoiceMessages = countWaiting;
- ((GSMPhone) phone).notifyMessageWaitingIndicator();
+ phone.notifyMessageWaitingIndicator();
try {
if (efMWIS != null) {
@@ -413,7 +414,7 @@
callForwardingEnabled = enable;
- ((GSMPhone) phone).notifyCallForwardingIndicator();
+ phone.notifyCallForwardingIndicator();
try {
if (mEfCfis != null) {
@@ -470,13 +471,18 @@
/** Returns the 5 or 6 digit MCC/MNC of the operator that
* provided the SIM card. Returns null of SIM is not yet ready
*/
- String getSIMOperatorNumeric() {
+ public String getSIMOperatorNumeric() {
if (imsi == null || mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
return null;
}
// Length = length of MCC + length of MNC
// length of mcc = 3 (TS 23.003 Section 2.2)
+ if (SystemProperties.getInt(com.android.internal.telephony.TelephonyProperties
+ .PROPERTY_NETWORK_LTE_ON_CDMA, 0) == 1) {
+ Log.e(LOG_TAG, "getSIMOperatorNumeric: STOPSHIP bad numeric operators in lte");
+ return SystemProperties.get("ro.cdma.home.operator.numeric", "310004");
+ }
return imsi.substring(0, 3 + mncLength);
}
@@ -547,7 +553,7 @@
// finally have both the imsi and the mncLength and can parse the imsi properly
MccTable.updateMccMncConfiguration(phone, imsi.substring(0, 3 + mncLength));
}
- ((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
+ phone.mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_IMSI, null);
break;
@@ -702,7 +708,7 @@
countVoiceMessages = -1;
}
- ((GSMPhone) phone).notifyMessageWaitingIndicator();
+ phone.notifyMessageWaitingIndicator();
break;
case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
@@ -731,7 +737,7 @@
countVoiceMessages = 0;
}
- ((GSMPhone) phone).notifyMessageWaitingIndicator();
+ phone.notifyMessageWaitingIndicator();
}
break;
@@ -842,7 +848,7 @@
callForwardingEnabled =
((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE);
- ((GSMPhone) phone).notifyCallForwardingIndicator();
+ phone.notifyCallForwardingIndicator();
}
break;
@@ -1042,7 +1048,7 @@
// Refer TS 51.011 Section 10.3.46 for the content description
callForwardingEnabled = ((data[1] & 0x01) != 0);
- ((GSMPhone) phone).notifyCallForwardingIndicator();
+ phone.notifyCallForwardingIndicator();
break;
case EVENT_GET_CSP_CPHS_DONE:
@@ -1152,7 +1158,7 @@
System.arraycopy(ba, 1, pdu, 0, n - 1);
SmsMessage message = SmsMessage.createFromPdu(pdu);
- ((GSMPhone) phone).mSMS.dispatchMessage(message);
+ phone.mSMS.dispatchMessage(message);
}
}
@@ -1178,7 +1184,7 @@
System.arraycopy(ba, 1, pdu, 0, n - 1);
SmsMessage message = SmsMessage.createFromPdu(pdu);
- ((GSMPhone) phone).mSMS.dispatchMessage(message);
+ phone.mSMS.dispatchMessage(message);
// 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
// 1 == "received by MS from network; message read"
@@ -1228,7 +1234,7 @@
recordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
- ((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
+ phone.mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_LOADED, null);
}
@@ -1249,11 +1255,11 @@
}
}
- private void onSimReady() {
+ public void onSimReady() {
/* broadcast intent SIM_READY here so that we can make sure
READY is sent before IMSI ready
*/
- ((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
+ phone.mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_READY, null);
fetchSimRecords();
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimCard.java b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
index 835cb29..781746c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimCard.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
@@ -19,6 +19,9 @@
import android.util.Log;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.TelephonyProperties;
+import android.os.SystemProperties;
/**
* {@hide}
@@ -34,6 +37,21 @@
updateStateProperty();
}
+ /**
+ * We have the Sim card for LTE on CDMA phone
+ */
+ public SimCard(PhoneBase phone, String logTag, Boolean dbg) {
+ super(phone, logTag, dbg);
+ mPhone.mCM.registerForSIMLockedOrAbsent(mHandler, EVENT_ICC_LOCKED_OR_ABSENT, null);
+ mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ mPhone.mCM.registerForSIMReady(mHandler, EVENT_ICC_READY, null);
+ updateStateProperty();
+
+ if(SystemProperties.getBoolean(TelephonyProperties.PROPERTY_NETWORK_LTE_ON_CDMA, false)) {
+ mPhone.mCM.registerForNVReady(mHandler, EVENT_ICC_READY, null);
+ }
+ }
+
@Override
public void dispose() {
//Unregister for all events