Merge "Add support for LTE VoPS info"
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 0617f56..e85db77 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -23,6 +23,7 @@
import android.os.ServiceManager;
import android.telephony.CellInfo;
import android.telephony.CellLocation;
+import android.telephony.DataFailCause;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
@@ -286,7 +287,7 @@
}
public void notifyPreciseDataConnectionFailed(Phone sender, String apnType,
- String apn, String failCause) {
+ String apn, @DataFailCause.FailCause int failCause) {
// FIXME: subId?
try {
mRegistry.notifyPreciseDataConnectionFailed(apnType, apn, failCause);
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 5e08a0c..9ca77b4 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -46,6 +46,7 @@
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.ClientRequestStats;
+import android.telephony.DataFailCause;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.PhoneStateListener;
import android.telephony.PhysicalChannelConfig;
@@ -3096,7 +3097,7 @@
}
public void notifyPreciseDataConnectionFailed(String apnType, String apn,
- String failCause) {
+ @DataFailCause.FailCause int failCause) {
mNotifier.notifyPreciseDataConnectionFailed(this, apnType, apn, failCause);
}
diff --git a/src/java/com/android/internal/telephony/PhoneNotifier.java b/src/java/com/android/internal/telephony/PhoneNotifier.java
index 397aff7..ce03ad8 100644
--- a/src/java/com/android/internal/telephony/PhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/PhoneNotifier.java
@@ -18,6 +18,7 @@
import android.telephony.CellInfo;
import android.telephony.CellLocation;
+import android.telephony.DataFailCause;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.TelephonyManager;
@@ -59,8 +60,8 @@
void notifyDisconnectCause(int cause, int preciseCause);
- void notifyPreciseDataConnectionFailed(Phone sender, String apnType, String apn,
- String failCause);
+ public void notifyPreciseDataConnectionFailed(Phone sender, String apnType, String apn,
+ @DataFailCause.FailCause int failCause);
/** send a notification that the SRVCC state has changed.*/
void notifySrvccStateChanged(Phone sender, @TelephonyManager.SrvccState int state);
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 42bb55a..41081e6 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -2452,10 +2452,21 @@
mPreferredNetworkType = networkType;
mMetrics.writeSetPreferredNetworkType(mPhoneId, networkType);
- try {
- radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
- } catch (RemoteException | RuntimeException e) {
- handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
+ if (mRadioVersion.lessOrEqual(RADIO_HAL_VERSION_1_3)) {
+ try {
+ radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
+ }
+ } else if (mRadioVersion.equals(RADIO_HAL_VERSION_1_4)) {
+ android.hardware.radio.V1_4.IRadio radioProxy14 =
+ (android.hardware.radio.V1_4.IRadio) radioProxy;
+ try {
+ radioProxy14.setPreferredNetworkTypeBitmap(
+ rr.mSerial, RadioAccessFamily.getRafFromNetworkType(networkType));
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "setPreferredNetworkTypeBitmap", e);
+ }
}
}
}
@@ -2466,13 +2477,21 @@
if (radioProxy != null) {
RILRequest rr = obtainRequest(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, result,
mRILDefaultWorkSource);
-
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
-
- try {
- radioProxy.getPreferredNetworkType(rr.mSerial);
- } catch (RemoteException | RuntimeException e) {
- handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
+ if (mRadioVersion.lessOrEqual(RADIO_HAL_VERSION_1_3)) {
+ try {
+ radioProxy.getPreferredNetworkType(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
+ }
+ } else if (mRadioVersion.equals(RADIO_HAL_VERSION_1_4)) {
+ android.hardware.radio.V1_4.IRadio radioProxy14 =
+ (android.hardware.radio.V1_4.IRadio) radioProxy;
+ try {
+ radioProxy14.getPreferredNetworkTypeBitmap(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getPreferredNetworkTypeBitmap", e);
+ }
}
}
}
diff --git a/src/java/com/android/internal/telephony/RadioConfigIndication.java b/src/java/com/android/internal/telephony/RadioConfigIndication.java
index 5774bb1..39af57b 100644
--- a/src/java/com/android/internal/telephony/RadioConfigIndication.java
+++ b/src/java/com/android/internal/telephony/RadioConfigIndication.java
@@ -16,7 +16,7 @@
package com.android.internal.telephony;
-import android.hardware.radio.config.V1_0.IRadioConfigIndication;
+import android.hardware.radio.config.V1_2.IRadioConfigIndication;
import android.os.AsyncResult;
import android.telephony.Rlog;
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index 84ed51d..7057612 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -42,6 +42,7 @@
import android.telephony.ModemActivityInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneNumberUtils;
+import android.telephony.RadioAccessFamily;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -745,6 +746,14 @@
}
/**
+ * Callback of setPreferredNetworkTypeBitmap defined in IRadio.hal.
+ * @param responseInfo Response info struct containing response type, serial no. and error
+ */
+ public void setPreferredNetworkTypeBitmapResponse(RadioResponseInfo responseInfo) {
+ responseVoid(responseInfo);
+ }
+
+ /**
*
* @param responseInfo Response info struct containing response type, serial no. and error
* @param nwType RadioPreferredNetworkType defined in types.hal
@@ -755,6 +764,19 @@
}
/**
+ * Callback of the getPreferredNetworkTypeBitmap defined in the IRadio.hal.
+ * @param responseInfo Response info struct containing response type, serial no. and error
+ * @param networkTypeBitmap a 32-bit bitmap of
+ * {@link android.telephony.TelephonyManager.NetworkTypeBitMask}.
+ */
+ public void getPreferredNetworkTypeBitmapResponse(
+ RadioResponseInfo responseInfo, int networkTypeBitmap) {
+ int networkType = RadioAccessFamily.getNetworkTypeFromRaf(networkTypeBitmap);
+ mRil.mPreferredNetworkType = networkType;
+ responseInts(responseInfo, networkType);
+ }
+
+ /**
*
* @param responseInfo Response info struct containing response type, serial no. and error
* @param cells Vector of neighboring radio cell information
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index f6c2d86..0789c5e 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -327,6 +327,8 @@
SubscriptionManager.GROUP_UUID));
boolean isMetered = cursor.getInt(cursor.getColumnIndexOrThrow(
SubscriptionManager.IS_METERED)) == 1;
+ int profileClass = cursor.getInt(cursor.getColumnIndexOrThrow(
+ SubscriptionManager.PROFILE_CLASS));
if (VDBG) {
String iccIdToPrint = SubscriptionInfo.givePrintableIccid(iccId);
@@ -339,7 +341,7 @@
+ isEmbedded + " accessRules:" + Arrays.toString(accessRules)
+ " cardId:" + cardIdToPrint + " publicCardId:" + publicCardId
+ " isOpportunistic:" + isOpportunistic + " groupUUID:" + groupUUID
- + " isMetered:" + isMetered);
+ + " isMetered:" + isMetered + " profileClass:" + profileClass);
}
// If line1number has been set to a different number, use it instead.
@@ -348,9 +350,9 @@
number = line1Number;
}
return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
- nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
- isEmbedded, accessRules, cardId, publicCardId, isOpportunistic, groupUUID,
- isMetered, false /* isGroupDisabled = false */, carrierId);
+ nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
+ isEmbedded, accessRules, cardId, publicCardId, isOpportunistic, groupUUID,
+ isMetered, false /* isGroupDisabled */, carrierId, profileClass);
}
/**
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 207a07a..7611620 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -785,6 +785,7 @@
values.put(SubscriptionManager.IS_REMOVABLE, isRemovable);
values.put(SubscriptionManager.DISPLAY_NAME, embeddedProfile.getNickname());
values.put(SubscriptionManager.NAME_SOURCE, SubscriptionManager.NAME_SOURCE_USER_INPUT);
+ values.put(SubscriptionManager.PROFILE_CLASS, embeddedProfile.getProfileClass());
hasChanges = true;
contentResolver.update(SubscriptionManager.CONTENT_URI, values,
SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.getIccid() + "\"", null);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 593945d..39b443a 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -598,24 +598,13 @@
ApnContext apnContext = cp.mApnContext;
if (apnContext == alreadySent) continue;
if (reason != null) apnContext.setReason(reason);
- Pair<ApnContext, Integer> pair =
- new Pair<ApnContext, Integer>(apnContext, cp.mConnectionGeneration);
+ Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration);
Message msg = mDct.obtainMessage(event, pair);
AsyncResult.forMessage(msg);
msg.sendToTarget();
}
}
- private void notifyAllOfConnected(String reason) {
- notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE, reason);
- }
-
- private void notifyAllDisconnectCompleted(@DataFailCause.FailCause int cause) {
- notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
- DataFailCause.toString(cause));
- }
-
-
/**
* Send the connectionCompletedMsg.
*
@@ -1184,6 +1173,26 @@
throw new UnknownHostException("Empty dns response and no system default dns");
}
+ // set pcscf
+ if (response.getPcscfs().size() > 0) {
+ for (String pcscf : response.getPcscfs()) {
+ if (pcscf == null) continue;
+ pcscf = pcscf.trim();
+ if (pcscf.isEmpty()) continue;
+ InetAddress ia;
+ try {
+ ia = NetworkUtils.numericToInetAddress(pcscf);
+ } catch (IllegalArgumentException e) {
+ throw new UnknownHostException("Non-numeric pcscf addr=" + pcscf);
+ }
+ if (!ia.isAnyLocalAddress()) {
+ linkProperties.addPcscfServer(ia);
+ } else {
+ log("bad address in PCSCF");
+ }
+ }
+ }
+
for (InetAddress gateway : response.getGateways()) {
// Allow 0.0.0.0 or :: as a gateway;
// this indicates a point-to-point interface.
@@ -1487,7 +1496,8 @@
log("DcInactiveState: enter notifyAllDisconnectCompleted failCause="
+ mDcFailCause);
}
- notifyAllDisconnectCompleted(mDcFailCause);
+ notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
+ DataFailCause.toString(mDcFailCause));
}
// Remove ourselves from cid mapping, before clearSettings
@@ -1685,7 +1695,8 @@
updateNetworkInfo();
// If we were retrying there maybe more than one, otherwise they'll only be one.
- notifyAllOfConnected(Phone.REASON_CONNECTED);
+ notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE,
+ Phone.REASON_CONNECTED);
mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(),
DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 185a6bb..f414a61 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -2571,15 +2571,8 @@
* A SETUP (aka bringUp) has completed, possibly with an error. If
* there is an error this method will call {@link #onDataSetupCompleteError}.
*/
- private void onDataSetupComplete(AsyncResult ar) {
-
- int cause = DataFailCause.UNKNOWN;
- boolean handleError = false;
- ApnContext apnContext = getValidApnContext(ar, "onDataSetupComplete");
-
- if (apnContext == null) return;
-
- if (ar.exception == null) {
+ private void onDataSetupComplete(ApnContext apnContext, boolean success, int cause) {
+ if (success) {
DataConnection dataConnection = apnContext.getDataConnection();
if (RADIO_TESTS) {
@@ -2602,8 +2595,7 @@
}
if (dataConnection == null) {
log("onDataSetupComplete: no connection to DC, handle as error");
- cause = DataFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN;
- handleError = true;
+ onDataSetupCompleteError(apnContext);
} else {
ApnSetting apn = apnContext.getApnSetting();
if (DBG) {
@@ -2714,7 +2706,6 @@
}
}
} else {
- cause = (int) (ar.result);
if (DBG) {
ApnSetting apn = apnContext.getApnSetting();
log(String.format("onDataSetupComplete: error apn=%s cause=%s",
@@ -2727,8 +2718,9 @@
cause, cid, mTelephonyManager.getNetworkType());
}
ApnSetting apn = apnContext.getApnSetting();
- mPhone.notifyPreciseDataConnectionFailed(apnContext.getApnType(),
- apn != null ? apn.getApnName() : "unknown", cause + "");
+ mPhone.notifyPreciseDataConnectionFailed(
+ apnContext.getApnType(), apn != null ? apn.getApnName()
+ : "unknown", cause);
// Compose broadcast intent send to the specific carrier signaling receivers
Intent intent = new Intent(TelephonyIntents
@@ -2749,37 +2741,8 @@
log("cause = " + cause + ", mark apn as permanent failed. apn = " + apn);
apnContext.markApnPermanentFailed(apn);
}
-
- handleError = true;
+ onDataSetupCompleteError(apnContext);
}
-
- if (handleError) {
- onDataSetupCompleteError(ar);
- }
- }
-
- /**
- * check for obsolete messages. Return ApnContext if valid, null if not
- */
- private ApnContext getValidApnContext(AsyncResult ar, String logString) {
- if (ar != null && ar.userObj instanceof Pair) {
- Pair<ApnContext, Integer>pair = (Pair<ApnContext, Integer>)ar.userObj;
- ApnContext apnContext = pair.first;
- if (apnContext != null) {
- final int generation = apnContext.getConnectionGeneration();
- if (DBG) {
- log("getValidApnContext (" + logString + ") on " + apnContext + " got " +
- generation + " vs " + pair.second);
- }
- if (generation == pair.second) {
- return apnContext;
- } else {
- log("ignoring obsolete " + logString);
- return null;
- }
- }
- }
- throw new RuntimeException(logString + ": No apnContext");
}
/**
@@ -2788,12 +2751,7 @@
* beginning if the list is empty. Between each SETUP request there will
* be a delay defined by {@link #getApnDelay()}.
*/
- private void onDataSetupCompleteError(AsyncResult ar) {
-
- ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
-
- if (apnContext == null) return;
-
+ private void onDataSetupCompleteError(ApnContext apnContext) {
long delay = apnContext.getDelayForNextApn(mFailFast);
// Check if we need to retry or not.
@@ -2828,10 +2786,7 @@
/**
* Called when EVENT_DISCONNECT_DONE is received.
*/
- private void onDisconnectDone(AsyncResult ar) {
- ApnContext apnContext = getValidApnContext(ar, "onDisconnectDone");
- if (apnContext == null) return;
-
+ private void onDisconnectDone(ApnContext apnContext) {
if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
apnContext.setState(DctConstants.State.IDLE);
@@ -3323,6 +3278,10 @@
public void handleMessage (Message msg) {
if (VDBG) log("handleMessage msg=" + msg);
+ AsyncResult ar;
+ Pair<ApnContext, Integer> pair;
+ ApnContext apnContext;
+ int generation;
switch (msg.what) {
case DctConstants.EVENT_RECORDS_LOADED:
// If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
@@ -3380,7 +3339,7 @@
cleanUpAllConnectionsInternal(false, Phone.REASON_PS_RESTRICT_ENABLED);
mReregisterOnReconnectFailure = false;
}
- ApnContext apnContext = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
+ apnContext = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
if (apnContext != null) {
apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
trySetupData(apnContext);
@@ -3465,16 +3424,49 @@
break;
case DctConstants.EVENT_DATA_SETUP_COMPLETE:
- onDataSetupComplete((AsyncResult) msg.obj);
+ ar = (AsyncResult) msg.obj;
+ pair = (Pair<ApnContext, Integer>) ar.userObj;
+ apnContext = pair.first;
+ generation = pair.second;
+ if (apnContext.getConnectionGeneration() == generation) {
+ boolean success = true;
+ int cause = DataFailCause.UNKNOWN;
+ if (ar.exception != null) {
+ success = false;
+ cause = (int) ar.result;
+ }
+ onDataSetupComplete(apnContext, success, cause);
+ } else {
+ loge("EVENT_DATA_SETUP_COMPLETE: Dropped the event because generation "
+ + "did not match.");
+ }
break;
case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
- onDataSetupCompleteError((AsyncResult) msg.obj);
+ ar = (AsyncResult) msg.obj;
+ pair = (Pair<ApnContext, Integer>) ar.userObj;
+ apnContext = pair.first;
+ generation = pair.second;
+ if (apnContext.getConnectionGeneration() == generation) {
+ onDataSetupCompleteError(apnContext);
+ } else {
+ loge("EVENT_DATA_SETUP_COMPLETE_ERROR: Dropped the event because generation "
+ + "did not match.");
+ }
break;
case DctConstants.EVENT_DISCONNECT_DONE:
- log("DataConnectionTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
- onDisconnectDone((AsyncResult) msg.obj);
+ log("EVENT_DISCONNECT_DONE msg=" + msg);
+ ar = (AsyncResult) msg.obj;
+ pair = (Pair<ApnContext, Integer>) ar.userObj;
+ apnContext = pair.first;
+ generation = pair.second;
+ if (apnContext.getConnectionGeneration() == generation) {
+ onDisconnectDone(apnContext);
+ } else {
+ loge("EVENT_DISCONNECT_DONE: Dropped the event because generation "
+ + "did not match.");
+ }
break;
case DctConstants.EVENT_VOICE_CALL_STARTED:
@@ -3615,7 +3607,7 @@
onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
break;
case DctConstants.EVENT_DATA_ENABLED_CHANGED:
- AsyncResult ar = (AsyncResult) msg.obj;
+ ar = (AsyncResult) msg.obj;
if (ar.result instanceof Pair) {
Pair<Boolean, Integer> p = (Pair<Boolean, Integer>) ar.result;
boolean enabled = p.first;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 1021b74..64e5350 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -46,11 +46,9 @@
import android.telecom.ConferenceParticipant;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
-import android.telephony.PreciseDisconnectCause;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
@@ -2350,7 +2348,7 @@
dialPendingMO();
}
mHoldSwitchingState = HoldSwapState.INACTIVE;
- } else if (mPendingMO.isEmergency()) {
+ } else if (mPendingMO != null && mPendingMO.isEmergency()) {
// If mPendingMO is an emergency call, disconnect the call that we tried to
// hold.
mBackgroundCall.getImsCall().terminate(ImsReasonInfo.CODE_UNSPECIFIED);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 6ed00e3..661e48a 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -603,10 +603,14 @@
final UiccSlot slot = mUiccSlots[slotIndex];
boolean isEuicc = slot.isEuicc();
String eid = null;
- String iccid = slot.getUiccCard().getIccId();
+ UiccCard card = slot.getUiccCard();
+ if (card == null) {
+ continue;
+ }
+ String iccid = card.getIccId();
int cardId = INVALID_CARD_ID;
if (isEuicc) {
- eid = slot.getUiccCard().getCardId();
+ eid = card.getCardId();
cardId = convertToPublicCardId(eid);
} else {
// leave eid null if the UICC is not embedded
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 34c9462..edcad49 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -201,7 +201,14 @@
}
public boolean isStateUnknown() {
- return (mCardState == null || mCardState == CardState.CARDSTATE_ABSENT) && mStateIsUnknown;
+ if (mCardState == null || mCardState == CardState.CARDSTATE_ABSENT) {
+ // mStateIsUnknown is valid only in this scenario.
+ return mStateIsUnknown;
+ }
+ // if mUiccCard is null, assume the state to be UNKNOWN for now.
+ // The state may be known but since the actual card object is not available,
+ // it is safer to return UNKNOWN.
+ return mUiccCard == null;
}
private void checkIsEuiccSupported() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index 10dd12b..e3e5d96 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -101,7 +101,9 @@
+ SubscriptionManager.GROUP_UUID + " TEXT,"
+ SubscriptionManager.IS_METERED + " INTEGER DEFAULT 1,"
+ SubscriptionManager.ISO_COUNTRY_CODE + " TEXT,"
- + SubscriptionManager.CARRIER_ID + " INTEGER DEFAULT -1"
+ + SubscriptionManager.CARRIER_ID + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.PROFILE_CLASS
+ + " INTEGER DEFAULT " + SubscriptionManager.PROFILE_CLASS_DEFAULT
+ ");";
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/ConnectivityServiceMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/ConnectivityServiceMock.java
index ccb3acc..a77588b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/ConnectivityServiceMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/ConnectivityServiceMock.java
@@ -55,7 +55,6 @@
import com.android.internal.net.VpnProfile;
import com.android.internal.util.AsyncChannel;
import com.android.server.connectivity.NetworkAgentInfo;
-import com.android.server.connectivity.NetworkMonitor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -262,7 +261,7 @@
//notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
//mKeepaliveTracker.handleStopAllKeepalives(nai,
// ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
- nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
+ // nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo);
//updateClat(null, nai.linkProperties, nai);
//synchronized (mNetworkForNetId) {
@@ -957,12 +956,6 @@
}
@VisibleForTesting
- public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
- NetworkAgentInfo nai, NetworkRequest defaultRequest) {
- throw new RuntimeException("not implemented");
- }
-
- @VisibleForTesting
public NetworkRequest defaultRequest = null;
@VisibleForTesting
public synchronized void addDefaultRequest() {
@@ -991,5 +984,8 @@
throw new RuntimeException("not implemented");
}
-
+ @Override
+ public NetworkRequest getDefaultRequest() {
+ throw new RuntimeException("not implemented");
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
index 1c636d5..418b46c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
@@ -23,6 +23,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.CellInfo;
+import android.telephony.DataFailCause;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
@@ -378,7 +379,7 @@
@Override
public void notifyPreciseDataConnectionFailed(String apnType, String apn,
- String failCause) {
+ @DataFailCause.FailCause int failCause) {
throw new RuntimeException("Not implemented");
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
index e1a5be0..dfd2bba 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -319,4 +319,29 @@
0); // slotIndex
assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
}
+
+ @Test
+ public void testGetAllUiccCardInfosNullCard() {
+ // Give UiccController a real context so it can use shared preferences
+ mUiccControllerUT.mContext = InstrumentationRegistry.getContext();
+
+ // Mock out UiccSlots
+ mUiccControllerUT.mUiccSlots[0] = mMockSlot;
+ doReturn(true).when(mMockSlot).isEuicc();
+ doReturn(null).when(mMockSlot).getUiccCard();
+
+ // simulate card status loaded so that the UiccController sets the card ID
+ IccCardStatus ics = new IccCardStatus();
+ ics.setCardState(1 /* present */);
+ ics.setUniversalPinState(3 /* disabled */);
+ ics.atr = "abcdef0123456789abcdef";
+ ics.iccid = "123451234567890";
+ ics.eid = "A1B2C3D4";
+ AsyncResult ar = new AsyncResult(null, ics, null);
+ Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
+ mUiccControllerUT.handleMessage(msg);
+
+ // assert that the getAllUiccCardInfos returns an empty list without crashing
+ assertEquals(0, mUiccControllerUT.getAllUiccCardInfos().size());
+ }
}