Loading src/java/com/android/internal/telephony/CarrierResolver.java +104 −54 Original line number Diff line number Diff line Loading @@ -60,10 +60,9 @@ public class CarrierResolver extends Handler { // events to trigger carrier identification private static final int SIM_LOAD_EVENT = 1; private static final int SIM_ABSENT_EVENT = 2; private static final int ICC_CHANGED_EVENT = 3; private static final int PREFER_APN_UPDATE_EVENT = 4; private static final int CARRIER_ID_DB_UPDATE_EVENT = 5; private static final int ICC_CHANGED_EVENT = 2; private static final int PREFER_APN_UPDATE_EVENT = 3; private static final int CARRIER_ID_DB_UPDATE_EVENT = 4; private static final Uri CONTENT_URL_PREFER_APN = Uri.withAppendedPath( Telephony.Carriers.CONTENT_URI, "preferapn"); Loading Loading @@ -93,8 +92,6 @@ public class CarrierResolver extends Handler { private IccRecords mIccRecords; private final LocalLog mCarrierIdLocalLog = new LocalLog(20); private final TelephonyManager mTelephonyMgr; private final SubscriptionsChangedListener mOnSubscriptionsChangedListener = new SubscriptionsChangedListener(); private final ContentObserver mContentObserver = new ContentObserver(this) { @Override Loading @@ -109,31 +106,6 @@ public class CarrierResolver extends Handler { } }; private class SubscriptionsChangedListener extends SubscriptionManager.OnSubscriptionsChangedListener { final AtomicInteger mPreviousSubId = new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID); /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList} */ @Override public void onSubscriptionsChanged() { int subId = mPhone.getSubId(); if (mPreviousSubId.getAndSet(subId) != subId) { if (DBG) { logd("SubscriptionListener.onSubscriptionInfoChanged subId: " + mPreviousSubId); } if (SubscriptionManager.isValidSubscriptionId(subId)) { sendEmptyMessage(SIM_LOAD_EVENT); } else { sendEmptyMessage(SIM_ABSENT_EVENT); } } } } public CarrierResolver(Phone phone) { logd("Creating CarrierResolver[" + phone.getPhoneId() + "]"); mContext = phone.getContext(); Loading @@ -145,11 +117,60 @@ public class CarrierResolver extends Handler { mContentObserver); mContext.getContentResolver().registerContentObserver( CarrierId.All.CONTENT_URI, false, mContentObserver); SubscriptionManager.from(mContext).addOnSubscriptionsChangedListener( mOnSubscriptionsChangedListener); UiccController.getInstance().registerForIccChanged(this, ICC_CHANGED_EVENT, null); } /** * This is triggered from SubscriptionInfoUpdater after sim state change. * The sequence of sim loading would be * 1. ACTION_SUBINFO_CONTENT_CHANGE * 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED * /ACTION_SIM_APPLICATION_STATE_CHANGED * 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED * * For SIM refresh either reset or file update, SubscriptionInfoUpdater will re-trigger * carrier identification with sim loaded state. */ public void resolveSubscriptionCarrierId(String simState) { logd("[resolveSubscriptionCarrierId] simState: " + simState); switch (simState) { case IccCardConstants.INTENT_VALUE_ICC_ABSENT: // only clear carrier id on absent to avoid transition to unknown carrier id during // intermediate states of sim refresh handleSimAbsent(); break; case IccCardConstants.INTENT_VALUE_ICC_LOCKED: // intentional fall through from above case, treat locked same as loaded case IccCardConstants.INTENT_VALUE_ICC_LOADED: handleSimLoaded(); break; } } private void handleSimLoaded() { if (mIccRecords != null) { /** * returns empty string to be consistent with * {@link TelephonyManager#getSimOperatorName()} */ mSpn = (mIccRecords.getServiceProviderName() == null) ? "" : mIccRecords.getServiceProviderName(); } else { loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN"); } mPreferApn = getPreferApn(); loadCarrierMatchingRulesOnMccMnc(); } private void handleSimAbsent() { mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } /** * Entry point for the carrier identification. * Loading @@ -174,23 +195,11 @@ public class CarrierResolver extends Handler { if (DBG) logd("handleMessage: " + msg.what); switch (msg.what) { case SIM_LOAD_EVENT: if (mIccRecords != null) { mSpn = mIccRecords.getServiceProviderName(); } else { loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN"); } mPreferApn = getPreferApn(); handleSimLoaded(); break; case CARRIER_ID_DB_UPDATE_EVENT: loadCarrierMatchingRulesOnMccMnc(); break; case SIM_ABSENT_EVENT: mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); break; case PREFER_APN_UPDATE_EVENT: String preferApn = getPreferApn(); if (!equals(mPreferApn, preferApn, true)) { Loading @@ -200,7 +209,7 @@ public class CarrierResolver extends Handler { } break; case ICC_CHANGED_EVENT: // all records used for carrier identification are from SimRecord // all records used for carrier identification are from SimRecord. final IccRecords newIccRecords = UiccController.getInstance().getIccRecords( mPhone.getPhoneId(), UiccController.APP_FAM_3GPP); if (mIccRecords != newIccRecords) { Loading Loading @@ -540,18 +549,14 @@ public class CarrierResolver extends Handler { mScore += SCORE_ICCID_PREFIX; } if (mGid1 != null) { // full string match. carrier matching should cover the corner case that gid1 // with garbage tail due to SIM manufacture issues. if (!CarrierResolver.equals(subscriptionRule.mGid1, mGid1, true)) { if (!gidMatch(subscriptionRule.mGid1, mGid1)) { mScore = SCORE_INVALID; return; } mScore += SCORE_GID1; } if (mGid2 != null) { // full string match. carrier matching should cover the corner case that gid2 // with garbage tail due to SIM manufacture issues. if (!CarrierResolver.equals(subscriptionRule.mGid2, mGid2, true)) { if (!gidMatch(subscriptionRule.mGid2, mGid2)) { mScore = SCORE_INVALID; return; } Loading Loading @@ -612,6 +617,13 @@ public class CarrierResolver extends Handler { return iccid.startsWith(prefix); } // We are doing prefix and case insensitive match. // Ideally we should do full string match. However due to SIM manufacture issues // gid from some SIM might has garbage tail. private boolean gidMatch(String gidFromSim, String gid) { return (gidFromSim != null) && gidFromSim.toLowerCase().startsWith(gid.toLowerCase()); } private boolean carrierPrivilegeRulesMatch(List<String> certsFromSubscription, List<String> certs) { if (certsFromSubscription == null || certsFromSubscription.isEmpty()) { Loading Loading @@ -890,6 +902,44 @@ public class CarrierResolver extends Handler { return ids; } // static helper function to get carrier id from mccmnc public static int getCarrierIdFromMccMnc(@NonNull Context context, String mccmnc) { try { Cursor cursor = context.getContentResolver().query( CarrierId.All.CONTENT_URI, /* projection */ null, /* selection */ CarrierId.All.MCCMNC + "=? AND " + CarrierId.All.GID1 + " is NULL AND " + CarrierId.All.GID2 + " is NULL AND " + CarrierId.All.IMSI_PREFIX_XPATTERN + " is NULL AND " + CarrierId.All.SPN + " is NULL AND " + CarrierId.All.ICCID_PREFIX + " is NULL AND " + CarrierId.All.PLMN + " is NULL AND " + CarrierId.All.PRIVILEGE_ACCESS_RULE + " is NULL AND " + CarrierId.All.APN + " is NULL", /* selectionArgs */ new String[]{mccmnc}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } while (cursor.moveToNext()) { return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } } } finally { if (cursor != null) { cursor.close(); } } } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); } return TelephonyManager.UNKNOWN_CARRIER_ID; } private static boolean equals(String a, String b, boolean ignoreCase) { if (a == null && b == null) return true; if (a != null && b != null) { Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +13 −8 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ public class GsmCdmaPhone extends Phone { private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; // Used for identify the carrier of current subscription private CarrierResolver mCarrerResolver; private CarrierResolver mCarrierResolver; private int mPrecisePhoneType; Loading Loading @@ -228,7 +228,7 @@ public class GsmCdmaPhone extends Phone { mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi); // DcTracker uses SST so needs to be created after it is instantiated mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mCarrerResolver = mTelephonyComponentFactory.makeCarrierResolver(this); mCarrierResolver = mTelephonyComponentFactory.makeCarrierResolver(this); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this); Loading Loading @@ -1566,32 +1566,37 @@ public class GsmCdmaPhone extends Phone { @Override public int getCarrierId() { return mCarrerResolver.getCarrierId(); return mCarrierResolver.getCarrierId(); } @Override public String getCarrierName() { return mCarrerResolver.getCarrierName(); return mCarrierResolver.getCarrierName(); } @Override public int getMNOCarrierId() { return mCarrerResolver.getMnoCarrierId(); return mCarrierResolver.getMnoCarrierId(); } @Override public int getPreciseCarrierId() { return mCarrerResolver.getPreciseCarrierId(); return mCarrierResolver.getPreciseCarrierId(); } @Override public String getPreciseCarrierName() { return mCarrerResolver.getPreciseCarrierName(); return mCarrierResolver.getPreciseCarrierName(); } @Override public void resolveSubscriptionCarrierId(String simState) { mCarrierResolver.resolveSubscriptionCarrierId(simState); } @Override public int getCarrierIdListVersion() { return mCarrerResolver.getCarrierListVersion(); return mCarrierResolver.getCarrierListVersion(); } @Override Loading src/java/com/android/internal/telephony/Phone.java +3 −0 Original line number Diff line number Diff line Loading @@ -3129,6 +3129,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; } public void resolveSubscriptionCarrierId(String simState) { } /** * Resets the Carrier Keys in the database. This involves 2 steps: * 1. Delete the keys from the database. Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +26 −5 Original line number Diff line number Diff line Loading @@ -243,10 +243,11 @@ public class SubscriptionInfoUpdater extends Handler { break; case EVENT_SIM_UNKNOWN: updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null); broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN); broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN); updateSubscriptionCarrierId(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); break; case EVENT_SIM_IO_ERROR: Loading @@ -254,12 +255,14 @@ public class SubscriptionInfoUpdater extends Handler { break; case EVENT_SIM_RESTRICTED: updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_CARD_RESTRICTED); broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); break; case EVENT_SIM_READY: Loading Loading @@ -333,10 +336,11 @@ public class SubscriptionInfoUpdater extends Handler { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimApplicationStateChanged(slotId, getSimStateFromLockedReason(reason)); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); } private static int getSimStateFromLockedReason(String lockedReason) { Loading Loading @@ -467,9 +471,18 @@ public class SubscriptionInfoUpdater extends Handler { mPackageManager, TelephonyManager.getDefault(), mContext.getContentResolver(), mCurrentlyActiveUserId); /** * The sim loading sequence will be * 1. ACTION_SUBINFO_CONTENT_CHANGE happens through updateSubscriptionInfoByIccId() above. * 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED * /ACTION_SIM_APPLICATION_STATE_CHANGED * 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED * 4. ACTION_CARRIER_CONFIG_CHANGED */ broadcastSimStateChanged(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null); broadcastSimCardStateChanged(loadedSlotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimApplicationStateChanged(loadedSlotId, TelephonyManager.SIM_STATE_LOADED); updateSubscriptionCarrierId(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED); updateCarrierServices(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED); } Loading @@ -480,6 +493,12 @@ public class SubscriptionInfoUpdater extends Handler { mCarrierServiceBindHelper.updateForPhoneId(slotId, simState); } private void updateSubscriptionCarrierId(int slotId, String simState) { if (mPhone != null && mPhone[slotId] != null) { mPhone[slotId].resolveSubscriptionCarrierId(simState); } } private void handleSimAbsent(int slotId) { if (mIccId[slotId] != null && !mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) { logd("SIM" + (slotId + 1) + " hot plug out"); Loading @@ -488,10 +507,11 @@ public class SubscriptionInfoUpdater extends Handler { if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); } private void handleSimError(int slotId) { Loading @@ -502,11 +522,12 @@ public class SubscriptionInfoUpdater extends Handler { if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); } /** Loading tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java +3 −4 Original line number Diff line number Diff line Loading @@ -83,9 +83,8 @@ public class CarrierResolverTest extends TelephonyTest { // events to trigger carrier identification private static final int SIM_LOAD_EVENT = 1; private static final int SIM_ABSENT_EVENT = 2; private static final int ICC_CHANGED_EVENT = 3; private static final int PREFER_APN_SET_EVENT = 4; private static final int ICC_CHANGED_EVENT = 2; private static final int PREFER_APN_SET_EVENT = 3; private CarrierResolver mCarrierResolver; private CarrierResolverHandler mCarrierCarrierResolverHandler; Loading Loading @@ -220,7 +219,7 @@ public class CarrierResolverTest extends TelephonyTest { assertEquals(CID_VZW, mCarrierResolver.getCarrierId()); assertEquals(NAME, mCarrierResolver.getCarrierName()); // trigger sim absent event mCarrierResolver.sendEmptyMessage(SIM_ABSENT_EVENT); mCarrierResolver.resolveSubscriptionCarrierId(IccCardConstants.INTENT_VALUE_ICC_ABSENT); waitForMs(200); assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId()); assertNull(mCarrierResolver.getCarrierName()); Loading Loading
src/java/com/android/internal/telephony/CarrierResolver.java +104 −54 Original line number Diff line number Diff line Loading @@ -60,10 +60,9 @@ public class CarrierResolver extends Handler { // events to trigger carrier identification private static final int SIM_LOAD_EVENT = 1; private static final int SIM_ABSENT_EVENT = 2; private static final int ICC_CHANGED_EVENT = 3; private static final int PREFER_APN_UPDATE_EVENT = 4; private static final int CARRIER_ID_DB_UPDATE_EVENT = 5; private static final int ICC_CHANGED_EVENT = 2; private static final int PREFER_APN_UPDATE_EVENT = 3; private static final int CARRIER_ID_DB_UPDATE_EVENT = 4; private static final Uri CONTENT_URL_PREFER_APN = Uri.withAppendedPath( Telephony.Carriers.CONTENT_URI, "preferapn"); Loading Loading @@ -93,8 +92,6 @@ public class CarrierResolver extends Handler { private IccRecords mIccRecords; private final LocalLog mCarrierIdLocalLog = new LocalLog(20); private final TelephonyManager mTelephonyMgr; private final SubscriptionsChangedListener mOnSubscriptionsChangedListener = new SubscriptionsChangedListener(); private final ContentObserver mContentObserver = new ContentObserver(this) { @Override Loading @@ -109,31 +106,6 @@ public class CarrierResolver extends Handler { } }; private class SubscriptionsChangedListener extends SubscriptionManager.OnSubscriptionsChangedListener { final AtomicInteger mPreviousSubId = new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID); /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList} */ @Override public void onSubscriptionsChanged() { int subId = mPhone.getSubId(); if (mPreviousSubId.getAndSet(subId) != subId) { if (DBG) { logd("SubscriptionListener.onSubscriptionInfoChanged subId: " + mPreviousSubId); } if (SubscriptionManager.isValidSubscriptionId(subId)) { sendEmptyMessage(SIM_LOAD_EVENT); } else { sendEmptyMessage(SIM_ABSENT_EVENT); } } } } public CarrierResolver(Phone phone) { logd("Creating CarrierResolver[" + phone.getPhoneId() + "]"); mContext = phone.getContext(); Loading @@ -145,11 +117,60 @@ public class CarrierResolver extends Handler { mContentObserver); mContext.getContentResolver().registerContentObserver( CarrierId.All.CONTENT_URI, false, mContentObserver); SubscriptionManager.from(mContext).addOnSubscriptionsChangedListener( mOnSubscriptionsChangedListener); UiccController.getInstance().registerForIccChanged(this, ICC_CHANGED_EVENT, null); } /** * This is triggered from SubscriptionInfoUpdater after sim state change. * The sequence of sim loading would be * 1. ACTION_SUBINFO_CONTENT_CHANGE * 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED * /ACTION_SIM_APPLICATION_STATE_CHANGED * 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED * * For SIM refresh either reset or file update, SubscriptionInfoUpdater will re-trigger * carrier identification with sim loaded state. */ public void resolveSubscriptionCarrierId(String simState) { logd("[resolveSubscriptionCarrierId] simState: " + simState); switch (simState) { case IccCardConstants.INTENT_VALUE_ICC_ABSENT: // only clear carrier id on absent to avoid transition to unknown carrier id during // intermediate states of sim refresh handleSimAbsent(); break; case IccCardConstants.INTENT_VALUE_ICC_LOCKED: // intentional fall through from above case, treat locked same as loaded case IccCardConstants.INTENT_VALUE_ICC_LOADED: handleSimLoaded(); break; } } private void handleSimLoaded() { if (mIccRecords != null) { /** * returns empty string to be consistent with * {@link TelephonyManager#getSimOperatorName()} */ mSpn = (mIccRecords.getServiceProviderName() == null) ? "" : mIccRecords.getServiceProviderName(); } else { loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN"); } mPreferApn = getPreferApn(); loadCarrierMatchingRulesOnMccMnc(); } private void handleSimAbsent() { mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } /** * Entry point for the carrier identification. * Loading @@ -174,23 +195,11 @@ public class CarrierResolver extends Handler { if (DBG) logd("handleMessage: " + msg.what); switch (msg.what) { case SIM_LOAD_EVENT: if (mIccRecords != null) { mSpn = mIccRecords.getServiceProviderName(); } else { loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN"); } mPreferApn = getPreferApn(); handleSimLoaded(); break; case CARRIER_ID_DB_UPDATE_EVENT: loadCarrierMatchingRulesOnMccMnc(); break; case SIM_ABSENT_EVENT: mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); break; case PREFER_APN_UPDATE_EVENT: String preferApn = getPreferApn(); if (!equals(mPreferApn, preferApn, true)) { Loading @@ -200,7 +209,7 @@ public class CarrierResolver extends Handler { } break; case ICC_CHANGED_EVENT: // all records used for carrier identification are from SimRecord // all records used for carrier identification are from SimRecord. final IccRecords newIccRecords = UiccController.getInstance().getIccRecords( mPhone.getPhoneId(), UiccController.APP_FAM_3GPP); if (mIccRecords != newIccRecords) { Loading Loading @@ -540,18 +549,14 @@ public class CarrierResolver extends Handler { mScore += SCORE_ICCID_PREFIX; } if (mGid1 != null) { // full string match. carrier matching should cover the corner case that gid1 // with garbage tail due to SIM manufacture issues. if (!CarrierResolver.equals(subscriptionRule.mGid1, mGid1, true)) { if (!gidMatch(subscriptionRule.mGid1, mGid1)) { mScore = SCORE_INVALID; return; } mScore += SCORE_GID1; } if (mGid2 != null) { // full string match. carrier matching should cover the corner case that gid2 // with garbage tail due to SIM manufacture issues. if (!CarrierResolver.equals(subscriptionRule.mGid2, mGid2, true)) { if (!gidMatch(subscriptionRule.mGid2, mGid2)) { mScore = SCORE_INVALID; return; } Loading Loading @@ -612,6 +617,13 @@ public class CarrierResolver extends Handler { return iccid.startsWith(prefix); } // We are doing prefix and case insensitive match. // Ideally we should do full string match. However due to SIM manufacture issues // gid from some SIM might has garbage tail. private boolean gidMatch(String gidFromSim, String gid) { return (gidFromSim != null) && gidFromSim.toLowerCase().startsWith(gid.toLowerCase()); } private boolean carrierPrivilegeRulesMatch(List<String> certsFromSubscription, List<String> certs) { if (certsFromSubscription == null || certsFromSubscription.isEmpty()) { Loading Loading @@ -890,6 +902,44 @@ public class CarrierResolver extends Handler { return ids; } // static helper function to get carrier id from mccmnc public static int getCarrierIdFromMccMnc(@NonNull Context context, String mccmnc) { try { Cursor cursor = context.getContentResolver().query( CarrierId.All.CONTENT_URI, /* projection */ null, /* selection */ CarrierId.All.MCCMNC + "=? AND " + CarrierId.All.GID1 + " is NULL AND " + CarrierId.All.GID2 + " is NULL AND " + CarrierId.All.IMSI_PREFIX_XPATTERN + " is NULL AND " + CarrierId.All.SPN + " is NULL AND " + CarrierId.All.ICCID_PREFIX + " is NULL AND " + CarrierId.All.PLMN + " is NULL AND " + CarrierId.All.PRIVILEGE_ACCESS_RULE + " is NULL AND " + CarrierId.All.APN + " is NULL", /* selectionArgs */ new String[]{mccmnc}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierIdFromMccMnc]- " + cursor.getCount() + " Records(s) in DB" + " mccmnc: " + mccmnc); } while (cursor.moveToNext()) { return cursor.getInt(cursor.getColumnIndex(CarrierId.CARRIER_ID)); } } } finally { if (cursor != null) { cursor.close(); } } } catch (Exception ex) { loge("[getCarrierIdFromMccMnc]- ex: " + ex); } return TelephonyManager.UNKNOWN_CARRIER_ID; } private static boolean equals(String a, String b, boolean ignoreCase) { if (a == null && b == null) return true; if (a != null && b != null) { Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +13 −8 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ public class GsmCdmaPhone extends Phone { private ArrayList <MmiCode> mPendingMMIs = new ArrayList<MmiCode>(); private IccPhoneBookInterfaceManager mIccPhoneBookIntManager; // Used for identify the carrier of current subscription private CarrierResolver mCarrerResolver; private CarrierResolver mCarrierResolver; private int mPrecisePhoneType; Loading Loading @@ -228,7 +228,7 @@ public class GsmCdmaPhone extends Phone { mSST = mTelephonyComponentFactory.makeServiceStateTracker(this, this.mCi); // DcTracker uses SST so needs to be created after it is instantiated mDcTracker = mTelephonyComponentFactory.makeDcTracker(this); mCarrerResolver = mTelephonyComponentFactory.makeCarrierResolver(this); mCarrierResolver = mTelephonyComponentFactory.makeCarrierResolver(this); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mDeviceStateMonitor = mTelephonyComponentFactory.makeDeviceStateMonitor(this); Loading Loading @@ -1566,32 +1566,37 @@ public class GsmCdmaPhone extends Phone { @Override public int getCarrierId() { return mCarrerResolver.getCarrierId(); return mCarrierResolver.getCarrierId(); } @Override public String getCarrierName() { return mCarrerResolver.getCarrierName(); return mCarrierResolver.getCarrierName(); } @Override public int getMNOCarrierId() { return mCarrerResolver.getMnoCarrierId(); return mCarrierResolver.getMnoCarrierId(); } @Override public int getPreciseCarrierId() { return mCarrerResolver.getPreciseCarrierId(); return mCarrierResolver.getPreciseCarrierId(); } @Override public String getPreciseCarrierName() { return mCarrerResolver.getPreciseCarrierName(); return mCarrierResolver.getPreciseCarrierName(); } @Override public void resolveSubscriptionCarrierId(String simState) { mCarrierResolver.resolveSubscriptionCarrierId(simState); } @Override public int getCarrierIdListVersion() { return mCarrerResolver.getCarrierListVersion(); return mCarrierResolver.getCarrierListVersion(); } @Override Loading
src/java/com/android/internal/telephony/Phone.java +3 −0 Original line number Diff line number Diff line Loading @@ -3129,6 +3129,9 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; } public void resolveSubscriptionCarrierId(String simState) { } /** * Resets the Carrier Keys in the database. This involves 2 steps: * 1. Delete the keys from the database. Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +26 −5 Original line number Diff line number Diff line Loading @@ -243,10 +243,11 @@ public class SubscriptionInfoUpdater extends Handler { break; case EVENT_SIM_UNKNOWN: updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null); broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN); broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_UNKNOWN); updateSubscriptionCarrierId(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_UNKNOWN); break; case EVENT_SIM_IO_ERROR: Loading @@ -254,12 +255,14 @@ public class SubscriptionInfoUpdater extends Handler { break; case EVENT_SIM_RESTRICTED: updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); broadcastSimStateChanged(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); broadcastSimCardStateChanged(msg.arg1, TelephonyManager.SIM_STATE_CARD_RESTRICTED); broadcastSimApplicationStateChanged(msg.arg1, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); updateCarrierServices(msg.arg1, IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED); break; case EVENT_SIM_READY: Loading Loading @@ -333,10 +336,11 @@ public class SubscriptionInfoUpdater extends Handler { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimApplicationStateChanged(slotId, getSimStateFromLockedReason(reason)); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED); } private static int getSimStateFromLockedReason(String lockedReason) { Loading Loading @@ -467,9 +471,18 @@ public class SubscriptionInfoUpdater extends Handler { mPackageManager, TelephonyManager.getDefault(), mContext.getContentResolver(), mCurrentlyActiveUserId); /** * The sim loading sequence will be * 1. ACTION_SUBINFO_CONTENT_CHANGE happens through updateSubscriptionInfoByIccId() above. * 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED * /ACTION_SIM_APPLICATION_STATE_CHANGED * 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED * 4. ACTION_CARRIER_CONFIG_CHANGED */ broadcastSimStateChanged(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null); broadcastSimCardStateChanged(loadedSlotId, TelephonyManager.SIM_STATE_PRESENT); broadcastSimApplicationStateChanged(loadedSlotId, TelephonyManager.SIM_STATE_LOADED); updateSubscriptionCarrierId(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED); updateCarrierServices(loadedSlotId, IccCardConstants.INTENT_VALUE_ICC_LOADED); } Loading @@ -480,6 +493,12 @@ public class SubscriptionInfoUpdater extends Handler { mCarrierServiceBindHelper.updateForPhoneId(slotId, simState); } private void updateSubscriptionCarrierId(int slotId, String simState) { if (mPhone != null && mPhone[slotId] != null) { mPhone[slotId].resolveSubscriptionCarrierId(simState); } } private void handleSimAbsent(int slotId) { if (mIccId[slotId] != null && !mIccId[slotId].equals(ICCID_STRING_FOR_NO_SIM)) { logd("SIM" + (slotId + 1) + " hot plug out"); Loading @@ -488,10 +507,11 @@ public class SubscriptionInfoUpdater extends Handler { if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT); } private void handleSimError(int slotId) { Loading @@ -502,11 +522,12 @@ public class SubscriptionInfoUpdater extends Handler { if (isAllIccIdQueryDone()) { updateSubscriptionInfoByIccId(); } updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR); broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY); updateSubscriptionCarrierId(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR); } /** Loading
tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java +3 −4 Original line number Diff line number Diff line Loading @@ -83,9 +83,8 @@ public class CarrierResolverTest extends TelephonyTest { // events to trigger carrier identification private static final int SIM_LOAD_EVENT = 1; private static final int SIM_ABSENT_EVENT = 2; private static final int ICC_CHANGED_EVENT = 3; private static final int PREFER_APN_SET_EVENT = 4; private static final int ICC_CHANGED_EVENT = 2; private static final int PREFER_APN_SET_EVENT = 3; private CarrierResolver mCarrierResolver; private CarrierResolverHandler mCarrierCarrierResolverHandler; Loading Loading @@ -220,7 +219,7 @@ public class CarrierResolverTest extends TelephonyTest { assertEquals(CID_VZW, mCarrierResolver.getCarrierId()); assertEquals(NAME, mCarrierResolver.getCarrierName()); // trigger sim absent event mCarrierResolver.sendEmptyMessage(SIM_ABSENT_EVENT); mCarrierResolver.resolveSubscriptionCarrierId(IccCardConstants.INTENT_VALUE_ICC_ABSENT); waitForMs(200); assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId()); assertNull(mCarrierResolver.getCarrierName()); Loading