Merge "using the correct intent extra for subId"
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index c8cea5a..853b85f 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -792,15 +792,17 @@
* RadioState has 3 values : RADIO_OFF, RADIO_UNAVAILABLE, RADIO_ON.
*
* @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED
+ * @param forceNotifyRegistrants boolean indicating if registrants should be notified even if
+ * there is no change in state
*/
- protected void setRadioState(RadioState newState) {
+ protected void setRadioState(RadioState newState, boolean forceNotifyRegistrants) {
RadioState oldState;
synchronized (mStateMonitor) {
oldState = mState;
mState = newState;
- if (oldState == mState) {
+ if (oldState == mState && !forceNotifyRegistrants) {
// no state transition
return;
}
diff --git a/src/java/com/android/internal/telephony/CallManager.java b/src/java/com/android/internal/telephony/CallManager.java
index 78a9324..3a49a12 100644
--- a/src/java/com/android/internal/telephony/CallManager.java
+++ b/src/java/com/android/internal/telephony/CallManager.java
@@ -202,14 +202,6 @@
}
/**
- * Returns all the registered phone objects.
- * @return all the registered phone objects.
- */
- public List<Phone> getAllPhones() {
- return Collections.unmodifiableList(mPhones);
- }
-
- /**
* get Phone object corresponds to subId
* @return Phone
*/
@@ -346,19 +338,6 @@
return phone;
}
- public Phone getPhoneInCall(int subId) {
- Phone phone = null;
- if (!getFirstActiveRingingCall(subId).isIdle()) {
- phone = getFirstActiveRingingCall(subId).getPhone();
- } else if (!getActiveFgCall(subId).isIdle()) {
- phone = getActiveFgCall(subId).getPhone();
- } else {
- // If BG call is idle, we return default phone
- phone = getFirstActiveBgCall(subId).getPhone();
- }
- return phone;
- }
-
/**
* Register phone to CallManager
* @param phone to be registered
@@ -447,14 +426,6 @@
}
/**
- * @return the phone associated with the background call
- * of a particular subId
- */
- public Phone getBgPhone(int subId) {
- return getFirstActiveBgCall(subId).getPhone();
- }
-
- /**
* @return the phone associated with the ringing call
*/
public Phone getRingingPhone() {
@@ -1926,42 +1897,6 @@
}
/**
- * @return the connections of active background call
- * return empty list if there is no active background call
- */
- public List<Connection> getBgCallConnections(int subId) {
- Call bgCall = getFirstActiveBgCall(subId);
- if ( bgCall != null) {
- return bgCall.getConnections();
- }
- return mEmptyConnections;
- }
-
- /**
- * @return the latest connection of active foreground call
- * return null if there is no active foreground call
- */
- public Connection getFgCallLatestConnection() {
- Call fgCall = getActiveFgCall();
- if ( fgCall != null) {
- return fgCall.getLatestConnection();
- }
- return null;
- }
-
- /**
- * @return the latest connection of active foreground call
- * return null if there is no active foreground call
- */
- public Connection getFgCallLatestConnection(int subId) {
- Call fgCall = getActiveFgCall(subId);
- if ( fgCall != null) {
- return fgCall.getLatestConnection();
- }
- return null;
- }
-
- /**
* @return true if there is at least one Foreground call in disconnected state
*/
public boolean hasDisconnectedFgCall() {
@@ -2092,22 +2027,6 @@
return false;
}
- /* FIXME Taken from klp-sprout-dev but setAudioMode was removed in L.
- private boolean isServiceStateInService() {
- boolean bInService = false;
-
- for (Phone phone : mPhones) {
- bInService = (phone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE);
- if (bInService) {
- break;
- }
- }
-
- if (VDBG) Rlog.d(LOG_TAG, "[isServiceStateInService] bInService = " + bInService);
- return bInService;
- }
- */
-
private class CallManagerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
@@ -2236,52 +2155,4 @@
}
}
};
-
- @Override
- public String toString() {
- Call call;
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
- b.append("CallManager {");
- b.append("\nstate = " + getState(i));
- call = getActiveFgCall(i);
- if (call != null) {
- b.append("\n- Foreground: " + getActiveFgCallState(i));
- b.append(" from " + call.getPhone());
- b.append("\n Conn: ").append(getFgCallConnections(i));
- }
- call = getFirstActiveBgCall(i);
- if (call != null) {
- b.append("\n- Background: " + call.getState());
- b.append(" from " + call.getPhone());
- b.append("\n Conn: ").append(getBgCallConnections(i));
- }
- call = getFirstActiveRingingCall(i);
- if (call != null) {
- b.append("\n- Ringing: " +call.getState());
- b.append(" from " + call.getPhone());
- }
- }
-
- for (Phone phone : getAllPhones()) {
- if (phone != null) {
- b.append("\nPhone: " + phone + ", name = " + phone.getPhoneName()
- + ", state = " + phone.getState());
- call = phone.getForegroundCall();
- if (call != null) {
- b.append("\n- Foreground: ").append(call);
- }
- call = phone.getBackgroundCall();
- if (call != null) {
- b.append(" Background: ").append(call);
- }
- call = phone.getRingingCall();
- if (call != null) {
- b.append(" Ringing: ").append(call);
- }
- }
- }
- b.append("\n}");
- return b.toString();
- }
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index d4be7af..66c05cf 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -421,8 +421,7 @@
public ServiceState getServiceState() {
if (mSST == null || mSST.mSS.getState() != ServiceState.STATE_IN_SERVICE) {
if (mImsPhone != null) {
- return ServiceState.mergeServiceStates(
- (mSST == null) ? new ServiceState() : mSST.mSS,
+ return mergeServiceStates((mSST == null) ? new ServiceState() : mSST.mSS,
mImsPhone.getServiceState());
}
}
@@ -829,6 +828,32 @@
return mCT.mRingingCall;
}
+ /**
+ * ImsService reports "IN_SERVICE" for its voice registration state even if the device
+ * has lost the physical link to the tower. This helper method merges the IMS and modem
+ * ServiceState, only overriding the voice registration state when we are registered to IMS over
+ * IWLAN. In this case the voice registration state will always be "OUT_OF_SERVICE", so override
+ * the voice registration state with the data registration state.
+ */
+ private ServiceState mergeServiceStates(ServiceState baseSs, ServiceState imsSs) {
+ // "IN_SERVICE" in this case means IMS is registered.
+ if (imsSs.getVoiceRegState() != ServiceState.STATE_IN_SERVICE) {
+ return baseSs;
+ }
+
+ if (imsSs.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
+ ServiceState newSs = new ServiceState(baseSs);
+ // Voice override for IWLAN. In this case, voice registration is OUT_OF_SERVICE, but
+ // the data RAT is IWLAN, so use that as a basis for determining whether or not the
+ // physical link is available.
+ newSs.setVoiceRegState(baseSs.getDataRegState());
+ newSs.setEmergencyOnly(false); // only get here if voice is IN_SERVICE
+ return newSs;
+ }
+
+ return baseSs;
+ }
+
private boolean handleCallDeflectionIncallSupplementaryService(
String dialString) {
if (dialString.length() > 1) {
@@ -2854,8 +2879,8 @@
* selection is disallowed. So we should force auto select mode.
*/
if (isManualSelProhibitedInGlobalMode()
- && ((nwMode == Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA)
- || (nwMode == Phone.NT_MODE_GLOBAL)) ){
+ && ((nwMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA)
+ || (nwMode == TelephonyManager.NETWORK_MODE_GLOBAL)) ){
logd("Should force auto network select mode = " + nwMode);
return true;
} else {
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 2a35370..42a156a 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -75,6 +75,8 @@
logd("GET_RECORD_SIZE Size " + mRecordSize[0] +
" total " + mRecordSize[1] +
" #record " + mRecordSize[2]);
+ } else {
+ loge("EVENT_GET_SIZE_DONE: failed; ex=" + ar.exception);
}
notifyPending(ar);
}
@@ -83,6 +85,9 @@
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
mSuccess = (ar.exception == null);
+ if (!mSuccess) {
+ loge("EVENT_UPDATE_DONE - failed; ex=" + ar.exception);
+ }
notifyPending(ar);
}
break;
@@ -92,7 +97,8 @@
if (ar.exception == null) {
mRecords = (List<AdnRecord>) ar.result;
} else {
- if(DBG) logd("Cannot load ADN records");
+ loge("EVENT_LOAD_DONE: Cannot load ADN records; ex="
+ + ar.exception);
mRecords = null;
}
notifyPending(ar);
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index d7cb490..9b01a0b 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -184,11 +184,6 @@
}
}
- protected void updatePhoneObject(Phone phone) {
- mPhone = phone;
- mDispatchersController.updatePhoneObject(phone);
- }
-
protected void enforceReceiveAndSend(String message) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.RECEIVE_SMS, message);
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index ee28cbc..b779299 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -154,14 +154,11 @@
/** Sent by {@link SmsBroadcastUndelivered} after cleaning the raw table. */
public static final int EVENT_START_ACCEPTING_SMS = 6;
- /** Update phone object */
- private static final int EVENT_UPDATE_PHONE_OBJECT = 7;
-
/** New SMS received as an AsyncResult. */
- public static final int EVENT_INJECT_SMS = 8;
+ public static final int EVENT_INJECT_SMS = 7;
/** Update the sms tracker */
- public static final int EVENT_UPDATE_TRACKER = 9;
+ public static final int EVENT_UPDATE_TRACKER = 8;
/** Wakelock release delay when returning to idle state. */
private static final int WAKELOCK_TIMEOUT = 3000;
@@ -272,13 +269,6 @@
}
/**
- * Update the phone object when it changes.
- */
- public void updatePhoneObject(Phone phone) {
- sendMessage(EVENT_UPDATE_PHONE_OBJECT, phone);
- }
-
- /**
* Dispose of the WAP push object and release the wakelock.
*/
@Override
@@ -303,10 +293,6 @@
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
- case EVENT_UPDATE_PHONE_OBJECT: {
- onUpdatePhoneObject((Phone) msg.obj);
- break;
- }
default: {
String errorText = "processMessage: unhandled message type " + msg.what +
" currState=" + getCurrentState().getName();
@@ -674,19 +660,6 @@
int result, Message response);
/**
- * Called when the phone changes the default method updates mPhone
- * mStorageMonitor and mCellBroadcastHandler.updatePhoneObject.
- * Override if different or other behavior is desired.
- *
- * @param phone
- */
- protected void onUpdatePhoneObject(Phone phone) {
- mPhone = phone;
- mStorageMonitor = mPhone.mSmsStorageMonitor;
- log("onUpdatePhoneObject: phone=" + mPhone.getClass().getSimpleName());
- }
-
- /**
* Notify interested apps if the framework has rejected an incoming SMS,
* and send an acknowledge message to the network.
* @param success indicates that last message was successfully received.
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index fd99196..a304ab6 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -176,36 +176,6 @@
static final int BM_US_2500M = RILConstants.BAND_MODE_USA_2500M;
static final int BM_NUM_BAND_MODES = 19; //Total number of band modes
- // Used for preferred network type
- // Note NT_* substitute RILConstants.NETWORK_MODE_* above the Phone
- int NT_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF;
- int NT_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY;
- int NT_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY;
- int NT_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS;
-
- int NT_MODE_CDMA = RILConstants.NETWORK_MODE_CDMA;
-
- int NT_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
- int NT_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
- int NT_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
-
- int NT_MODE_LTE_CDMA_AND_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
- int NT_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA;
- int NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
- int NT_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY;
- int NT_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA;
-
- int NT_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
- int NT_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
- int NT_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
- int NT_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
- int NT_MODE_LTE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
- int NT_MODE_TDSCDMA_GSM_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
- int NT_MODE_LTE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
- int NT_MODE_LTE_TDSCDMA_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
- int NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
- int NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
-
int PREFERRED_NT_MODE = RILConstants.PREFERRED_NETWORK_MODE;
// Used for CDMA roaming mode
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 33f7a47..638fa31 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -353,7 +353,7 @@
// increment the cookie so that death notification can be ignored
mRadioProxyCookie.incrementAndGet();
- setRadioState(RadioState.RADIO_UNAVAILABLE);
+ setRadioState(RadioState.RADIO_UNAVAILABLE, true /* forceNotifyRegistrants */);
RILRequest.resetSerial();
// Clear request list on close
@@ -4188,7 +4188,7 @@
}
break;
case RIL_REQUEST_SHUTDOWN:
- setRadioState(RadioState.RADIO_UNAVAILABLE);
+ setRadioState(RadioState.RADIO_UNAVAILABLE, false /* forceNotifyRegistrants */);
break;
}
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index f7a7943..ae76ef3 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -126,7 +126,7 @@
newState);
}
- mRil.setRadioState(newState);
+ mRil.setRadioState(newState, false /* forceNotifyRegistrants */);
}
public void callStateChanged(int indicationType) {
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 052178b..2420ac4 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -221,11 +221,6 @@
}
}
- protected void updatePhoneObject(Phone phone) {
- mPhone = phone;
- Rlog.d(TAG, "Active phone changed to " + mPhone.getPhoneName() );
- }
-
/** Unregister for incoming SMS events. */
public void dispose() {
mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index d8906e7..ff01d5b 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -104,15 +104,6 @@
mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
}
- /* Updates the phone object when there is a change */
- protected void updatePhoneObject(Phone phone) {
- Rlog.d(TAG, "In IMS updatePhoneObject ");
- mCdmaDispatcher.updatePhoneObject(phone);
- mGsmDispatcher.updatePhoneObject(phone);
- mGsmInboundSmsHandler.updatePhoneObject(phone);
- mCdmaInboundSmsHandler.updatePhoneObject(phone);
- }
-
public void dispose() {
mCi.unregisterForOn(this);
mCi.unregisterForImsNetworkStateChanged(this);
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 962a1fa..9766cf0 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -55,12 +55,14 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@@ -90,9 +92,15 @@
private static final int DEPRECATED_SETTING = -1;
private ScLocalLog mLocalLog = new ScLocalLog(MAX_LOCAL_LOG_LINES);
+ // Lock that both mCacheActiveSubInfoList and mCacheOpportunisticSubInfoList use.
+ private Object mSubInfoListLock = new Object();
+
/* The Cache of Active SubInfoRecord(s) list of currently in use SubInfoRecord(s) */
private final List<SubscriptionInfo> mCacheActiveSubInfoList = new ArrayList<>();
+ /* Similar to mCacheActiveSubInfoList but only caching opportunistic subscriptions. */
+ private List<SubscriptionInfo> mCacheOpportunisticSubInfoList = new ArrayList<>();
+
/**
* Copied from android.util.LocalLog with flush() adding flush and line number
* TODO: Update LocalLog
@@ -149,12 +157,12 @@
protected static Phone[] sPhones;
protected Context mContext;
protected TelephonyManager mTelephonyManager;
- protected CallManager mCM;
private AppOpsManager mAppOps;
- // Each slot can have multiple subs.
- private static Map<Integer, ArrayList<Integer>> sSlotIndexToSubIds = new ConcurrentHashMap<>();
+ // FIXME: Does not allow for multiple subs in a slot and change to SparseArray
+ private static Map<Integer, Integer> sSlotIndexToSubId =
+ new ConcurrentHashMap<Integer, Integer>();
private static int mDefaultFallbackSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
@@ -199,7 +207,6 @@
protected void init(Context c) {
mContext = c;
- mCM = CallManager.getInstance();
mTelephonyManager = TelephonyManager.from(mContext);
mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -213,12 +220,11 @@
}
private boolean isSubInfoReady() {
- return sSlotIndexToSubIds.size() > 0;
+ return sSlotIndexToSubId.size() > 0;
}
private SubscriptionController(Phone phone) {
mContext = phone.getContext();
- mCM = CallManager.getInstance();
mAppOps = mContext.getSystemService(AppOpsManager.class);
if(ServiceManager.getService("isub") == null) {
@@ -601,39 +607,7 @@
*/
@Override
public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {
- if (!isSubInfoReady()) {
- if (DBG) logdl("[getActiveSubInfoList] Sub Controller not ready");
- return null;
- }
-
- boolean canReadAllPhoneState;
- try {
- canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
- Binder.getCallingUid(), callingPackage, "getActiveSubscriptionInfoList");
- } catch (SecurityException e) {
- canReadAllPhoneState = false;
- }
-
- synchronized (mCacheActiveSubInfoList) {
- // If the caller can read all phone state, just return the full list.
- if (canReadAllPhoneState) {
- return new ArrayList<>(mCacheActiveSubInfoList);
- }
-
- // Filter the list to only include subscriptions which the caller can manage.
- return mCacheActiveSubInfoList.stream()
- .filter(subscriptionInfo -> {
- try {
- return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
- subscriptionInfo.getSubscriptionId(), callingPackage,
- "getActiveSubscriptionInfoList");
- } catch (SecurityException e) {
- return false;
- }
- })
- .collect(Collectors.toList());
- }
+ return getSubscriptionInfoListFromCacheHelper(callingPackage, mCacheActiveSubInfoList);
}
/**
@@ -649,7 +623,9 @@
return;
}
- synchronized (mCacheActiveSubInfoList) {
+ boolean opptSubListChanged = false;
+
+ synchronized (mSubInfoListLock) {
mCacheActiveSubInfoList.clear();
List<SubscriptionInfo> activeSubscriptionInfoList = getSubInfo(
SubscriptionManager.SIM_SLOT_INDEX + ">=0", null);
@@ -657,6 +633,10 @@
activeSubscriptionInfoList.sort(SUBSCRIPTION_INFO_COMPARATOR);
mCacheActiveSubInfoList.addAll(activeSubscriptionInfoList);
}
+
+ // Refresh cached opportunistic sub list and detect whether it's changed.
+ opptSubListChanged = refreshCachedOpportunisticSubscriptionInfoList();
+
if (DBG_CACHE) {
if (!mCacheActiveSubInfoList.isEmpty()) {
for (SubscriptionInfo si : mCacheActiveSubInfoList) {
@@ -668,6 +648,11 @@
}
}
}
+
+ // Send notification outside synchronization.
+ if (opptSubListChanged) {
+ notifyOpportunisticSubscriptionInfoChanged();
+ }
}
/**
@@ -979,20 +964,24 @@
do {
int subId = cursor.getInt(cursor.getColumnIndexOrThrow(
SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID));
- // If sSlotIndexToSubIds already has the same subId for a slotIndex/phoneId,
+ // If sSlotIndexToSubId already has the same subId for a slotIndex/phoneId,
// do not add it.
- if (addToSubIdList(slotIndex, subId)) {
+ Integer currentSubId = sSlotIndexToSubId.get(slotIndex);
+ if (currentSubId == null
+ || currentSubId != subId
+ || !SubscriptionManager.isValidSubscriptionId(currentSubId)) {
// TODO While two subs active, if user deactivats first
// one, need to update the default subId with second one.
// FIXME: Currently we assume phoneId == slotIndex which in the future
// may not be true, for instance with multiple subs per slot.
// But is true at the moment.
+ sSlotIndexToSubId.put(slotIndex, subId);
int subIdCountMax = getActiveSubInfoCountMax();
int defaultSubId = getDefaultSubId();
if (DBG) {
logdl("[addSubInfoRecord]"
- + " sSlotIndexToSubIds.size=" + sSlotIndexToSubIds.size()
+ + " sSlotIndexToSubId.size=" + sSlotIndexToSubId.size()
+ " slotIndex=" + slotIndex + " subId=" + subId
+ " defaultSubId=" + defaultSubId + " simCount=" + subIdCountMax);
}
@@ -1059,7 +1048,7 @@
// Once the records are loaded, notify DcTracker
sPhones[slotIndex].updateDataConnectionTracker();
- if (DBG) logdl("[addSubInfoRecord]- info size=" + sSlotIndexToSubIds.size());
+ if (DBG) logdl("[addSubInfoRecord]- info size=" + sSlotIndexToSubId.size());
} finally {
Binder.restoreCallingIdentity(identity);
@@ -1412,18 +1401,20 @@
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
}
- int size = sSlotIndexToSubIds.size();
+ int size = sSlotIndexToSubId.size();
- if (size == 0) {
+ if (size == 0)
+ {
if (DBG) logd("[getSlotIndex]- size == 0, return SIM_NOT_INSERTED instead");
return SubscriptionManager.SIM_NOT_INSERTED;
}
- for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, Integer> entry: sSlotIndexToSubId.entrySet()) {
int sim = entry.getKey();
- ArrayList<Integer> subs = entry.getValue();
+ int sub = entry.getValue();
- if (subs.contains(subId)) {
+ if (subId == sub)
+ {
if (VDBG) logv("[getSlotIndex]- return = " + sim);
return sim;
}
@@ -1459,17 +1450,26 @@
}
// Check if we've got any SubscriptionInfo records using slotIndexToSubId as a surrogate.
- int size = sSlotIndexToSubIds.size();
+ int size = sSlotIndexToSubId.size();
if (size == 0) {
if (VDBG) {
- logd("[getSubId]- sSlotIndexToSubIds.size == 0, return DummySubIds slotIndex="
+ logd("[getSubId]- sSlotIndexToSubId.size == 0, return DummySubIds slotIndex="
+ slotIndex);
}
return getDummySubIds(slotIndex);
}
+ // Create an array of subIds that are in this slot?
+ ArrayList<Integer> subIds = new ArrayList<Integer>();
+ for (Entry<Integer, Integer> entry: sSlotIndexToSubId.entrySet()) {
+ int slot = entry.getKey();
+ int sub = entry.getValue();
+ if (slotIndex == slot) {
+ subIds.add(sub);
+ }
+ }
+
// Convert ArrayList to array
- ArrayList<Integer> subIds = sSlotIndexToSubIds.get(slotIndex);
int numSubIds = subIds.size();
if (numSubIds > 0) {
int[] subIdArr = new int[numSubIds];
@@ -1502,7 +1502,7 @@
return SubscriptionManager.INVALID_PHONE_INDEX;
}
- int size = sSlotIndexToSubIds.size();
+ int size = sSlotIndexToSubId.size();
if (size == 0) {
phoneId = mDefaultPhoneId;
if (DBG) logdl("[getPhoneId]- no sims, returning default phoneId=" + phoneId);
@@ -1510,11 +1510,11 @@
}
// FIXME: Assumes phoneId == slotIndex
- for (Entry<Integer, ArrayList<Integer>> entry: sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, Integer> entry: sSlotIndexToSubId.entrySet()) {
int sim = entry.getKey();
- ArrayList<Integer> subs = entry.getValue();
+ int sub = entry.getValue();
- if (subs.contains(subId)) {
+ if (subId == sub) {
if (VDBG) logdl("[getPhoneId]- found subId=" + subId + " phoneId=" + sim);
return sim;
}
@@ -1559,14 +1559,14 @@
// Now that all security checks passes, perform the operation as ourselves.
final long identity = Binder.clearCallingIdentity();
try {
- int size = sSlotIndexToSubIds.size();
+ int size = sSlotIndexToSubId.size();
if (size == 0) {
if (DBG) logdl("[clearSubInfo]- no simInfo size=" + size);
return 0;
}
- sSlotIndexToSubIds.clear();
+ sSlotIndexToSubId.clear();
if (DBG) logdl("[clearSubInfo]- clear size=" + size);
return size;
} finally {
@@ -1927,29 +1927,23 @@
sPhones = phones;
}
- private synchronized ArrayList<Integer> getActiveSubIdArrayList() {
- ArrayList<Integer> allSubs = new ArrayList<>();
- for (int i : sSlotIndexToSubIds.keySet()) {
- allSubs.addAll(sSlotIndexToSubIds.get(i));
- }
- return allSubs;
- }
-
/**
* @return the list of subId's that are active, is never null but the length maybe 0.
*/
@Override
public int[] getActiveSubIdList() {
- ArrayList<Integer> allSubs = getActiveSubIdArrayList();
- int[] subIdArr = new int[allSubs.size()];
+ Set<Entry<Integer, Integer>> simInfoSet = new HashSet<>(sSlotIndexToSubId.entrySet());
+
+ int[] subIdArr = new int[simInfoSet.size()];
int i = 0;
- for (int sub : allSubs) {
+ for (Entry<Integer, Integer> entry: simInfoSet) {
+ int sub = entry.getValue();
subIdArr[i] = sub;
i++;
}
if (VDBG) {
- logdl("[getActiveSubIdList] allSubs=" + allSubs + " subIdArr.length="
+ logdl("[getActiveSubIdList] simInfoSet=" + simInfoSet + " subIdArr.length="
+ subIdArr.length);
}
return subIdArr;
@@ -1972,7 +1966,7 @@
@Deprecated // This should be moved into isActiveSubId(int, String)
public boolean isActiveSubId(int subId) {
boolean retVal = SubscriptionManager.isValidSubscriptionId(subId)
- && getActiveSubIdArrayList().contains(subId);
+ && sSlotIndexToSubId.containsValue(subId);
if (VDBG) logdl("[isActiveSubId]- " + retVal);
return retVal;
@@ -2175,8 +2169,8 @@
.from(mContext).getDefaultSmsPhoneId());
pw.flush();
- for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
- pw.println(" sSlotIndexToSubId[" + entry.getKey() + "]: subIds=" + entry);
+ for (Entry<Integer, Integer> entry : sSlotIndexToSubId.entrySet()) {
+ pw.println(" sSlotIndexToSubId[" + entry.getKey() + "]: subId=" + entry.getValue());
}
pw.flush();
pw.println("++++++++++++++++++++++++++++++++");
@@ -2313,44 +2307,81 @@
@Override
public List<SubscriptionInfo> getOpportunisticSubscriptions(int slotId, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
- "getOpportunisticSubscriptions")) {
+ return getSubscriptionInfoListFromCacheHelper(
+ callingPackage, mCacheOpportunisticSubInfoList);
+ }
+
+ // Helper function of getOpportunisticSubscriptions and getActiveSubscriptionInfoList.
+ // They are doing similar things except operating on different cache.
+ private List<SubscriptionInfo> getSubscriptionInfoListFromCacheHelper(
+ String callingPackage, List<SubscriptionInfo> cacheSubList) {
+ if (!isSubInfoReady()) {
+ if (DBG) logdl("[getSubscriptionInfoList] Sub Controller not ready");
return null;
}
- final long token = Binder.clearCallingIdentity();
-
+ boolean canReadAllPhoneState;
try {
- List<SubscriptionInfo> activeSubList = getActiveSubscriptionInfoList(callingPackage);
- List<SubscriptionInfo> opportunisticSubList = new ArrayList<>();
+ canReadAllPhoneState = TelephonyPermissions.checkReadPhoneState(mContext,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
+ Binder.getCallingUid(), callingPackage, "getSubscriptionInfoList");
+ } catch (SecurityException e) {
+ canReadAllPhoneState = false;
+ }
- if (activeSubList != null) {
- for (SubscriptionInfo subInfo : activeSubList) {
- if (subInfo.isOpportunistic() && subInfo.getSimSlotIndex() == slotId) {
- opportunisticSubList.add(subInfo);
- }
- }
+ synchronized (mSubInfoListLock) {
+ // If the caller can read all phone state, just return the full list.
+ if (canReadAllPhoneState) {
+ return new ArrayList<>(cacheSubList);
}
- return opportunisticSubList;
- } finally {
- Binder.restoreCallingIdentity(token);
+ // Filter the list to only include subscriptions which the caller can manage.
+ return cacheSubList.stream()
+ .filter(subscriptionInfo -> {
+ try {
+ return TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
+ subscriptionInfo.getSubscriptionId(), callingPackage,
+ "getOpportunisticSubscriptions");
+ } catch (SecurityException e) {
+ return false;
+ }
+ })
+ .collect(Collectors.toList());
}
}
- private synchronized boolean addToSubIdList(int slotIndex, int subId) {
- ArrayList<Integer> subIdsList = sSlotIndexToSubIds.get(slotIndex);
- if (subIdsList == null) {
- subIdsList = new ArrayList<>();
- sSlotIndexToSubIds.put(slotIndex, subIdsList);
+ private void notifyOpportunisticSubscriptionInfoChanged() {
+ ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+ "telephony.registry"));
+ try {
+ if (DBG) logd("notifyOpptSubscriptionInfoChanged:");
+ tr.notifyOpportunisticSubscriptionInfoChanged();
+ } catch (RemoteException ex) {
+ // Should never happen because its always available.
}
+ }
- // add the given subId unless it already exists
- if (!subIdsList.contains(subId)) {
- subIdsList.add(subId);
- return true;
+
+ private boolean refreshCachedOpportunisticSubscriptionInfoList() {
+ synchronized (mSubInfoListLock) {
+ List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList;
+
+ mCacheOpportunisticSubInfoList = mCacheActiveSubInfoList.stream()
+ .filter(subscriptionInfo -> subscriptionInfo.isOpportunistic())
+ .collect(Collectors.toList());
+
+ if (DBG_CACHE) {
+ if (!mCacheOpportunisticSubInfoList.isEmpty()) {
+ for (SubscriptionInfo si : mCacheOpportunisticSubInfoList) {
+ logd("[refreshCachedOpptSubscriptionInfoList] Setting Cached info="
+ + si);
+ }
+ } else {
+ logdl("[refreshCachedOpptSubscriptionInfoList]- no info return");
+ }
+ }
+
+ return !oldOpptCachedList.equals(mCacheOpportunisticSubInfoList);
}
- return false;
}
}
diff --git a/src/java/com/android/internal/telephony/WakeLockStateMachine.java b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
index e2061b9..aca016f 100644
--- a/src/java/com/android/internal/telephony/WakeLockStateMachine.java
+++ b/src/java/com/android/internal/telephony/WakeLockStateMachine.java
@@ -48,8 +48,6 @@
/** Release wakelock after a short timeout when returning to idle state. */
static final int EVENT_RELEASE_WAKE_LOCK = 3;
- static final int EVENT_UPDATE_PHONE_OBJECT = 4;
-
protected Phone mPhone;
protected Context mContext;
@@ -77,10 +75,6 @@
setInitialState(mIdleState);
}
- public void updatePhoneObject(Phone phone) {
- sendMessage(EVENT_UPDATE_PHONE_OBJECT, phone);
- }
-
/**
* Tell the state machine to quit after processing all messages.
*/
@@ -112,11 +106,6 @@
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
- case EVENT_UPDATE_PHONE_OBJECT: {
- mPhone = (Phone) msg.obj;
- log("updatePhoneObject: phone=" + mPhone.getClass().getSimpleName());
- break;
- }
default: {
String errorText = "processMessage: unhandled message type " + msg.what;
if (Build.IS_DEBUGGABLE) {
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index e2c178a..46d0243 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -193,19 +193,6 @@
}
/**
- * Called when the phone changes the default method updates mPhone
- * mStorageMonitor and mCellBroadcastHandler.updatePhoneObject.
- * Override if different or other behavior is desired.
- *
- * @param phone
- */
- @Override
- protected void onUpdatePhoneObject(Phone phone) {
- super.onUpdatePhoneObject(phone);
- mCellBroadcastHandler.updatePhoneObject(phone);
- }
-
- /**
* Convert Android result code to CDMA SMS failure cause.
* @param rc the Android SMS intent result value
* @return 0 for success, or a CDMA SMS failure cause value
diff --git a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
index 3fe2a33..f6efc5f 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
@@ -177,22 +177,6 @@
}
/**
- * Called when the phone changes the default method updates mPhone
- * mStorageMonitor and mCellBroadcastHandler.updatePhoneObject.
- * Override if different or other behavior is desired.
- *
- * @param phone
- */
- @Override
- protected void onUpdatePhoneObject(Phone phone) {
- super.onUpdatePhoneObject(phone);
- log("onUpdatePhoneObject: dispose of old CellBroadcastHandler and make a new one");
- mCellBroadcastHandler.dispose();
- mCellBroadcastHandler = GsmCellBroadcastHandler
- .makeGsmCellBroadcastHandler(mContext, phone);
- }
-
- /**
* Convert Android result code to 3GPP SMS failure cause.
* @param rc the Android SMS intent result value
* @return 0 for success, or a 3GPP SMS failure cause value
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index f0aee01..4a030b1 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -1131,17 +1131,6 @@
}
}
- /**
- * @return true if the ImsResolver is in the process of resolving a dynamic query and should not
- * be considered available, false if the ImsResolver is idle.
- */
- public boolean isResolvingBinding() {
- return mHandler.hasMessages(HANDLER_START_DYNAMIC_FEATURE_QUERY)
- // We haven't processed this message yet, so it is still resolving.
- || mHandler.hasMessages(HANDLER_DYNAMIC_FEATURE_CHANGE)
- || mFeatureQueryManager.isQueryInProgress();
- }
-
private String printFeatures(Set<ImsFeatureConfiguration.FeatureSlotPair> features) {
StringBuilder featureString = new StringBuilder();
featureString.append("features: [");
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index a241785..e3c147b 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -158,7 +158,7 @@
simulatedCallState = new SimulatedGsmCallState(looper);
- setRadioState(RadioState.RADIO_ON);
+ setRadioState(RadioState.RADIO_ON, false /* forceNotifyRegistrants */);
mSimLockedState = INITIAL_LOCK_STATE;
mSimLockEnabled = (mSimLockedState != SimLockState.NONE);
mPinCode = DEFAULT_SIM_PIN_CODE;
@@ -1241,9 +1241,9 @@
}
if(on) {
- setRadioState(RadioState.RADIO_ON);
+ setRadioState(RadioState.RADIO_ON, false /* forceNotifyRegistrants */);
} else {
- setRadioState(RadioState.RADIO_OFF);
+ setRadioState(RadioState.RADIO_OFF, false /* forceNotifyRegistrants */);
}
resultSuccess(result, null);
}
@@ -1599,7 +1599,7 @@
@Override
public void
shutdown() {
- setRadioState(RadioState.RADIO_UNAVAILABLE);
+ setRadioState(RadioState.RADIO_UNAVAILABLE, false /* forceNotifyRegistrants */);
Looper looper = mHandlerThread.getLooper();
if (looper != null) {
looper.quit();
@@ -2024,7 +2024,7 @@
@Override
public void requestShutdown(Message result) {
- setRadioState(RadioState.RADIO_UNAVAILABLE);
+ setRadioState(RadioState.RADIO_UNAVAILABLE, false /* forceNotifyRegistrants */);
}
@Override
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index 91cc5a0..7bc2acc 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -29,6 +29,7 @@
import android.text.TextUtils;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.MccTable;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -46,6 +47,30 @@
protected static final boolean DBG = true;
protected static final boolean VDBG = false; // STOPSHIP if true
+ // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
+ private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
+ "302370", "302720", "310260",
+ "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
+ "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
+ "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
+ "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
+ "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
+ "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
+ "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
+ "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
+ "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
+ "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
+ "405849", "405850", "405851", "405852", "405853", "405854", "405855", "405856",
+ "405857", "405858", "405859", "405860", "405861", "405862", "405863", "405864",
+ "405865", "405866", "405867", "405868", "405869", "405870", "405871", "405872",
+ "405873", "405874", "405875", "405876", "405877", "405878", "405879", "405880",
+ "405881", "405882", "405883", "405884", "405885", "405886", "405908", "405909",
+ "405910", "405911", "405912", "405913", "405914", "405915", "405916", "405917",
+ "405918", "405919", "405920", "405921", "405922", "405923", "405924", "405925",
+ "405926", "405927", "405928", "405929", "405930", "405931", "405932", "502142",
+ "502143", "502145", "502146", "502147", "502148"
+ };
+
// ***** Instance Variables
protected AtomicBoolean mDestroyed = new AtomicBoolean(false);
protected AtomicBoolean mLoaded = new AtomicBoolean(false);
@@ -93,7 +118,7 @@
protected String mNewVoiceMailNum = null;
protected String mNewVoiceMailTag = null;
protected boolean mIsVoiceMailFixed = false;
- protected String mImsi;
+ protected String mImsi; // IMSI must be only valid numeric characters 0-9 without padding 'f's
private IccIoResult auth_rsp;
protected int mMncLength = UNINITIALIZED;
@@ -456,15 +481,16 @@
}
/**
- * Imsi could be set by ServiceStateTrackers in case of cdma
- * @param imsi
+ * Update IMSI record and try to extract the PLMN information and notify registrants.
+ * @param inImsi the IMSI value
*/
- public void setImsi(String imsi) {
+ public void setImsi(String inImsi) {
// Remove trailing F's if present in IMSI.
- mImsi = IccUtils.stripTrailingFs(imsi);
- if (!Objects.equals(mImsi, imsi)) {
+ mImsi = IccUtils.stripTrailingFs(inImsi);
+ if (!Objects.equals(mImsi, inImsi)) {
loge("Invalid IMSI padding digits received.");
}
+
if (TextUtils.isEmpty(mImsi)) mImsi = null;
if (mImsi != null && !mImsi.matches("[0-9]+")) {
@@ -472,9 +498,64 @@
mImsi = null;
}
+ // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
+ // than 15 (and usually 15).
+ // This will also handle un-set IMSI records (all Fs)
+ if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
+ loge("invalid IMSI " + mImsi);
+ mImsi = null;
+ }
+
+ log("IMSI: mMncLength=" + mMncLength);
+
+ if (mImsi != null && mImsi.length() >= 6) {
+ log("IMSI: " + mImsi.substring(0, 6) + Rlog.pii(VDBG, mImsi.substring(6)));
+ }
+
+ // IMSI has changed so the PLMN might have changed as well
+ updateOperatorPlmn();
+
mImsiReadyRegistrants.notifyRegistrants();
}
+ protected void updateOperatorPlmn() {
+ // In case of a test override, use the test IMSI
+ String imsi = getIMSI();
+
+ if (imsi != null) {
+ // First try to guess the length based on a table of known 3-digit MNCs.
+ if (((mMncLength == UNKNOWN) || (mMncLength == 2)) && imsi.length() >= 6) {
+ String mccmncCode = imsi.substring(0, 6);
+ for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
+ if (mccmnc.equals(mccmncCode)) {
+ mMncLength = 3;
+ log("IMSI: setting1 mMncLength=" + mMncLength);
+ break;
+ }
+ }
+ }
+
+ // If still unknown, guess using the MCC.
+ if (mMncLength == UNKNOWN) {
+ try {
+ int mcc = Integer.parseInt(imsi.substring(0, 3));
+ mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
+ log("setting2 mMncLength=" + mMncLength);
+ } catch (NumberFormatException e) {
+ loge("Corrupt IMSI! setting3 mMncLength=" + mMncLength);
+ }
+ }
+
+ if (mMncLength != UNKNOWN && mMncLength != UNINITIALIZED
+ && imsi.length() >= 3 + mMncLength) {
+ log("update mccmnc=" + imsi.substring(0, 3 + mMncLength));
+ // finally have both the imsi and the mncLength and
+ // can parse the imsi properly
+ MccTable.updateMccMncConfiguration(mContext, imsi.substring(0, 3 + mMncLength));
+ }
+ }
+ }
+
/**
* Get the Network Access ID (NAI) on a CSIM for CDMA like networks. Default is null if IMSI is
* not supported or unavailable.
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 10e651f..4f44f15 100755
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -40,7 +40,6 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Objects;
/**
* {@hide}
@@ -172,31 +171,6 @@
private static final int EVENT_APP_NETWORK_LOCKED = 3 + SYSTEM_EVENT_BASE;
- // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
-
- private static final String[] MCCMNC_CODES_HAVING_3DIGITS_MNC = {
- "302370", "302720", "310260",
- "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
- "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
- "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
- "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
- "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
- "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
- "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
- "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
- "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
- "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
- "405849", "405850", "405851", "405852", "405853", "405854", "405855", "405856",
- "405857", "405858", "405859", "405860", "405861", "405862", "405863", "405864",
- "405865", "405866", "405867", "405868", "405869", "405870", "405871", "405872",
- "405873", "405874", "405875", "405876", "405877", "405878", "405879", "405880",
- "405881", "405882", "405883", "405884", "405885", "405886", "405908", "405909",
- "405910", "405911", "405912", "405913", "405914", "405915", "405916", "405917",
- "405918", "405919", "405920", "405921", "405922", "405923", "405924", "405925",
- "405926", "405927", "405928", "405929", "405930", "405931", "405932", "502142",
- "502143", "502145", "502146", "502147", "502148"
- };
-
// ***** Constructor
public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
@@ -656,7 +630,6 @@
/* IO events */
case EVENT_GET_IMSI_DONE:
isRecordLoadResponse = true;
-
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
@@ -664,69 +637,7 @@
break;
}
- String imsi = (String) ar.result;
- // Remove trailing F's if present in IMSI.
- mImsi = IccUtils.stripTrailingFs(imsi);
-
- if (!Objects.equals(mImsi, imsi)) {
- loge("Invalid IMSI padding digits received.");
- }
-
- if (mImsi != null && !mImsi.matches("[0-9]+")) {
- loge("Invalid non-numeric IMSI digits received.");
- mImsi = null;
- }
-
- // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
- // than 15 (and usually 15).
- if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
- loge("invalid IMSI " + mImsi);
- mImsi = null;
- }
-
- log("IMSI: mMncLength=" + mMncLength);
-
- if (mImsi != null && mImsi.length() >= 6) {
- log("IMSI: " + mImsi.substring(0, 6)
- + Rlog.pii(LOG_TAG, mImsi.substring(6)));
- }
-
- imsi = getIMSI();
-
- if (((mMncLength == UNKNOWN) || (mMncLength == 2))
- && ((imsi != null) && (imsi.length() >= 6))) {
- String mccmncCode = imsi.substring(0, 6);
- for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
- if (mccmnc.equals(mccmncCode)) {
- mMncLength = 3;
- log("IMSI: setting1 mMncLength=" + mMncLength);
- break;
- }
- }
- }
-
- if (mMncLength == UNKNOWN) {
- // the SIM has told us all it knows, but it didn't know the mnc length.
- // guess using the mcc
- try {
- int mcc = Integer.parseInt(imsi.substring(0, 3));
- mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
- log("setting2 mMncLength=" + mMncLength);
- } catch (NumberFormatException e) {
- mMncLength = UNKNOWN;
- loge("Corrupt IMSI! setting3 mMncLength=" + mMncLength);
- }
- }
-
- if (mMncLength != UNKNOWN && mMncLength != UNINITIALIZED
- && imsi.length() >= 3 + mMncLength) {
- log("update mccmnc=" + imsi.substring(0, 3 + mMncLength));
- // finally have both the imsi and the mncLength and
- // can parse the imsi properly
- MccTable.updateMccMncConfiguration(mContext,
- imsi.substring(0, 3 + mMncLength));
- }
- mImsiReadyRegistrants.notifyRegistrants();
+ setImsi((String) ar.result);
break;
case EVENT_GET_MBI_DONE:
@@ -914,20 +825,10 @@
break;
case EVENT_GET_AD_DONE:
+ isRecordLoadResponse = true;
+ mMncLength = UNKNOWN;
try {
- isRecordLoadResponse = true;
-
- if (mCarrierTestOverride.isInTestMode() && getIMSI() != null) {
- imsi = getIMSI();
- try {
- int mcc = Integer.parseInt(imsi.substring(0, 3));
- mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
- log("[TestMode] mMncLength=" + mMncLength);
- } catch (NumberFormatException e) {
- mMncLength = UNKNOWN;
- loge("[TestMode] Corrupt IMSI! mMncLength=" + mMncLength);
- }
- } else {
+ if (!mCarrierTestOverride.isInTestMode()) {
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
@@ -947,62 +848,15 @@
break;
}
- mMncLength = data[3] & 0xf;
- log("setting4 mMncLength=" + mMncLength);
- }
-
- if (mMncLength == 0xf) {
- mMncLength = UNKNOWN;
- log("setting5 mMncLength=" + mMncLength);
- } else if (mMncLength != 2 && mMncLength != 3) {
- mMncLength = UNINITIALIZED;
- log("setting5 mMncLength=" + mMncLength);
+ int len = data[3] & 0xf;
+ if (len == 2 || len == 3) {
+ mMncLength = len;
+ } else {
+ log("Received invalid or unset MNC Length=" + len);
+ }
}
} finally {
-
- // IMSI could be a value reading from Sim or a fake IMSI if in the test mode
- imsi = getIMSI();
-
- if (((mMncLength == UNINITIALIZED) || (mMncLength == UNKNOWN)
- || (mMncLength == 2)) && ((imsi != null)
- && (imsi.length() >= 6))) {
- String mccmncCode = imsi.substring(0, 6);
- log("mccmncCode=" + mccmncCode);
- for (String mccmnc : MCCMNC_CODES_HAVING_3DIGITS_MNC) {
- if (mccmnc.equals(mccmncCode)) {
- mMncLength = 3;
- log("setting6 mMncLength=" + mMncLength);
- break;
- }
- }
- }
-
- if (mMncLength == UNKNOWN || mMncLength == UNINITIALIZED) {
- if (imsi != null) {
- try {
- int mcc = Integer.parseInt(imsi.substring(0, 3));
-
- mMncLength = MccTable.smallestDigitsMccForMnc(mcc);
- log("setting7 mMncLength=" + mMncLength);
- } catch (NumberFormatException e) {
- mMncLength = UNKNOWN;
- loge("Corrupt IMSI! setting8 mMncLength=" + mMncLength);
- }
- } else {
- // Indicate we got this info, but it didn't contain the length.
- mMncLength = UNKNOWN;
- log("MNC length not present in EF_AD setting9 "
- + "mMncLength=" + mMncLength);
- }
- }
- if (imsi != null && mMncLength != UNKNOWN
- && imsi.length() >= 3 + mMncLength) {
- // finally have both imsi and the length of the mnc and can parse
- // the imsi properly
- log("update mccmnc=" + imsi.substring(0, 3 + mMncLength));
- MccTable.updateMccMncConfiguration(mContext,
- imsi.substring(0, 3 + mMncLength));
- }
+ updateOperatorPlmn();
}
break;
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
index b8b2818..636aa1c 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -660,9 +660,15 @@
.addChild(ctxParams1Builder)
.build().toHex());
}),
- (byte[] response) ->
- parseResponseAndCheckSimpleError(response,
- EuiccCardErrorException.OPERATION_AUTHENTICATE_SERVER).toBytes(),
+ (byte[] response) -> {
+ Asn1Node root = parseResponse(response);
+ if (root.hasChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2)) {
+ throw new EuiccCardErrorException(
+ EuiccCardErrorException.OPERATION_AUTHENTICATE_SERVER,
+ root.getChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2).asInteger());
+ }
+ return root.toBytes();
+ },
callback, handler);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
new file mode 100644
index 0000000..86c41c9
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2018 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.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.telephony.SubscriptionManager;
+import android.test.mock.MockContentProvider;
+import android.util.Log;
+
+public class FakeTelephonyProvider extends MockContentProvider {
+ static final String TAG = "FakeTelephonyProvider";
+
+ private InMemoryTelephonyProviderDbHelper mDbHelper =
+ new InMemoryTelephonyProviderDbHelper();
+
+ /**
+ * An in memory DB.
+ */
+ private class InMemoryTelephonyProviderDbHelper extends SQLiteOpenHelper {
+ InMemoryTelephonyProviderDbHelper() {
+ super(InstrumentationRegistry.getTargetContext(),
+ null, // db file name is null for in-memory db
+ null, // CursorFactory is null by default
+ 1); // db version is no-op for tests
+ Log.d(TAG, "InMemoryTelephonyProviderDbHelper creating in-memory database");
+ }
+
+ // This should always be consistent with TelephonyProvider#getStringForSimInfoTableCreation.
+ private String getStringForSimInfoTableCreation(String tableName) {
+ return "CREATE TABLE " + tableName + "("
+ + SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID
+ + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ + SubscriptionManager.ICC_ID + " TEXT NOT NULL,"
+ + SubscriptionManager.SIM_SLOT_INDEX
+ + " INTEGER DEFAULT " + SubscriptionManager.SIM_NOT_INSERTED + ","
+ + SubscriptionManager.DISPLAY_NAME + " TEXT,"
+ + SubscriptionManager.CARRIER_NAME + " TEXT,"
+ + SubscriptionManager.NAME_SOURCE
+ + " INTEGER DEFAULT " + SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE + ","
+ + SubscriptionManager.COLOR + " INTEGER DEFAULT "
+ + SubscriptionManager.COLOR_DEFAULT + ","
+ + SubscriptionManager.NUMBER + " TEXT,"
+ + SubscriptionManager.DISPLAY_NUMBER_FORMAT
+ + " INTEGER NOT NULL DEFAULT "
+ + SubscriptionManager.DISPLAY_NUMBER_DEFAULT + ","
+ + SubscriptionManager.DATA_ROAMING
+ + " INTEGER DEFAULT " + SubscriptionManager.DATA_ROAMING_DEFAULT + ","
+ + SubscriptionManager.MCC + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.MNC + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.MCC_STRING + " TEXT,"
+ + SubscriptionManager.MNC_STRING + " TEXT,"
+ + SubscriptionManager.SIM_PROVISIONING_STATUS
+ + " INTEGER DEFAULT " + SubscriptionManager.SIM_PROVISIONED + ","
+ + SubscriptionManager.IS_EMBEDDED + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.CARD_ID + " TEXT NOT NULL,"
+ + SubscriptionManager.ACCESS_RULES + " BLOB,"
+ + SubscriptionManager.IS_REMOVABLE + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.CB_EXTREME_THREAT_ALERT + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_SEVERE_THREAT_ALERT + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_AMBER_ALERT + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_EMERGENCY_ALERT + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_ALERT_SOUND_DURATION + " INTEGER DEFAULT 4,"
+ + SubscriptionManager.CB_ALERT_REMINDER_INTERVAL + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.CB_ALERT_VIBRATE + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_ALERT_SPEECH + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_ETWS_TEST_ALERT + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.CB_CHANNEL_50_ALERT + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.CB_CMAS_TEST_ALERT + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.CB_OPT_OUT_DIALOG + " INTEGER DEFAULT 1,"
+ + SubscriptionManager.ENHANCED_4G_MODE_ENABLED + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.VT_IMS_ENABLED + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.WFC_IMS_ENABLED + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.WFC_IMS_MODE + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.WFC_IMS_ROAMING_MODE + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.WFC_IMS_ROAMING_ENABLED + " INTEGER DEFAULT -1,"
+ + SubscriptionManager.IS_OPPORTUNISTIC + " INTEGER DEFAULT 0,"
+ + SubscriptionManager.PARENT_SUB_ID + " INTEGER DEFAULT -1"
+ + ");";
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ // TODO: set up other tables when needed.
+ // set up the siminfo table
+ Log.d(TAG, "InMemoryTelephonyProviderDbHelper onCreate creating the siminfo table");
+ db.execSQL(getStringForSimInfoTableCreation("siminfo"));
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.d(TAG, "InMemoryTelephonyProviderDbHelper onUpgrade doing nothing");
+ return;
+ }
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ SQLiteDatabase db = mDbHelper.getWritableDatabase();
+ long id = db.insert("siminfo", null, values);
+ return ContentUris.withAppendedId(SubscriptionManager.CONTENT_URI, id);
+ }
+
+ @Override
+ public synchronized int delete(Uri url, String where, String[] whereArgs) {
+ return mDbHelper.getWritableDatabase().delete("siminfo", where, whereArgs);
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return mDbHelper.getReadableDatabase().query("siminfo", projection, selection,
+ selectionArgs, null, null, sortOrder);
+ }
+
+ @Override
+ public Bundle call(String method, String request, Bundle args) {
+ return null;
+ }
+
+ @Override
+ public final int update(Uri uri, ContentValues values, String where,
+ String[] selectionArgs) {
+ return mDbHelper.getWritableDatabase().update("siminfo", values, where, selectionArgs);
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
index 6e6854b..76ead95 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
@@ -26,7 +26,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.os.HandlerThread;
+import android.os.Looper;
import android.telephony.SmsMessage;
import android.telephony.ims.stub.ImsSmsImplBase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -44,33 +44,19 @@
@Mock private SMSDispatcher.SmsTracker mSmsTracker;
private HashMap<String, Object> mTrackerData;
private ImsSmsDispatcher mImsSmsDispatcher;
- private ImsSmsDispatcherTestHandler mImsSmsDispatcherTestHandler;
-
-
- private class ImsSmsDispatcherTestHandler extends HandlerThread {
-
- private ImsSmsDispatcherTestHandler(String name) {
- super(name);
- }
-
- @Override
- public void onLooperPrepared() {
- mImsSmsDispatcher = spy(new ImsSmsDispatcher(mPhone, mSmsDispatchersController));
- when(mSmsDispatchersController.isIms()).thenReturn(true);
- setReady(true);
- }
- }
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
- mImsSmsDispatcherTestHandler = new ImsSmsDispatcherTestHandler(TAG);
- mImsSmsDispatcherTestHandler.start();
+ mImsSmsDispatcher = spy(new ImsSmsDispatcher(mPhone, mSmsDispatchersController));
+ when(mSmsDispatchersController.isIms()).thenReturn(true);
- mTrackerData = new HashMap(1);
+ mTrackerData = new HashMap<>(1);
when(mSmsTracker.getData()).thenReturn(mTrackerData);
- waitUntilReady();
}
/**
@@ -93,7 +79,6 @@
assertEquals(token + 1, mImsSmsDispatcher.mNextToken.get());
assertEquals(trackersSize + 1, mImsSmsDispatcher.mTrackers.size());
- ArgumentCaptor<byte[]> byteCaptor = ArgumentCaptor.forClass(byte[].class);
verify(mImsManager).sendSms(eq(token + 1), anyInt(), eq(SmsMessage.FORMAT_3GPP),
nullable(String.class), eq(false), eq(pdu));
}
@@ -155,8 +140,6 @@
@After
public void tearDown() throws Exception {
mImsSmsDispatcher = null;
- mImsSmsDispatcherTestHandler.quit();
- mImsSmsDispatcherTestHandler.join();
super.tearDown();
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 606ed21..489a19f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -15,24 +15,26 @@
*/
package com.android.internal.telephony;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
-import android.app.AppOpsManager;
-import android.content.ContentValues;
import android.content.Intent;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
import org.junit.After;
import org.junit.Before;
@@ -40,117 +42,15 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import java.util.ArrayList;
import java.util.List;
public class SubscriptionControllerTest extends TelephonyTest {
-
private static final int SINGLE_SIM = 1;
private String mCallingPackage;
private SubscriptionController mSubscriptionControllerUT;
private MockContentResolver mMockContentResolver;
-
- @Mock private List<SubscriptionInfo> mSubList;
- @Mock private AppOpsManager mAppOps;
-
- public class FakeSubscriptionContentProvider extends MockContentProvider {
-
- private ArrayList<ContentValues> mSubscriptionArray =
- new ArrayList<ContentValues>();
-
- private String[] mKeyMappingSet = new String[]{
- SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
- SubscriptionManager.ICC_ID, SubscriptionManager.SIM_SLOT_INDEX,
- SubscriptionManager.DISPLAY_NAME, SubscriptionManager.CARRIER_NAME,
- SubscriptionManager.NAME_SOURCE, SubscriptionManager.COLOR,
- SubscriptionManager.NUMBER, SubscriptionManager.DISPLAY_NUMBER_FORMAT,
- SubscriptionManager.DATA_ROAMING, SubscriptionManager.MCC,
- SubscriptionManager.MNC, SubscriptionManager.MCC_STRING,
- SubscriptionManager.MNC_STRING,
- SubscriptionManager.CB_EXTREME_THREAT_ALERT,
- SubscriptionManager.CB_SEVERE_THREAT_ALERT, SubscriptionManager.CB_AMBER_ALERT,
- SubscriptionManager.CB_ALERT_SOUND_DURATION,
- SubscriptionManager.CB_ALERT_REMINDER_INTERVAL,
- SubscriptionManager.CB_ALERT_VIBRATE, SubscriptionManager.CB_ALERT_SPEECH,
- SubscriptionManager.CB_ETWS_TEST_ALERT, SubscriptionManager.CB_CHANNEL_50_ALERT,
- SubscriptionManager.CB_CMAS_TEST_ALERT, SubscriptionManager.CB_OPT_OUT_DIALOG,
- SubscriptionManager.SIM_PROVISIONING_STATUS, SubscriptionManager.IS_EMBEDDED,
- SubscriptionManager.ACCESS_RULES, SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
- SubscriptionManager.VT_IMS_ENABLED, SubscriptionManager.WFC_IMS_ENABLED,
- SubscriptionManager.WFC_IMS_MODE, SubscriptionManager.WFC_IMS_ROAMING_MODE,
- SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
- SubscriptionManager.CARD_ID, SubscriptionManager.IS_OPPORTUNISTIC,
- SubscriptionManager.PARENT_SUB_ID
- };
-
- /* internal util function */
- private MatrixCursor convertFromContentToCursor(ContentValues initialValues,
- String[] projection) {
- MatrixCursor cursor = null;
- ArrayList<Object> values = new ArrayList<Object>();
- if (projection == null) {
- projection = mKeyMappingSet;
- }
- if (initialValues != null && projection.length != 0) {
- cursor = new MatrixCursor(projection);
- /* push value from contentValues to matrixCursors */
- for (String key : projection) {
- if (initialValues.containsKey(key)) {
- values.add(initialValues.get(key));
- } else {
- values.add(null);
- }
- }
- }
- cursor.addRow(values.toArray());
- return cursor;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- if (mSubscriptionArray.size() > 0) {
- mSubscriptionArray.remove(0);
- return 1;
- }
- return -1;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- values.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, 0);
- mSubscriptionArray.add(values);
- return uri;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- if (mSubscriptionArray.size() > 0) {
- return convertFromContentToCursor(mSubscriptionArray.get(0), projection);
- }
- return null;
- }
-
- @Override
- public Bundle call(String method, String request, Bundle args) {
- return null;
- }
-
- @Override
- public int update(android.net.Uri uri, android.content.ContentValues values,
- java.lang.String selection, java.lang.String[] selectionArgs) {
- if (mSubscriptionArray.size() > 0) {
- ContentValues val = mSubscriptionArray.get(0);
- for (String key : values.keySet()) {
- val.put(key, values.getAsString(key));
- Log.d(TAG, "update the values..." + key + "..." + values.getAsString(key));
- }
- mSubscriptionArray.set(0, val);
- return 1;
- }
- return -1;
- }
- }
+ @Mock
+ private ITelephonyRegistry.Stub mTelephonyRegisteryMock;
@Before
public void setUp() throws Exception {
@@ -171,7 +71,8 @@
mSubscriptionControllerUT.getInstance().updatePhonesAvailability(new Phone[]{mPhone});
mMockContentResolver = (MockContentResolver) mContext.getContentResolver();
mMockContentResolver.addProvider(SubscriptionManager.CONTENT_URI.getAuthority(),
- new FakeSubscriptionContentProvider());
+ new FakeTelephonyProvider());
+
}
@After
@@ -179,6 +80,10 @@
/* should clear fake content provider and resolver here */
mContext.getContentResolver().delete(SubscriptionManager.CONTENT_URI, null, null);
+ /*clear sub info in mSubscriptionControllerUT since they will otherwise be persistent
+ * between each test case. */
+ mSubscriptionControllerUT.clearSubInfo();
+
/* clear settings for default voice/data/sms sub ID */
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
@@ -196,11 +101,10 @@
@Test @SmallTest
public void testInsertSim() {
- int slotID = mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage);
-
//verify there is no sim inserted in the SubscriptionManager
- assertEquals(0, slotID);
+ assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+ int slotID = 0;
//insert one Subscription Info
mSubscriptionControllerUT.addSubInfoRecord("test", slotID);
@@ -286,11 +190,11 @@
@Test @SmallTest
public void testCleanUpSIM() {
testInsertSim();
- assertFalse(mSubscriptionControllerUT.isActiveSubId(1));
+ assertFalse(mSubscriptionControllerUT.isActiveSubId(2));
mSubscriptionControllerUT.clearSubInfo();
- assertFalse(mSubscriptionControllerUT.isActiveSubId(0));
+ assertFalse(mSubscriptionControllerUT.isActiveSubId(1));
assertEquals(SubscriptionManager.SIM_NOT_INSERTED,
- mSubscriptionControllerUT.getSlotIndex(0));
+ mSubscriptionControllerUT.getSlotIndex(1));
}
@Test @SmallTest
@@ -316,10 +220,10 @@
public void testSetGetMCCMNC() {
testInsertSim();
String mCcMncVERIZON = "310004";
- mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 0);
+ mSubscriptionControllerUT.setMccMnc(mCcMncVERIZON, 1);
SubscriptionInfo subInfo = mSubscriptionControllerUT
- .getActiveSubscriptionInfo(0, mCallingPackage);
+ .getActiveSubscriptionInfo(1, mCallingPackage);
assertNotNull(subInfo);
assertEquals(Integer.parseInt(mCcMncVERIZON.substring(0, 3)), subInfo.getMcc());
assertEquals(Integer.parseInt(mCcMncVERIZON.substring(3)), subInfo.getMnc());
@@ -429,4 +333,62 @@
SubscriptionManager.WFC_IMS_ROAMING_MODE,
mCallingPackage));
}
+
+
+ @Test
+ @SmallTest
+ public void testOpptSubInfoListChanged() throws Exception {
+ registerMockTelephonyRegistry();
+ verify(mTelephonyRegisteryMock, times(0))
+ .notifyOpportunisticSubscriptionInfoChanged();
+
+ testInsertSim();
+ testInsertSim2();
+
+ // Neither sub1 or sub2 are opportunistic. So getOpportunisticSubscriptions
+ // should return empty list and no callback triggered.
+ List<SubscriptionInfo> opptSubList = mSubscriptionControllerUT
+ .getOpportunisticSubscriptions(0, mCallingPackage);
+
+ assertTrue(opptSubList.isEmpty());
+ verify(mTelephonyRegisteryMock, times(0))
+ .notifyOpportunisticSubscriptionInfoChanged();
+
+ // Setting sub2 as opportunistic should trigger callback.
+ mSubscriptionControllerUT.setOpportunistic(true, 2);
+
+ verify(mTelephonyRegisteryMock, times(1))
+ .notifyOpportunisticSubscriptionInfoChanged();
+ opptSubList = mSubscriptionControllerUT
+ .getOpportunisticSubscriptions(0, mCallingPackage);
+ assertEquals(1, opptSubList.size());
+ assertEquals("test2", opptSubList.get(0).getIccId());
+
+ // Changing non-opportunistic sub1 shouldn't trigger callback.
+ mSubscriptionControllerUT.setDisplayName("DisplayName", 1);
+ verify(mTelephonyRegisteryMock, times(1))
+ .notifyOpportunisticSubscriptionInfoChanged();
+
+ mSubscriptionControllerUT.setDisplayName("DisplayName", 2);
+ verify(mTelephonyRegisteryMock, times(2))
+ .notifyOpportunisticSubscriptionInfoChanged();
+ }
+
+ private void testInsertSim2() {
+ // verify there's already a SIM profile added.
+ assertEquals(1, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+
+ int slotID = 0;
+ //insert one Subscription Info
+ mSubscriptionControllerUT.addSubInfoRecord("test2", slotID);
+
+ //verify there is one sim
+ assertEquals(2, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage));
+ }
+
+ private void registerMockTelephonyRegistry() {
+ mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock);
+ doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock)
+ .queryLocalInterface(anyString());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java
index 2498b78..86df4f5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoTest.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import android.telephony.SubscriptionInfo;
import android.test.suitebuilder.annotation.SmallTest;
@@ -78,4 +79,22 @@
mSubscriptionInfoUT.setIconTint(0);
assertEquals(0, mSubscriptionInfoUT.getIconTint());
}
+
+ @Test
+ @SmallTest
+ public void testEquals() {
+ SubscriptionInfo copiedInfo = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0,
+ "T-mobile", "T-mobile", 0, 255, "12345", 0, null,
+ "310", "260", "156", false, null, null);
+ SubscriptionInfo differentDisplayName = new SubscriptionInfo(1, "890126042XXXXXXXXXXX", 0,
+ "AT&T", "T-mobile", 0, 255, "12345", 0, null,
+ "310", "260", "156", false, null, null);
+ SubscriptionInfo differentSubId = new SubscriptionInfo(2, "890126042XXXXXXXXXXX", 0,
+ "AT&T", "T-mobile", 0, 255, "12345", 0, null,
+ "310", "260", "156", false, null, null);
+
+ assertEquals(mSubscriptionInfoUT, copiedInfo);
+ assertNotEquals(mSubscriptionInfoUT, differentDisplayName);
+ assertNotEquals(mSubscriptionInfoUT, differentSubId);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index ab26c56..6e4257e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -19,7 +19,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
@@ -35,7 +34,6 @@
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -165,8 +163,6 @@
@Mock
protected IActivityManager mIActivityManager;
@Mock
- protected InboundSmsTracker mInboundSmsTracker;
- @Mock
protected IIntentSender mIIntentSender;
@Mock
protected IBinder mIBinder;
@@ -350,16 +346,6 @@
.makeDcTracker(nullable(Phone.class));
doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory)
.makeWspTypeDecoder(nullable(byte[].class));
- doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
- .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
- anyBoolean(), nullable(String.class), nullable(String.class),
- nullable(String.class));
- doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
- .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
- nullable(String.class), nullable(String.class), anyInt(), anyInt(),
- anyInt(), anyBoolean(), nullable(String.class));
- doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
- .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
doReturn(mImsCT).when(mTelephonyComponentFactory)
.makeImsPhoneCallTracker(nullable(ImsPhone.class));
doReturn(mCdmaSSM).when(mTelephonyComponentFactory)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index 35d2bb0..08e54ac 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -21,6 +21,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
@@ -29,9 +31,9 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.database.Cursor;
import android.os.AsyncResult;
import android.os.HandlerThread;
import android.os.RemoteException;
@@ -44,10 +46,10 @@
import com.android.internal.telephony.FakeSmsContentProvider;
import com.android.internal.telephony.InboundSmsHandler;
+import com.android.internal.telephony.InboundSmsTracker;
import com.android.internal.telephony.SmsStorageMonitor;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.util.HexDump;
import com.android.internal.util.IState;
import com.android.internal.util.StateMachine;
@@ -72,8 +74,9 @@
private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
private CdmaInboundSmsHandlerTestHandler mCdmaInboundSmsHandlerTestHandler;
private SmsEnvelope mSmsEnvelope = new SmsEnvelope();
- private ContentValues mInboundSmsTrackerCV = new ContentValues();
private FakeSmsContentProvider mContentProvider;
+ private InboundSmsTracker mInboundSmsTracker;
+ private byte[] mSmsPdu = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
private class CdmaInboundSmsHandlerTestHandler extends HandlerThread {
@@ -118,28 +121,32 @@
fail("Unexpected RemoteException: " + re.getStackTrace());
}
- byte[] smsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
- doReturn(smsPdu).when(mCdmaSmsMessage).getPdu();
-
- mInboundSmsTrackerCV.put("destination_port", 1 << 16);
- mInboundSmsTrackerCV.put("pdu", HexDump.toHexString(smsPdu));
- mInboundSmsTrackerCV.put("address", "1234567890");
- mInboundSmsTrackerCV.put("reference_number", 1);
- mInboundSmsTrackerCV.put("sequence", 1);
- mInboundSmsTrackerCV.put("count", 1);
- mInboundSmsTrackerCV.put("date", System.currentTimeMillis());
- mInboundSmsTrackerCV.put("message_body", "This is the message body of a single-part " +
- "message");
+ doReturn(mSmsPdu).when(mCdmaSmsMessage).getPdu();
doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
- doReturn(1).when(mInboundSmsTracker).getMessageCount();
- doReturn(-1).when(mInboundSmsTracker).getDestPort();
- doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues();
- doReturn(smsPdu).when(mInboundSmsTracker).getPdu();
- doReturn("This is the message body").when(mInboundSmsTracker).getMessageBody();
- doReturn("1234567890").when(mInboundSmsTracker).getAddress();
+
+ mInboundSmsTracker = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ true, /* is3gpp2 */
+ false, /* is3gpp2WapPdu */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ "This is the message body of a single-part message" /* messageBody */);
+
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ anyBoolean(), nullable(String.class), nullable(String.class),
+ nullable(String.class));
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ nullable(String.class), nullable(String.class), anyInt(), anyInt(),
+ anyInt(), anyBoolean(), nullable(String.class));
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
mContentProvider = new FakeSmsContentProvider();
((MockContentResolver)mContext.getContentResolver()).addProvider(
@@ -214,7 +221,19 @@
@MediumTest
public void testNewSmsFromBlockedNumber_noBroadcastsSent() {
String blockedNumber = "123456789";
- doReturn(blockedNumber).when(mInboundSmsTracker).getDisplayAddress();
+ mInboundSmsTracker = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ true, /* is3gpp2 */
+ false, /* is3gpp2WapPdu */
+ "1234567890", /* address */
+ blockedNumber, /* displayAddress */
+ "This is the message body of a single-part message" /* messageBody */);
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ anyBoolean(), nullable(String.class), nullable(String.class),
+ nullable(String.class));
mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber);
transitionFromStartupToIdle();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 12453ed..851a217 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -64,7 +64,6 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
@@ -80,11 +79,13 @@
private SmsMessage mGsmSmsMessage;
@Mock
private SmsHeader mSmsHeader;
- @Mock
+ private InboundSmsTracker mInboundSmsTracker;
private InboundSmsTracker mInboundSmsTrackerPart1;
- @Mock
private InboundSmsTracker mInboundSmsTrackerPart2;
@Mock
+ private InboundSmsTracker mMockInboundSmsTracker;
+ private ContentValues mInboundSmsTrackerCV;
+ @Mock
private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
private GsmInboundSmsHandler mGsmInboundSmsHandler;
@@ -94,11 +95,8 @@
private static final String RAW_TABLE_NAME = "raw";
private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI,
RAW_TABLE_NAME);
+ private static final int TEST_TIMEOUT = 5000;
- private ContentValues mInboundSmsTrackerCV = new ContentValues();
- // For multi-part SMS
- private ContentValues mInboundSmsTrackerCVPart1;
- private ContentValues mInboundSmsTrackerCVPart2;
private String mMessageBody = "This is the message body of a single-part message";
private String mMessageBodyPart1 = "This is the first part of a multi-part message";
private String mMessageBodyPart2 = "This is the second part of a multi-part message";
@@ -130,6 +128,38 @@
}
}
+ /**
+ * This is used only for InboundSmsTracker constructed through Cursor. For other cases
+ * real objects should be used. This should be used only for tests related to
+ * SmsBroadcastUndelivered.
+ */
+ private void createMockInboundSmsTracker() {
+ mInboundSmsTrackerCV = new ContentValues();
+ mInboundSmsTrackerCV.put("destination_port", InboundSmsTracker.DEST_PORT_FLAG_NO_PORT);
+ mInboundSmsTrackerCV.put("pdu", HexDump.toHexString(mSmsPdu));
+ mInboundSmsTrackerCV.put("address", "1234567890");
+ mInboundSmsTrackerCV.put("reference_number", 1);
+ mInboundSmsTrackerCV.put("sequence", 1);
+ mInboundSmsTrackerCV.put("count", 1);
+ mInboundSmsTrackerCV.put("date", System.currentTimeMillis());
+ mInboundSmsTrackerCV.put("message_body", mMessageBody);
+ mInboundSmsTrackerCV.put("display_originating_addr", "1234567890");
+
+ doReturn(1).when(mMockInboundSmsTracker).getMessageCount();
+ doReturn(1).when(mMockInboundSmsTracker).getReferenceNumber();
+ doReturn("1234567890").when(mMockInboundSmsTracker).getAddress();
+ doReturn(1).when(mMockInboundSmsTracker).getSequenceNumber();
+ doReturn(1).when(mMockInboundSmsTracker).getIndexOffset();
+ doReturn(-1).when(mMockInboundSmsTracker).getDestPort();
+ doReturn(mMessageBody).when(mMockInboundSmsTracker).getMessageBody();
+ doReturn(mSmsPdu).when(mMockInboundSmsTracker).getPdu();
+ doReturn(mInboundSmsTrackerCV.get("date")).when(mMockInboundSmsTracker).getTimestamp();
+ doReturn(mInboundSmsTrackerCV).when(mMockInboundSmsTracker).getContentValues();
+
+ doReturn(mMockInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(Cursor.class), anyBoolean());
+ }
+
@Before
public void setUp() throws Exception {
super.setUp("GsmInboundSmsHandlerTest");
@@ -147,26 +177,22 @@
}
mSmsMessage.mWrappedSmsMessage = mGsmSmsMessage;
- mInboundSmsTrackerCV.put("destination_port", InboundSmsTracker.DEST_PORT_FLAG_NO_PORT);
- mInboundSmsTrackerCV.put("pdu", HexDump.toHexString(mSmsPdu));
- mInboundSmsTrackerCV.put("address", "1234567890");
- mInboundSmsTrackerCV.put("reference_number", 1);
- mInboundSmsTrackerCV.put("sequence", 1);
- mInboundSmsTrackerCV.put("count", 1);
- mInboundSmsTrackerCV.put("date", System.currentTimeMillis());
- mInboundSmsTrackerCV.put("message_body", mMessageBody);
- mInboundSmsTrackerCV.put("display_originating_addr", "1234567890");
- doReturn(1).when(mInboundSmsTracker).getMessageCount();
- doReturn(1).when(mInboundSmsTracker).getReferenceNumber();
- doReturn("1234567890").when(mInboundSmsTracker).getAddress();
- doReturn(1).when(mInboundSmsTracker).getSequenceNumber();
- doReturn(1).when(mInboundSmsTracker).getIndexOffset();
- doReturn(-1).when(mInboundSmsTracker).getDestPort();
- doReturn(mMessageBody).when(mInboundSmsTracker).getMessageBody();
- doReturn(mSmsPdu).when(mInboundSmsTracker).getPdu();
- doReturn(mInboundSmsTrackerCV.get("date")).when(mInboundSmsTracker).getTimestamp();
- doReturn(mInboundSmsTrackerCV).when(mInboundSmsTracker).getContentValues();
+ mInboundSmsTracker = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ false, /* is3gpp2 */
+ false, /* is3gpp2WapPdu */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ mMessageBody /* messageBody */);
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ anyBoolean(), nullable(String.class), nullable(String.class),
+ nullable(String.class));
+
+ createMockInboundSmsTracker();
mContentProvider = new FakeSmsContentProvider();
((MockContentResolver)mContext.getContentResolver()).addProvider(
@@ -189,6 +215,7 @@
mGsmInboundSmsHandler = null;
mContentProvider.shutdown();
mGsmInboundSmsHandlerTestHandler.quit();
+ mGsmInboundSmsHandlerTestHandler.join();
super.tearDown();
}
@@ -198,7 +225,7 @@
// trigger transition to IdleState
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_START_ACCEPTING_SMS);
- waitForMs(50);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
assertEquals("IdleState", getCurrentState().getName());
}
@@ -221,29 +248,37 @@
assertEquals("WaitingState", getCurrentState().getName());
mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
- waitForMs(50);
-
+ // handle broadcast complete msg
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ // transition from waiting state to delivering state
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ // transition from delivering state to idle state
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
assertEquals("IdleState", getCurrentState().getName());
}
+ private void sendNewSms() {
+ mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
+ new AsyncResult(null, mSmsMessage, null));
+ // handle EVENT_NEW_SMS
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ // handle EVENT_BROADCAST_SMS
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ }
+
@FlakyTest
- @Ignore
@Test
@MediumTest
public void testNewSms() {
transitionFromStartupToIdle();
// send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
- new AsyncResult(null, mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
verifySmsIntentBroadcasts(0);
// send same SMS again, verify no broadcasts are sent
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
- new AsyncResult(null, mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
@@ -253,14 +288,11 @@
@MediumTest
public void testNewSmsFromBlockedNumber_noBroadcastsSent() {
String blockedNumber = "1234567890";
- doReturn(blockedNumber).when(mInboundSmsTracker).getDisplayAddress();
mFakeBlockedNumberContentProvider.mBlockedNumbers.add(blockedNumber);
transitionFromStartupToIdle();
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
- new AsyncResult(null, mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
@@ -275,7 +307,12 @@
assertEquals("WaitingState", getCurrentState().getName());
mContextFixture.sendBroadcastToOrderedBroadcastReceivers();
- waitForMs(50);
+ // handle broadcast complete msg
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ // transition from waiting state to delivering state
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ // transition from delivering state to idle state
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
assertEquals("IdleState", getCurrentState().getName());
}
@@ -285,23 +322,36 @@
public void testBroadcastSms() {
transitionFromStartupToIdle();
- doReturn(0).when(mInboundSmsTracker).getDestPort();
+ mInboundSmsTracker = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ 0, /* destPort */
+ false, /* is3gpp2 */
+ false, /* is3gpp2WapPdu */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ mMessageBody /* messageBody */);
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ anyBoolean(), nullable(String.class), nullable(String.class),
+ nullable(String.class));
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS,
mInboundSmsTracker);
- waitForMs(100);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
verifyDataSmsIntentBroadcasts(0);
// send same data sms again, and since it's not text sms it should be broadcast again
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_SMS,
mInboundSmsTracker);
- waitForMs(100);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
verifyDataSmsIntentBroadcasts(1);
}
@FlakyTest
- @Ignore
@Test
@MediumTest
public void testInjectSms() {
@@ -309,121 +359,49 @@
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, new AsyncResult(null,
mSmsMessage, null));
- waitForMs(200);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
verifySmsIntentBroadcasts(0);
// inject same SMS again, verify no broadcasts are sent
mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_INJECT_SMS, new AsyncResult(null,
mSmsMessage, null));
- waitForMs(100);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
+ waitForHandlerAction(mGsmInboundSmsHandler.getHandler(), TEST_TIMEOUT);
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
}
- private void prepareMultiPartSms(boolean isWapPush) {
+ private void prepareMultiPartSms(boolean is3gpp2WapPush) {
// Part 1
- mInboundSmsTrackerCVPart1 = new ContentValues();
- mInboundSmsTrackerCVPart1.put("pdu", HexDump.toHexString(mSmsPdu));
- mInboundSmsTrackerCVPart1.put("address", "1234567890");
- mInboundSmsTrackerCVPart1.put("reference_number", 1);
- mInboundSmsTrackerCVPart1.put("sequence", 1);
- mInboundSmsTrackerCVPart1.put("count", 2);
- mInboundSmsTrackerCVPart1.put("date", System.currentTimeMillis());
- mInboundSmsTrackerCVPart1.put("message_body", mMessageBodyPart1);
- mInboundSmsTrackerCVPart1.put("display_originating_addr", "1234567890");
-
- doReturn(2).when(mInboundSmsTrackerPart1).getMessageCount();
- doReturn(1).when(mInboundSmsTrackerPart1).getReferenceNumber();
- doReturn("1234567890").when(mInboundSmsTrackerPart1).getAddress();
- doReturn(1).when(mInboundSmsTrackerPart1).getSequenceNumber();
- doReturn(1).when(mInboundSmsTrackerPart1).getIndexOffset();
- doReturn(-1).when(mInboundSmsTrackerPart1).getDestPort();
- doReturn(mMessageBodyPart1).when(mInboundSmsTrackerPart1).getMessageBody();
- doReturn(mSmsPdu).when(mInboundSmsTrackerPart1).getPdu();
- doReturn(new String[]{mInboundSmsTrackerPart1.getAddress(),
- Integer.toString(mInboundSmsTrackerPart1.getReferenceNumber()),
- Integer.toString(mInboundSmsTrackerPart1.getMessageCount())})
- .when(mInboundSmsTrackerPart1).getDeleteWhereArgs();
- doReturn(mInboundSmsTrackerCVPart1.get("date")).when(mInboundSmsTrackerPart1).
- getTimestamp();
- doReturn(mInboundSmsTrackerCVPart1).when(mInboundSmsTrackerPart1).getContentValues();
- if (isWapPush) {
- mInboundSmsTrackerCVPart1.put("destination_port",
- (InboundSmsTracker.DEST_PORT_FLAG_3GPP2 |
- InboundSmsTracker.DEST_PORT_FLAG_3GPP2_WAP_PDU |
- SmsHeader.PORT_WAP_PUSH));
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE_3GPP2WAP).when(mInboundSmsTrackerPart1)
- .getQueryForSegments();
- doReturn(InboundSmsTracker.SELECT_BY_DUPLICATE_REFERENCE_3GPP2WAP)
- .when(mInboundSmsTrackerPart1).getQueryForMultiPartDuplicates();
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE_3GPP2WAP).when(mInboundSmsTrackerPart1)
- .getDeleteWhere();
- doReturn(SmsHeader.PORT_WAP_PUSH).when(mInboundSmsTrackerPart1).getDestPort();
- doReturn(true).when(mInboundSmsTrackerPart1).is3gpp2();
-
- } else {
- mInboundSmsTrackerCVPart1.put("destination_port",
- InboundSmsTracker.DEST_PORT_FLAG_NO_PORT);
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE).when(mInboundSmsTrackerPart1)
- .getQueryForSegments();
- doReturn(InboundSmsTracker.SELECT_BY_DUPLICATE_REFERENCE)
- .when(mInboundSmsTrackerPart1).getQueryForMultiPartDuplicates();
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE).when(mInboundSmsTrackerPart1)
- .getDeleteWhere();
- }
+ mInboundSmsTrackerPart1 = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ is3gpp2WapPush, /* is3gpp2 */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ 1, /* referenceNumber */
+ 1, /* sequenceNumber */
+ 2, /* messageCount */
+ is3gpp2WapPush, /* is3gpp2WapPdu */
+ mMessageBodyPart1 /* messageBody */);
// Part 2
- mInboundSmsTrackerCVPart2 = new ContentValues();
- mInboundSmsTrackerCVPart2.put("pdu", HexDump.toHexString(mSmsPdu));
- mInboundSmsTrackerCVPart2.put("address", "1234567890");
- mInboundSmsTrackerCVPart2.put("reference_number", 1);
- mInboundSmsTrackerCVPart2.put("sequence", 2);
- mInboundSmsTrackerCVPart2.put("count", 2);
- mInboundSmsTrackerCVPart2.put("date", System.currentTimeMillis());
- mInboundSmsTrackerCVPart2.put("message_body", mMessageBodyPart2);
- mInboundSmsTrackerCVPart2.put("display_originating_addr", "1234567890");
-
- doReturn(2).when(mInboundSmsTrackerPart2).getMessageCount();
- doReturn(1).when(mInboundSmsTrackerPart2).getReferenceNumber();
- doReturn("1234567890").when(mInboundSmsTrackerPart2).getAddress();
- doReturn(2).when(mInboundSmsTrackerPart2).getSequenceNumber();
- doReturn(1).when(mInboundSmsTrackerPart2).getIndexOffset();
- doReturn(-1).when(mInboundSmsTrackerPart2).getDestPort();
- doReturn(mMessageBodyPart2).when(mInboundSmsTrackerPart2).getMessageBody();
- doReturn(mSmsPdu).when(mInboundSmsTrackerPart2).getPdu();
- doReturn(new String[]{mInboundSmsTrackerPart2.getAddress(),
- Integer.toString(mInboundSmsTrackerPart2.getReferenceNumber()),
- Integer.toString(mInboundSmsTrackerPart2.getMessageCount())})
- .when(mInboundSmsTrackerPart2).getDeleteWhereArgs();
- doReturn(mInboundSmsTrackerCVPart2.get("date")).when(mInboundSmsTrackerPart2).
- getTimestamp();
- doReturn(mInboundSmsTrackerCVPart2).when(mInboundSmsTrackerPart2).getContentValues();
- if (isWapPush) {
- mInboundSmsTrackerCVPart2.put("destination_port",
- (InboundSmsTracker.DEST_PORT_FLAG_3GPP2 |
- InboundSmsTracker.DEST_PORT_FLAG_3GPP2_WAP_PDU |
- SmsHeader.PORT_WAP_PUSH));
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE_3GPP2WAP).when(mInboundSmsTrackerPart2)
- .getQueryForSegments();
- doReturn(InboundSmsTracker.SELECT_BY_DUPLICATE_REFERENCE_3GPP2WAP)
- .when(mInboundSmsTrackerPart2).getQueryForMultiPartDuplicates();
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE_3GPP2WAP).when(mInboundSmsTrackerPart2)
- .getDeleteWhere();
- doReturn(SmsHeader.PORT_WAP_PUSH).when(mInboundSmsTrackerPart2).getDestPort();
- doReturn(true).when(mInboundSmsTrackerPart2).is3gpp2();
-
- } else {
- mInboundSmsTrackerCVPart2.put("destination_port",
- InboundSmsTracker.DEST_PORT_FLAG_NO_PORT);
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE).when(mInboundSmsTrackerPart2)
- .getQueryForSegments();
- doReturn(InboundSmsTracker.SELECT_BY_DUPLICATE_REFERENCE)
- .when(mInboundSmsTrackerPart2).getQueryForMultiPartDuplicates();
- doReturn(InboundSmsTracker.SELECT_BY_REFERENCE).when(mInboundSmsTrackerPart2)
- .getDeleteWhere();
- }
+ mInboundSmsTrackerPart2 = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ is3gpp2WapPush, /* is3gpp2 */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ 1, /* referenceNumber */
+ 2, /* sequenceNumber */
+ 2, /* messageCount */
+ is3gpp2WapPush, /* is3gpp2WapPdu */
+ mMessageBodyPart2 /* messageBody */);
}
@Test
@@ -447,9 +425,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(200);
+ sendNewSms();
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -460,9 +436,8 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(200);
+ sendNewSms();
+
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -475,9 +450,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(200);
+ sendNewSms();
// verify broadcast intents
verifySmsIntentBroadcasts(0);
@@ -488,7 +461,6 @@
}
@FlakyTest
- @Ignore
@Test
@MediumTest
public void testMultiPartSms() {
@@ -504,9 +476,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -515,9 +485,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify broadcast intents
verifySmsIntentBroadcasts(0);
@@ -531,9 +499,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify no additional broadcasts sent
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
@@ -549,9 +515,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify no additional broadcasts sent
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
@@ -571,8 +535,18 @@
// prepare SMS part 1 and part 2
prepareMultiPartSms(false);
// change seqNumber in part 2 to 1
- mInboundSmsTrackerCVPart2.put("sequence", 1);
- doReturn(1).when(mInboundSmsTrackerPart2).getSequenceNumber();
+ mInboundSmsTrackerPart2 = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ false, /* is3gpp2 */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ 1, /* referenceNumber */
+ 1, /* sequenceNumber */
+ 2, /* messageCount */
+ false, /* is3gpp2WapPdu */
+ mMessageBodyPart2 /* messageBody */);
mSmsHeader.concatRef = new SmsHeader.ConcatRef();
doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
@@ -581,9 +555,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -592,9 +564,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify no broadcasts sent
verify(mContext, never()).sendBroadcast(any(Intent.class));
@@ -619,9 +589,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify the message is stored in the raw table
assertEquals(1, mContentProvider.getNumRows());
@@ -631,16 +599,24 @@
// change seqNumber in part 2 to an invalid value
int invalidSeqNumber = -1;
- mInboundSmsTrackerCVPart2.put("sequence", invalidSeqNumber);
- doReturn(invalidSeqNumber).when(mInboundSmsTrackerPart2).getSequenceNumber();
+ mInboundSmsTrackerPart2 = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ false, /* is3gpp2 */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ 1, /* referenceNumber */
+ invalidSeqNumber, /* sequenceNumber */
+ 2, /* messageCount */
+ false, /* is3gpp2WapPdu */
+ mMessageBodyPart2 /* messageBody */);
doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// verify no broadcasts sent
verify(mContext, never()).sendBroadcast(any(Intent.class));
@@ -665,9 +641,7 @@
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -676,9 +650,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
@@ -694,7 +666,18 @@
// prepare SMS part 1 and part 2
prepareMultiPartSms(false);
// only the first SMS is configured with the display originating email address
- mInboundSmsTrackerCVPart1.put("display_originating_addr", "1234567890@test.com");
+ mInboundSmsTrackerPart1 = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ -1, /* destPort */
+ false, /* is3gpp2 */
+ "1234567890", /* address */
+ "1234567890@test.com", /* displayAddress */
+ 1, /* referenceNumber */
+ 1, /* sequenceNumber */
+ 2, /* messageCount */
+ false, /* is3gpp2WapPdu */
+ mMessageBodyPart1 /* messageBody */);
mSmsHeader.concatRef = new SmsHeader.ConcatRef();
doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
@@ -703,9 +686,7 @@
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
// State machine should go back to idle and wait for second part
assertEquals("IdleState", getCurrentState().getName());
@@ -714,9 +695,7 @@
.makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
nullable(String.class), nullable(String.class), anyInt(), anyInt(),
anyInt(), anyBoolean(), nullable(String.class));
- mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, new AsyncResult(null,
- mSmsMessage, null));
- waitForMs(100);
+ sendNewSms();
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
@@ -726,13 +705,10 @@
@MediumTest
public void testBroadcastUndeliveredUserLocked() throws Exception {
replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null);
- doReturn(0).when(mInboundSmsTracker).getDestPort();
+ doReturn(0).when(mMockInboundSmsTracker).getDestPort();
// add a fake entry to db
- mContentProvider.insert(sRawUri, mInboundSmsTrackerCV);
-
- // make it a single-part message
- doReturn(1).when(mInboundSmsTracker).getMessageCount();
+ mContentProvider.insert(sRawUri, mMockInboundSmsTracker.getContentValues());
// user locked
UserManager userManager = (UserManager)mContext.getSystemService(Context.USER_SERVICE);
@@ -745,6 +721,7 @@
verify(mContext).registerReceiverAsUser(any(BroadcastReceiver.class), eq((UserHandle)null),
any(IntentFilter.class), eq((String)null), eq((Handler)null));
+ // wait for ScanRawTableThread
waitForMs(100);
// verify no broadcasts sent because due to !isUserUnlocked
@@ -753,6 +730,7 @@
// when user unlocks the device, the message in db should be broadcast
doReturn(true).when(userManager).isUserUnlocked();
mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED));
+ // wait for ScanRawTableThread
waitForMs(100);
verifyDataSmsIntentBroadcasts(1);
@@ -762,15 +740,14 @@
@MediumTest
public void testBroadcastUndeliveredUserUnlocked() throws Exception {
replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null);
- doReturn(0).when(mInboundSmsTracker).getDestPort();
+ doReturn(0).when(mMockInboundSmsTracker).getDestPort();
// add a fake entry to db
- mContentProvider.insert(sRawUri, mInboundSmsTrackerCV);
-
- // make it a single-part message
- doReturn(1).when(mInboundSmsTracker).getMessageCount();
+ mContentProvider.insert(sRawUri, mMockInboundSmsTracker.getContentValues());
SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+
+ // wait for ScanRawTableThread
waitForMs(100);
// user is unlocked; intent should be broadcast right away
@@ -782,18 +759,28 @@
public void testBroadcastUndeliveredDeleted() throws Exception {
replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null);
SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
- doReturn(0).when(mInboundSmsTracker).getDestPort();
+ mInboundSmsTracker = new InboundSmsTracker(
+ mSmsPdu, /* pdu */
+ System.currentTimeMillis(), /* timestamp */
+ 0, /* destPort */
+ false, /* is3gpp2 */
+ false, /* is3gpp2WapPdu */
+ "1234567890", /* address */
+ "1234567890", /* displayAddress */
+ mMessageBody /* messageBody */);
+ doReturn(mInboundSmsTracker).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(nullable(byte[].class), anyLong(), anyInt(), anyBoolean(),
+ anyBoolean(), nullable(String.class), nullable(String.class),
+ nullable(String.class));
//add a fake entry to db
ContentValues rawSms = new ContentValues();
rawSms.put("deleted", 1);
mContentProvider.insert(sRawUri, rawSms);
- //make it a single-part message
- doReturn(1).when(mInboundSmsTracker).getMessageCount();
-
//when user unlocks the device, broadcast should not be sent for new message
mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED));
+ // wait for ScanRawTableThread
waitForMs(100);
verify(mContext, times(1)).sendBroadcast(any(Intent.class));
@@ -802,7 +789,6 @@
}
@FlakyTest
- @Ignore
@Test
@MediumTest
public void testBroadcastUndeliveredMultiPart() throws Exception {
@@ -812,8 +798,8 @@
prepareMultiPartSms(false);
//add the 2 SMS parts to db
- mContentProvider.insert(sRawUri, mInboundSmsTrackerCVPart1);
- mContentProvider.insert(sRawUri, mInboundSmsTrackerCVPart2);
+ mContentProvider.insert(sRawUri, mInboundSmsTrackerPart1.getContentValues());
+ mContentProvider.insert(sRawUri, mInboundSmsTrackerPart2.getContentValues());
//return InboundSmsTracker objects corresponding to the 2 parts
doReturn(mInboundSmsTrackerPart1).doReturn(mInboundSmsTrackerPart2).
@@ -821,7 +807,8 @@
anyBoolean());
SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
- waitForMs(100);
+ // wait for ScanRawTableThread
+ waitForMs(200);
verifySmsIntentBroadcasts(0);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
index 5c847cd..b38b5e8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
@@ -29,7 +29,7 @@
package com.android.internal.telephony.uicc;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
import android.os.HandlerThread;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
index a3d7245..6f488a8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
@@ -564,7 +564,7 @@
com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
.thenReturn(new String[] {});
- int channel = mockLogicalChannelResponses("BF38038101039000");
+ int channel = mockLogicalChannelResponses("BF3805A1030201039000");
ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id