Loading proto/src/carrierId.proto +5 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,11 @@ message CarrierId { // [Optional] Carrier attributes to match a carrier. At least one value is required. // [Optional] Carrier attributes to match a carrier. At least one value is required. repeated CarrierAttribute carrier_attribute = 3; repeated CarrierAttribute carrier_attribute = 3; // [Optional] A unique canonical number to represent its parent carrier. The parent-child // relationship can be used to differentiate a single carrier by different networks, // by prepaid v.s. postpaid or even by 4G v.s. 3G plan. optional int32 parent_canonical_id = 4; }; }; // Attributes used to match a carrier. // Attributes used to match a carrier. Loading src/java/com/android/internal/telephony/CarrierResolver.java +153 −25 Original line number Original line Diff line number Diff line Loading @@ -72,12 +72,15 @@ public class CarrierResolver extends Handler { private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>(); private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>(); // cached carrier Id // cached carrier Id private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached precise carrier Id private int mPreciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to // the cid. // the cid. private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached carrier name // cached carrier name private String mCarrierName; private String mCarrierName; private String mPreciseCarrierName; // cached preferapn name // cached preferapn name private String mPreferApn; private String mPreferApn; // cached service provider name. telephonyManager API returns empty string as default value. // cached service provider name. telephonyManager API returns empty string as default value. Loading Loading @@ -184,8 +187,9 @@ public class CarrierResolver extends Handler { mCarrierMatchingRulesOnMccMnc.clear(); mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mSpn = null; mPreferApn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); break; break; case PREFER_APN_UPDATE_EVENT: case PREFER_APN_UPDATE_EVENT: String preferApn = getPreferApn(); String preferApn = getPreferApn(); Loading Loading @@ -250,6 +254,34 @@ public class CarrierResolver extends Handler { } } } } private String getCarrierNameFromId(int cid) { try { Cursor cursor = mContext.getContentResolver().query( CarrierId.All.CONTENT_URI, /* projection */ null, /* selection */ CarrierId.CARRIER_ID + "=?", /* selectionArgs */ new String[]{cid + ""}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierNameFromId]- " + cursor.getCount() + " Records(s) in DB" + " cid: " + cid); } while (cursor.moveToNext()) { return cursor.getString(cursor.getColumnIndex(CarrierId.CARRIER_NAME)); } } } finally { if (cursor != null) { cursor.close(); } } } catch (Exception ex) { loge("[getCarrierNameFromId]- ex: " + ex); } return null; } private static List<CarrierMatchingRule> getCarrierMatchingRulesFromMccMnc( private static List<CarrierMatchingRule> getCarrierMatchingRulesFromMccMnc( @NonNull Context context, String mccmnc) { @NonNull Context context, String mccmnc) { List<CarrierMatchingRule> rules = new ArrayList<>(); List<CarrierMatchingRule> rules = new ArrayList<>(); Loading Loading @@ -308,7 +340,9 @@ public class CarrierResolver extends Handler { return null; return null; } } private void updateCarrierIdAndName(int cid, int mnoCid, String name) { private void updateCarrierIdAndName(int cid, String name, int preciseCarrierId, String preciseCarrierName, int mnoCid) { boolean update = false; boolean update = false; if (!equals(name, mCarrierName, true)) { if (!equals(name, mCarrierName, true)) { logd("[updateCarrierName] from:" + mCarrierName + " to:" + name); logd("[updateCarrierName] from:" + mCarrierName + " to:" + name); Loading @@ -325,7 +359,6 @@ public class CarrierResolver extends Handler { mMnoCarrierId = mnoCid; mMnoCarrierId = mnoCid; update = true; update = true; } } if (update) { if (update) { mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:" mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:" + mCarrierName + " mnoCid:" + mMnoCarrierId); + mCarrierName + " mnoCid:" + mMnoCarrierId); Loading @@ -337,7 +370,7 @@ public class CarrierResolver extends Handler { intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); mContext.sendBroadcast(intent); mContext.sendBroadcast(intent); // update current subscriptions // notify content observers for carrier id change event ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues(); cv.put(CarrierId.CARRIER_ID, mCarrierId); cv.put(CarrierId.CARRIER_ID, mCarrierId); cv.put(CarrierId.CARRIER_NAME, mCarrierName); cv.put(CarrierId.CARRIER_NAME, mCarrierName); Loading @@ -346,6 +379,38 @@ public class CarrierResolver extends Handler { Uri.withAppendedPath(CarrierId.CONTENT_URI, Uri.withAppendedPath(CarrierId.CONTENT_URI, Integer.toString(mPhone.getSubId())), cv, null, null); Integer.toString(mPhone.getSubId())), cv, null, null); } } update = false; if (preciseCarrierId != mPreciseCarrierId) { logd("[updatePreciseCarrierId] from:" + mPreciseCarrierId + " to:" + preciseCarrierId); mPreciseCarrierId = preciseCarrierId; update = true; } if (preciseCarrierName != mPreciseCarrierName) { logd("[updatePreciseCarrierName] from:" + mPreciseCarrierName + " to:" + preciseCarrierName); mPreciseCarrierName = preciseCarrierName; update = true; } if (update) { mCarrierIdLocalLog.log("[updatePreciseCarrierIdAndName] cid:" + mPreciseCarrierId + " name:" + mPreciseCarrierName); final Intent intent = new Intent(TelephonyManager .ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED); intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_ID, mPreciseCarrierId); intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_NAME, mPreciseCarrierName); intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); mContext.sendBroadcast(intent); // notify content observers for precise carrier id change event. ContentValues cv = new ContentValues(); cv.put(CarrierId.PRECISE_CARRIER_ID, mPreciseCarrierId); cv.put(CarrierId.PRECISE_CARRIER_ID_NAME, mPreciseCarrierName); mContext.getContentResolver().update( Telephony.CarrierId.getPreciseCarrierIdUriForSubscriptionId(mPhone.getSubId()), cv, null, null); } } } private static CarrierMatchingRule makeCarrierMatchingRule(Cursor cursor) { private static CarrierMatchingRule makeCarrierMatchingRule(Cursor cursor) { Loading @@ -364,7 +429,8 @@ public class CarrierResolver extends Handler { cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)), cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)), (TextUtils.isEmpty(certs) ? null : new ArrayList<>(Arrays.asList(certs))), (TextUtils.isEmpty(certs) ? null : new ArrayList<>(Arrays.asList(certs))), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)), cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME))); cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME)), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.PARENT_CARRIER_ID))); } } /** /** Loading Loading @@ -408,12 +474,14 @@ public class CarrierResolver extends Handler { private String mName; private String mName; // unique carrier id // unique carrier id private int mCid; private int mCid; // unique parent carrier id private int mParentCid; private int mScore = 0; private int mScore = 0; CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix, private CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix, String gid1, String gid2, String plmn, String spn, String apn, String gid1, String gid2, String plmn, String spn, String apn, List<String> privilegeAccessRule, int cid, String name) { List<String> privilegeAccessRule, int cid, String name, int parentCid) { mMccMnc = mccmnc; mMccMnc = mccmnc; mImsiPrefixPattern = imsiPrefixPattern; mImsiPrefixPattern = imsiPrefixPattern; mIccidPrefix = iccidPrefix; mIccidPrefix = iccidPrefix; Loading @@ -425,6 +493,22 @@ public class CarrierResolver extends Handler { mPrivilegeAccessRule = privilegeAccessRule; mPrivilegeAccessRule = privilegeAccessRule; mCid = cid; mCid = cid; mName = name; mName = name; mParentCid = parentCid; } private CarrierMatchingRule(CarrierMatchingRule rule) { mMccMnc = rule.mMccMnc; mImsiPrefixPattern = rule.mImsiPrefixPattern; mIccidPrefix = rule.mIccidPrefix; mGid1 = rule.mGid1; mGid2 = rule.mGid2; mPlmn = rule.mPlmn; mSpn = rule.mSpn; mApn = rule.mApn; mPrivilegeAccessRule = rule.mPrivilegeAccessRule; mCid = rule.mCid; mName = rule.mName; mParentCid = rule.mParentCid; } } // Calculate matching score. Values which aren't set in the rule are considered "wild". // Calculate matching score. Values which aren't set in the rule are considered "wild". Loading Loading @@ -586,21 +670,25 @@ public class CarrierResolver extends Handler { } } return new CarrierMatchingRule( return new CarrierMatchingRule( mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, accessRules, mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, accessRules, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } } /** /** * find the best matching carrier from candidates with matched subscription MCCMNC. * find the best matching carrier from candidates with matched subscription MCCMNC. * @return the best matching carrier id. */ */ private int matchSubscriptionCarrier() { private void matchSubscriptionCarrier() { int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { logd("[matchSubscriptionCarrier]" + "skip before sim records loaded"); logd("[matchSubscriptionCarrier]" + "skip before sim records loaded"); return carrierId; return; } } int maxScore = CarrierMatchingRule.SCORE_INVALID; int maxScore = CarrierMatchingRule.SCORE_INVALID; /** * For child-parent relationship. either child and parent have the same matching * score, or child's matching score > parents' matching score. */ CarrierMatchingRule maxRule = null; CarrierMatchingRule maxRule = null; CarrierMatchingRule maxRuleParent = null; /** /** * matching rule with mccmnc only. If mnoRule is found, then mno carrier id equals to the * matching rule with mccmnc only. If mnoRule is found, then mno carrier id equals to the * cid from mnoRule. otherwise, mno carrier id is same as cid. * cid from mnoRule. otherwise, mno carrier id is same as cid. Loading @@ -613,7 +701,15 @@ public class CarrierResolver extends Handler { if (rule.mScore > maxScore) { if (rule.mScore > maxScore) { maxScore = rule.mScore; maxScore = rule.mScore; maxRule = rule; maxRule = rule; carrierId = rule.mCid; maxRuleParent = rule; } else if (maxScore > CarrierMatchingRule.SCORE_INVALID && rule.mScore == maxScore) { // to handle the case that child parent has the same matching score, we need to // differentiate who is child who is parent. if (rule.mParentCid == maxRule.mCid) { maxRule = rule; } else if (maxRule.mParentCid == rule.mCid) { maxRuleParent = rule; } } } if (rule.mScore == CarrierMatchingRule.SCORE_MCCMNC) { if (rule.mScore == CarrierMatchingRule.SCORE_MCCMNC) { mnoRule = rule; mnoRule = rule; Loading @@ -622,12 +718,23 @@ public class CarrierResolver extends Handler { if (maxScore == CarrierMatchingRule.SCORE_INVALID) { if (maxScore == CarrierMatchingRule.SCORE_INVALID) { logd("[matchSubscriptionCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID logd("[matchSubscriptionCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID + " name: " + null); + " name: " + null); updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } else { } else { logd("[matchSubscriptionCarrier] cid: " + maxRule.mCid + " name: " + maxRule.mName); // if there is a single matching result, check if this rule has parent cid assigned. updateCarrierIdAndName(maxRule.mCid, if ((maxRule == maxRuleParent) (mnoRule == null) ? maxRule.mCid : mnoRule.mCid, maxRule.mName); && maxRule.mParentCid != TelephonyManager.UNKNOWN_CARRIER_ID) { maxRuleParent = new CarrierMatchingRule(maxRule); maxRuleParent.mCid = maxRuleParent.mParentCid; maxRuleParent.mName = getCarrierNameFromId(maxRuleParent.mCid); } logd("[matchSubscriptionCarrier] precise cid: " + maxRule.mCid + " precise name: " + maxRule.mName +" cid: " + maxRuleParent.mCid + " name: " + maxRuleParent.mName); updateCarrierIdAndName(maxRuleParent.mCid, maxRuleParent.mName, maxRule.mCid, maxRule.mName, (mnoRule == null) ? maxRule.mCid : mnoRule.mCid); } } /* /* Loading @@ -648,7 +755,6 @@ public class CarrierResolver extends Handler { TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent( TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent( mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId, mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId, unknownMccmncToLog, unknownGid1ToLog); unknownMccmncToLog, unknownGid1ToLog); return carrierId; } } public int getCarrierListVersion() { public int getCarrierListVersion() { Loading @@ -662,15 +768,33 @@ public class CarrierResolver extends Handler { public int getCarrierId() { public int getCarrierId() { return mCarrierId; return mCarrierId; } } /** public int getMnoCarrierId() { * Returns fine-grained carrier id of the current subscription. Carrier ids with a valid parent return mMnoCarrierId; * id are precise carrier ids. * The precise carrier id can be used to further differentiate a carrier by different * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique * carrier id but can have multiple precise carrier id. e.g, * {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while * {@link #getPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the * current underlying network. * For carriers without any fine-grained carrier ids, return {@link #getCarrierId()} */ public int getPreciseCarrierId() { return mPreciseCarrierId; } } public String getCarrierName() { public String getCarrierName() { return mCarrierName; return mCarrierName; } } public String getPreciseCarrierName() { return mPreciseCarrierName; } public int getMnoCarrierId() { return mMnoCarrierId; } /** /** * a util function to convert carrierIdentifier to the best matching carrier id. * a util function to convert carrierIdentifier to the best matching carrier id. * * Loading @@ -694,7 +818,9 @@ public class CarrierResolver extends Handler { // assign null to other fields which are not supported by carrierIdentifier. // assign null to other fields which are not supported by carrierIdentifier. CarrierMatchingRule targetRule = CarrierMatchingRule targetRule = new CarrierMatchingRule(mccmnc, imsi, null, gid1, gid2, null, new CarrierMatchingRule(mccmnc, imsi, null, gid1, gid2, null, spn, null, null, -1, null); spn, null, null, TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION, null, TelephonyManager.UNKNOWN_CARRIER_ID); int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; int maxScore = CarrierMatchingRule.SCORE_INVALID; int maxScore = CarrierMatchingRule.SCORE_INVALID; Loading Loading @@ -786,8 +912,10 @@ public class CarrierResolver extends Handler { ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.println("mCarrierId: " + mCarrierId); ipw.println("mCarrierId: " + mCarrierId); ipw.println("mPreciseCarrierId: " + mPreciseCarrierId); ipw.println("mMnoCarrierId: " + mMnoCarrierId); ipw.println("mMnoCarrierId: " + mMnoCarrierId); ipw.println("mCarrierName: " + mCarrierName); ipw.println("mCarrierName: " + mCarrierName); ipw.println("mPreciseCarrierName: " + mPreciseCarrierName); ipw.println("version: " + getCarrierListVersion()); ipw.println("version: " + getCarrierListVersion()); ipw.println("mCarrierMatchingRules on mccmnc: " ipw.println("mCarrierMatchingRules on mccmnc: " Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1579,6 +1579,16 @@ public class GsmCdmaPhone extends Phone { return mCarrerResolver.getMnoCarrierId(); return mCarrerResolver.getMnoCarrierId(); } } @Override public int getPreciseCarrierId() { return mCarrerResolver.getPreciseCarrierId(); } @Override public String getPreciseCarrierName() { return mCarrerResolver.getPreciseCarrierName(); } @Override @Override public int getCarrierIdListVersion() { public int getCarrierIdListVersion() { return mCarrerResolver.getCarrierListVersion(); return mCarrerResolver.getCarrierListVersion(); Loading src/java/com/android/internal/telephony/Phone.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -3117,6 +3117,14 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return TelephonyManager.UNKNOWN_CARRIER_ID; return TelephonyManager.UNKNOWN_CARRIER_ID; } } public int getPreciseCarrierId() { return TelephonyManager.UNKNOWN_CARRIER_ID; } public String getPreciseCarrierName() { return null; } public int getCarrierIdListVersion() { public int getCarrierIdListVersion() { return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; } } Loading tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java +189 −11 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
proto/src/carrierId.proto +5 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,11 @@ message CarrierId { // [Optional] Carrier attributes to match a carrier. At least one value is required. // [Optional] Carrier attributes to match a carrier. At least one value is required. repeated CarrierAttribute carrier_attribute = 3; repeated CarrierAttribute carrier_attribute = 3; // [Optional] A unique canonical number to represent its parent carrier. The parent-child // relationship can be used to differentiate a single carrier by different networks, // by prepaid v.s. postpaid or even by 4G v.s. 3G plan. optional int32 parent_canonical_id = 4; }; }; // Attributes used to match a carrier. // Attributes used to match a carrier. Loading
src/java/com/android/internal/telephony/CarrierResolver.java +153 −25 Original line number Original line Diff line number Diff line Loading @@ -72,12 +72,15 @@ public class CarrierResolver extends Handler { private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>(); private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>(); // cached carrier Id // cached carrier Id private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached precise carrier Id private int mPreciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely // cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to // identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to // the cid. // the cid. private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; // cached carrier name // cached carrier name private String mCarrierName; private String mCarrierName; private String mPreciseCarrierName; // cached preferapn name // cached preferapn name private String mPreferApn; private String mPreferApn; // cached service provider name. telephonyManager API returns empty string as default value. // cached service provider name. telephonyManager API returns empty string as default value. Loading Loading @@ -184,8 +187,9 @@ public class CarrierResolver extends Handler { mCarrierMatchingRulesOnMccMnc.clear(); mCarrierMatchingRulesOnMccMnc.clear(); mSpn = null; mSpn = null; mPreferApn = null; mPreferApn = null; updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); break; break; case PREFER_APN_UPDATE_EVENT: case PREFER_APN_UPDATE_EVENT: String preferApn = getPreferApn(); String preferApn = getPreferApn(); Loading Loading @@ -250,6 +254,34 @@ public class CarrierResolver extends Handler { } } } } private String getCarrierNameFromId(int cid) { try { Cursor cursor = mContext.getContentResolver().query( CarrierId.All.CONTENT_URI, /* projection */ null, /* selection */ CarrierId.CARRIER_ID + "=?", /* selectionArgs */ new String[]{cid + ""}, null); try { if (cursor != null) { if (VDBG) { logd("[getCarrierNameFromId]- " + cursor.getCount() + " Records(s) in DB" + " cid: " + cid); } while (cursor.moveToNext()) { return cursor.getString(cursor.getColumnIndex(CarrierId.CARRIER_NAME)); } } } finally { if (cursor != null) { cursor.close(); } } } catch (Exception ex) { loge("[getCarrierNameFromId]- ex: " + ex); } return null; } private static List<CarrierMatchingRule> getCarrierMatchingRulesFromMccMnc( private static List<CarrierMatchingRule> getCarrierMatchingRulesFromMccMnc( @NonNull Context context, String mccmnc) { @NonNull Context context, String mccmnc) { List<CarrierMatchingRule> rules = new ArrayList<>(); List<CarrierMatchingRule> rules = new ArrayList<>(); Loading Loading @@ -308,7 +340,9 @@ public class CarrierResolver extends Handler { return null; return null; } } private void updateCarrierIdAndName(int cid, int mnoCid, String name) { private void updateCarrierIdAndName(int cid, String name, int preciseCarrierId, String preciseCarrierName, int mnoCid) { boolean update = false; boolean update = false; if (!equals(name, mCarrierName, true)) { if (!equals(name, mCarrierName, true)) { logd("[updateCarrierName] from:" + mCarrierName + " to:" + name); logd("[updateCarrierName] from:" + mCarrierName + " to:" + name); Loading @@ -325,7 +359,6 @@ public class CarrierResolver extends Handler { mMnoCarrierId = mnoCid; mMnoCarrierId = mnoCid; update = true; update = true; } } if (update) { if (update) { mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:" mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:" + mCarrierName + " mnoCid:" + mMnoCarrierId); + mCarrierName + " mnoCid:" + mMnoCarrierId); Loading @@ -337,7 +370,7 @@ public class CarrierResolver extends Handler { intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); mContext.sendBroadcast(intent); mContext.sendBroadcast(intent); // update current subscriptions // notify content observers for carrier id change event ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues(); cv.put(CarrierId.CARRIER_ID, mCarrierId); cv.put(CarrierId.CARRIER_ID, mCarrierId); cv.put(CarrierId.CARRIER_NAME, mCarrierName); cv.put(CarrierId.CARRIER_NAME, mCarrierName); Loading @@ -346,6 +379,38 @@ public class CarrierResolver extends Handler { Uri.withAppendedPath(CarrierId.CONTENT_URI, Uri.withAppendedPath(CarrierId.CONTENT_URI, Integer.toString(mPhone.getSubId())), cv, null, null); Integer.toString(mPhone.getSubId())), cv, null, null); } } update = false; if (preciseCarrierId != mPreciseCarrierId) { logd("[updatePreciseCarrierId] from:" + mPreciseCarrierId + " to:" + preciseCarrierId); mPreciseCarrierId = preciseCarrierId; update = true; } if (preciseCarrierName != mPreciseCarrierName) { logd("[updatePreciseCarrierName] from:" + mPreciseCarrierName + " to:" + preciseCarrierName); mPreciseCarrierName = preciseCarrierName; update = true; } if (update) { mCarrierIdLocalLog.log("[updatePreciseCarrierIdAndName] cid:" + mPreciseCarrierId + " name:" + mPreciseCarrierName); final Intent intent = new Intent(TelephonyManager .ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED); intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_ID, mPreciseCarrierId); intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_NAME, mPreciseCarrierName); intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); mContext.sendBroadcast(intent); // notify content observers for precise carrier id change event. ContentValues cv = new ContentValues(); cv.put(CarrierId.PRECISE_CARRIER_ID, mPreciseCarrierId); cv.put(CarrierId.PRECISE_CARRIER_ID_NAME, mPreciseCarrierName); mContext.getContentResolver().update( Telephony.CarrierId.getPreciseCarrierIdUriForSubscriptionId(mPhone.getSubId()), cv, null, null); } } } private static CarrierMatchingRule makeCarrierMatchingRule(Cursor cursor) { private static CarrierMatchingRule makeCarrierMatchingRule(Cursor cursor) { Loading @@ -364,7 +429,8 @@ public class CarrierResolver extends Handler { cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)), cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)), (TextUtils.isEmpty(certs) ? null : new ArrayList<>(Arrays.asList(certs))), (TextUtils.isEmpty(certs) ? null : new ArrayList<>(Arrays.asList(certs))), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)), cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME))); cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME)), cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.PARENT_CARRIER_ID))); } } /** /** Loading Loading @@ -408,12 +474,14 @@ public class CarrierResolver extends Handler { private String mName; private String mName; // unique carrier id // unique carrier id private int mCid; private int mCid; // unique parent carrier id private int mParentCid; private int mScore = 0; private int mScore = 0; CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix, private CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix, String gid1, String gid2, String plmn, String spn, String apn, String gid1, String gid2, String plmn, String spn, String apn, List<String> privilegeAccessRule, int cid, String name) { List<String> privilegeAccessRule, int cid, String name, int parentCid) { mMccMnc = mccmnc; mMccMnc = mccmnc; mImsiPrefixPattern = imsiPrefixPattern; mImsiPrefixPattern = imsiPrefixPattern; mIccidPrefix = iccidPrefix; mIccidPrefix = iccidPrefix; Loading @@ -425,6 +493,22 @@ public class CarrierResolver extends Handler { mPrivilegeAccessRule = privilegeAccessRule; mPrivilegeAccessRule = privilegeAccessRule; mCid = cid; mCid = cid; mName = name; mName = name; mParentCid = parentCid; } private CarrierMatchingRule(CarrierMatchingRule rule) { mMccMnc = rule.mMccMnc; mImsiPrefixPattern = rule.mImsiPrefixPattern; mIccidPrefix = rule.mIccidPrefix; mGid1 = rule.mGid1; mGid2 = rule.mGid2; mPlmn = rule.mPlmn; mSpn = rule.mSpn; mApn = rule.mApn; mPrivilegeAccessRule = rule.mPrivilegeAccessRule; mCid = rule.mCid; mName = rule.mName; mParentCid = rule.mParentCid; } } // Calculate matching score. Values which aren't set in the rule are considered "wild". // Calculate matching score. Values which aren't set in the rule are considered "wild". Loading Loading @@ -586,21 +670,25 @@ public class CarrierResolver extends Handler { } } return new CarrierMatchingRule( return new CarrierMatchingRule( mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, accessRules, mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, accessRules, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } } /** /** * find the best matching carrier from candidates with matched subscription MCCMNC. * find the best matching carrier from candidates with matched subscription MCCMNC. * @return the best matching carrier id. */ */ private int matchSubscriptionCarrier() { private void matchSubscriptionCarrier() { int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { logd("[matchSubscriptionCarrier]" + "skip before sim records loaded"); logd("[matchSubscriptionCarrier]" + "skip before sim records loaded"); return carrierId; return; } } int maxScore = CarrierMatchingRule.SCORE_INVALID; int maxScore = CarrierMatchingRule.SCORE_INVALID; /** * For child-parent relationship. either child and parent have the same matching * score, or child's matching score > parents' matching score. */ CarrierMatchingRule maxRule = null; CarrierMatchingRule maxRule = null; CarrierMatchingRule maxRuleParent = null; /** /** * matching rule with mccmnc only. If mnoRule is found, then mno carrier id equals to the * matching rule with mccmnc only. If mnoRule is found, then mno carrier id equals to the * cid from mnoRule. otherwise, mno carrier id is same as cid. * cid from mnoRule. otherwise, mno carrier id is same as cid. Loading @@ -613,7 +701,15 @@ public class CarrierResolver extends Handler { if (rule.mScore > maxScore) { if (rule.mScore > maxScore) { maxScore = rule.mScore; maxScore = rule.mScore; maxRule = rule; maxRule = rule; carrierId = rule.mCid; maxRuleParent = rule; } else if (maxScore > CarrierMatchingRule.SCORE_INVALID && rule.mScore == maxScore) { // to handle the case that child parent has the same matching score, we need to // differentiate who is child who is parent. if (rule.mParentCid == maxRule.mCid) { maxRule = rule; } else if (maxRule.mParentCid == rule.mCid) { maxRuleParent = rule; } } } if (rule.mScore == CarrierMatchingRule.SCORE_MCCMNC) { if (rule.mScore == CarrierMatchingRule.SCORE_MCCMNC) { mnoRule = rule; mnoRule = rule; Loading @@ -622,12 +718,23 @@ public class CarrierResolver extends Handler { if (maxScore == CarrierMatchingRule.SCORE_INVALID) { if (maxScore == CarrierMatchingRule.SCORE_INVALID) { logd("[matchSubscriptionCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID logd("[matchSubscriptionCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID + " name: " + null); + " name: " + null); updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID, null); TelephonyManager.UNKNOWN_CARRIER_ID, null, TelephonyManager.UNKNOWN_CARRIER_ID); } else { } else { logd("[matchSubscriptionCarrier] cid: " + maxRule.mCid + " name: " + maxRule.mName); // if there is a single matching result, check if this rule has parent cid assigned. updateCarrierIdAndName(maxRule.mCid, if ((maxRule == maxRuleParent) (mnoRule == null) ? maxRule.mCid : mnoRule.mCid, maxRule.mName); && maxRule.mParentCid != TelephonyManager.UNKNOWN_CARRIER_ID) { maxRuleParent = new CarrierMatchingRule(maxRule); maxRuleParent.mCid = maxRuleParent.mParentCid; maxRuleParent.mName = getCarrierNameFromId(maxRuleParent.mCid); } logd("[matchSubscriptionCarrier] precise cid: " + maxRule.mCid + " precise name: " + maxRule.mName +" cid: " + maxRuleParent.mCid + " name: " + maxRuleParent.mName); updateCarrierIdAndName(maxRuleParent.mCid, maxRuleParent.mName, maxRule.mCid, maxRule.mName, (mnoRule == null) ? maxRule.mCid : mnoRule.mCid); } } /* /* Loading @@ -648,7 +755,6 @@ public class CarrierResolver extends Handler { TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent( TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent( mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId, mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId, unknownMccmncToLog, unknownGid1ToLog); unknownMccmncToLog, unknownGid1ToLog); return carrierId; } } public int getCarrierListVersion() { public int getCarrierListVersion() { Loading @@ -662,15 +768,33 @@ public class CarrierResolver extends Handler { public int getCarrierId() { public int getCarrierId() { return mCarrierId; return mCarrierId; } } /** public int getMnoCarrierId() { * Returns fine-grained carrier id of the current subscription. Carrier ids with a valid parent return mMnoCarrierId; * id are precise carrier ids. * The precise carrier id can be used to further differentiate a carrier by different * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique * carrier id but can have multiple precise carrier id. e.g, * {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while * {@link #getPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the * current underlying network. * For carriers without any fine-grained carrier ids, return {@link #getCarrierId()} */ public int getPreciseCarrierId() { return mPreciseCarrierId; } } public String getCarrierName() { public String getCarrierName() { return mCarrierName; return mCarrierName; } } public String getPreciseCarrierName() { return mPreciseCarrierName; } public int getMnoCarrierId() { return mMnoCarrierId; } /** /** * a util function to convert carrierIdentifier to the best matching carrier id. * a util function to convert carrierIdentifier to the best matching carrier id. * * Loading @@ -694,7 +818,9 @@ public class CarrierResolver extends Handler { // assign null to other fields which are not supported by carrierIdentifier. // assign null to other fields which are not supported by carrierIdentifier. CarrierMatchingRule targetRule = CarrierMatchingRule targetRule = new CarrierMatchingRule(mccmnc, imsi, null, gid1, gid2, null, new CarrierMatchingRule(mccmnc, imsi, null, gid1, gid2, null, spn, null, null, -1, null); spn, null, null, TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION, null, TelephonyManager.UNKNOWN_CARRIER_ID); int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; int maxScore = CarrierMatchingRule.SCORE_INVALID; int maxScore = CarrierMatchingRule.SCORE_INVALID; Loading Loading @@ -786,8 +912,10 @@ public class CarrierResolver extends Handler { ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.println("mCarrierId: " + mCarrierId); ipw.println("mCarrierId: " + mCarrierId); ipw.println("mPreciseCarrierId: " + mPreciseCarrierId); ipw.println("mMnoCarrierId: " + mMnoCarrierId); ipw.println("mMnoCarrierId: " + mMnoCarrierId); ipw.println("mCarrierName: " + mCarrierName); ipw.println("mCarrierName: " + mCarrierName); ipw.println("mPreciseCarrierName: " + mPreciseCarrierName); ipw.println("version: " + getCarrierListVersion()); ipw.println("version: " + getCarrierListVersion()); ipw.println("mCarrierMatchingRules on mccmnc: " ipw.println("mCarrierMatchingRules on mccmnc: " Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1579,6 +1579,16 @@ public class GsmCdmaPhone extends Phone { return mCarrerResolver.getMnoCarrierId(); return mCarrerResolver.getMnoCarrierId(); } } @Override public int getPreciseCarrierId() { return mCarrerResolver.getPreciseCarrierId(); } @Override public String getPreciseCarrierName() { return mCarrerResolver.getPreciseCarrierName(); } @Override @Override public int getCarrierIdListVersion() { public int getCarrierIdListVersion() { return mCarrerResolver.getCarrierListVersion(); return mCarrerResolver.getCarrierListVersion(); Loading
src/java/com/android/internal/telephony/Phone.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -3117,6 +3117,14 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { return TelephonyManager.UNKNOWN_CARRIER_ID; return TelephonyManager.UNKNOWN_CARRIER_ID; } } public int getPreciseCarrierId() { return TelephonyManager.UNKNOWN_CARRIER_ID; } public String getPreciseCarrierName() { return null; } public int getCarrierIdListVersion() { public int getCarrierIdListVersion() { return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION; } } Loading
tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java +189 −11 File changed.Preview size limit exceeded, changes collapsed. Show changes