12db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu/* 22db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * Copyright 2017 The Android Open Source Project 32db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 42db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * Licensed under the Apache License, Version 2.0 (the "License"); 52db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * you may not use this file except in compliance with the License. 62db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * You may obtain a copy of the License at 72db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 82db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * http://www.apache.org/licenses/LICENSE-2.0 92db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * Unless required by applicable law or agreed to in writing, software 112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * distributed under the License is distributed on an "AS IS" BASIS, 122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * See the License for the specific language governing permissions and 142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * limitations under the License. 152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxupackage com.android.internal.telephony; 172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 18f24387f54a080dfc6e72c0511b2b3db757585edffionaxuimport static android.provider.Telephony.CarrierId; 19769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian 2063d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxuimport android.content.ContentValues; 212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.content.Context; 224431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxuimport android.content.Intent; 232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.database.ContentObserver; 242db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.database.Cursor; 252db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.net.Uri; 262db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.os.Handler; 272db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.os.Message; 282db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.provider.Telephony; 292db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.telephony.Rlog; 302db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.telephony.SubscriptionManager; 312db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.telephony.TelephonyManager; 322db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.text.TextUtils; 332db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.util.LocalLog; 342db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport android.util.Log; 352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3695719cadc5d606bec05b02902f6dc0a8c45f5d58sqianimport com.android.internal.telephony.metrics.TelephonyMetrics; 372db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport com.android.internal.telephony.uicc.IccRecords; 382db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport com.android.internal.telephony.uicc.UiccController; 39d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxuimport com.android.internal.telephony.uicc.UiccProfile; 402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport com.android.internal.util.IndentingPrintWriter; 412db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 422db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport java.io.FileDescriptor; 432db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport java.io.PrintWriter; 442db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport java.util.ArrayList; 452db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport java.util.List; 462db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxuimport java.util.concurrent.atomic.AtomicInteger; 472db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 482db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu/** 492db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * CarrierIdentifier identifies the subscription carrier and returns a canonical carrier Id 502db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * and a user friendly carrier name. CarrierIdentifier reads subscription info and check against 512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * all carrier matching rules stored in CarrierIdProvider. It is msim aware, each phone has a 522db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * dedicated CarrierIdentifier. 532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxupublic class CarrierIdentifier extends Handler { 552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final String LOG_TAG = CarrierIdentifier.class.getSimpleName(); 562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final boolean DBG = true; 572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE); 582db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // events to trigger carrier identification 602db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SIM_LOAD_EVENT = 1; 612db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SIM_ABSENT_EVENT = 2; 622db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SPN_OVERRIDE_EVENT = 3; 632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int ICC_CHANGED_EVENT = 4; 642db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int PREFER_APN_UPDATE_EVENT = 5; 652db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int CARRIER_ID_DB_UPDATE_EVENT = 6; 662db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 672db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final Uri CONTENT_URL_PREFER_APN = Uri.withAppendedPath( 682db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Telephony.Carriers.CONTENT_URI, "preferapn"); 692db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final String OPERATOR_BRAND_OVERRIDE_PREFIX = "operator_branding_"; 702db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 712db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // cached matching rules based mccmnc to speed up resolution 722db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>(); 732db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // cached carrier Id 744431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; 752db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // cached carrier name 762db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mCarrierName; 772db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // cached preferapn name 782db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mPreferApn; 792db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // cached service provider name. telephonyManager API returns empty string as default value. 802db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // some carriers need to target devices with Empty SPN. In that case, carrier matching rule 812db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // should specify "" spn explicitly. 822db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mSpn = ""; 832db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 842db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private Context mContext; 852db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private Phone mPhone; 862db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private IccRecords mIccRecords; 87d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu private UiccProfile mUiccProfile; 882db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private final LocalLog mCarrierIdLocalLog = new LocalLog(20); 892db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private final TelephonyManager mTelephonyMgr; 902db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private final SubscriptionsChangedListener mOnSubscriptionsChangedListener = 912db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu new SubscriptionsChangedListener(); 922db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 932db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private final ContentObserver mContentObserver = new ContentObserver(this) { 942db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu @Override 952db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public void onChange(boolean selfChange, Uri uri) { 962db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (CONTENT_URL_PREFER_APN.equals(uri.getLastPathSegment())) { 9763d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu logd("onChange URI: " + uri); 982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu sendEmptyMessage(PREFER_APN_UPDATE_EVENT); 99f24387f54a080dfc6e72c0511b2b3db757585edffionaxu } else if (CarrierId.All.CONTENT_URI.equals(uri)) { 10063d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu logd("onChange URI: " + uri); 1012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu sendEmptyMessage(CARRIER_ID_DB_UPDATE_EVENT); 1022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu }; 1052db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 1062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private class SubscriptionsChangedListener 1072db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu extends SubscriptionManager.OnSubscriptionsChangedListener { 1082db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final AtomicInteger mPreviousSubId = 1092db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /** 1112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * Callback invoked when there is any change to any SubscriptionInfo. Typically 1122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList} 1132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 1142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu @Override 1152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public void onSubscriptionsChanged() { 1162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu int subId = mPhone.getSubId(); 1172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mPreviousSubId.getAndSet(subId) != subId) { 1182db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (DBG) { 1192db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("SubscriptionListener.onSubscriptionInfoChanged subId: " 1202db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + mPreviousSubId); 1212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1222db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (SubscriptionManager.isValidSubscriptionId(subId)) { 1232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu sendEmptyMessage(SIM_LOAD_EVENT); 1242db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } else { 1252db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu sendEmptyMessage(SIM_ABSENT_EVENT); 1262db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1272db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1282db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1292db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1302db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 1312db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public CarrierIdentifier(Phone phone) { 1322db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("Creating CarrierIdentifier[" + phone.getPhoneId() + "]"); 1332db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mContext = phone.getContext(); 1342db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mPhone = phone; 1352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mTelephonyMgr = TelephonyManager.from(mContext); 1362db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 1372db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // register events 1382db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mContext.getContentResolver().registerContentObserver(CONTENT_URL_PREFER_APN, false, 1392db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mContentObserver); 1402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mContext.getContentResolver().registerContentObserver( 141f24387f54a080dfc6e72c0511b2b3db757585edffionaxu CarrierId.All.CONTENT_URI, false, mContentObserver); 1422db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu SubscriptionManager.from(mContext).addOnSubscriptionsChangedListener( 1432db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mOnSubscriptionsChangedListener); 1442db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu UiccController.getInstance().registerForIccChanged(this, ICC_CHANGED_EVENT, null); 1452db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1462db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 1472db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /** 1482db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * Entry point for the carrier identification. 1492db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 1502db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 1. SIM_LOAD_EVENT 1512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * This indicates that all SIM records has been loaded and its first entry point for the 1522db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * carrier identification. Note, there are other attributes could be changed on the fly 1532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * like APN and SPN. We cached all carrier matching rules based on MCCMNC to speed 1542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * up carrier resolution on following trigger events. 1552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 1562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 2. PREFER_APN_UPDATE_EVENT 1572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * This indicates prefer apn has been changed. It could be triggered when user modified 1582db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * APN settings or when default data connection first establishes on the current carrier. 1592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * We follow up on this by querying prefer apn sqlite and re-issue carrier identification 1602db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * with the updated prefer apn name. 1612db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 1622db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 3. SPN_OVERRIDE_EVENT 1632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * This indicates that SPN value as been changed. It could be triggered from EF_SPN 1642db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * record loading, carrier config override 1652db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * {@link android.telephony.CarrierConfigManager#KEY_CARRIER_NAME_STRING} 1662db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * or carrier app override {@link TelephonyManager#setOperatorBrandOverride(String)}. 1672db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * we follow up this by checking the cached mSPN against the latest value and issue 1682db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * carrier identification only if spn changes. 1692db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 1702db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * 4. CARRIER_ID_DB_UPDATE_EVENT 1712db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * This indicates that carrierIdentification database which stores all matching rules 1722db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * has been updated. It could be triggered from OTA or assets update. 1732db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 1742db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu @Override 1752db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public void handleMessage(Message msg) { 1762db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (VDBG) logd("handleMessage: " + msg.what); 1772db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu switch (msg.what) { 1782db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case SIM_LOAD_EVENT: 1792db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case CARRIER_ID_DB_UPDATE_EVENT: 1802db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mSpn = mTelephonyMgr.getSimOperatorNameForPhone(mPhone.getPhoneId()); 1812db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mPreferApn = getPreferApn(); 1822db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu loadCarrierMatchingRulesOnMccMnc(); 1832db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 1842db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case SIM_ABSENT_EVENT: 1852db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierMatchingRulesOnMccMnc.clear(); 1862db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mSpn = null; 1872db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mPreferApn = null; 1884431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null); 1892db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 1902db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case PREFER_APN_UPDATE_EVENT: 1912db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu String preferApn = getPreferApn(); 1922db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!equals(mPreferApn, preferApn, true)) { 1932db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[updatePreferApn] from:" + mPreferApn + " to:" + preferApn); 1942db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mPreferApn = preferApn; 1952db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu matchCarrier(); 1962db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 1972db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 1982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case SPN_OVERRIDE_EVENT: 1992db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu String spn = mTelephonyMgr.getSimOperatorNameForPhone(mPhone.getPhoneId()); 2002db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!equals(mSpn, spn, true)) { 2012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[updateSpn] from:" + mSpn + " to:" + spn); 2022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mSpn = spn; 2032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu matchCarrier(); 2042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2052db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 2062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu case ICC_CHANGED_EVENT: 207d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu // all records used for carrier identification are from SimRecord 208d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu final IccRecords newIccRecords = UiccController.getInstance().getIccRecords( 209d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu mPhone.getPhoneId(), UiccController.APP_FAM_3GPP); 2102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mIccRecords != newIccRecords) { 2112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mIccRecords != null) { 2122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("Removing stale icc objects."); 213ba3cd5d9bb09cfb989fd65c00e4f45287aa60df1fionaxu mIccRecords.unregisterForRecordsLoaded(this); 21434d5b710cf2d5f2408b53b41490efa88a57dc4f4fionaxu mIccRecords.unregisterForRecordsOverride(this); 2152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mIccRecords = null; 2162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (newIccRecords != null) { 2182db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("new Icc object"); 219ba3cd5d9bb09cfb989fd65c00e4f45287aa60df1fionaxu newIccRecords.registerForRecordsLoaded(this, SIM_LOAD_EVENT, null); 22034d5b710cf2d5f2408b53b41490efa88a57dc4f4fionaxu newIccRecords.registerForRecordsOverride(this, SIM_LOAD_EVENT, null); 2212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mIccRecords = newIccRecords; 2222db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 224d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu // check UICC profile 225d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu final UiccProfile uiccProfile = UiccController.getInstance() 226d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu .getUiccProfileForPhone(mPhone.getPhoneId()); 227d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu if (mUiccProfile != uiccProfile) { 228d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu if (mUiccProfile != null) { 229d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu logd("unregister operatorBrandOverride"); 230d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu mUiccProfile.unregisterForOperatorBrandOverride(this); 231d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu mUiccProfile = null; 232d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu } 233d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu if (uiccProfile != null) { 234d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu logd("register operatorBrandOverride"); 235d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu uiccProfile.registerForOpertorBrandOverride(this, SPN_OVERRIDE_EVENT, null); 236d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu mUiccProfile = uiccProfile; 237d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu } 238d27bd6be3ed4a0d20a228767792476bdbbfc1484fionaxu } 2392db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 2402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu default: 2412db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu loge("invalid msg: " + msg.what); 2422db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu break; 2432db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2442db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2452db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 2462db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private void loadCarrierMatchingRulesOnMccMnc() { 2472db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu try { 2482db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu String mccmnc = mTelephonyMgr.getSimOperatorNumericForPhone(mPhone.getPhoneId()); 24963d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu Cursor cursor = mContext.getContentResolver().query( 250f24387f54a080dfc6e72c0511b2b3db757585edffionaxu CarrierId.All.CONTENT_URI, 2512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /* projection */ null, 252f24387f54a080dfc6e72c0511b2b3db757585edffionaxu /* selection */ CarrierId.All.MCCMNC + "=?", 2532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /* selectionArgs */ new String[]{mccmnc}, null); 2542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu try { 2552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (cursor != null) { 2562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (VDBG) { 2572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[loadCarrierMatchingRules]- " + cursor.getCount() 2582db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " Records(s) in DB" + " mccmnc: " + mccmnc); 2592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2602db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierMatchingRulesOnMccMnc.clear(); 2612db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu while (cursor.moveToNext()) { 2622db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierMatchingRulesOnMccMnc.add(makeCarrierMatchingRule(cursor)); 2632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2642db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu matchCarrier(); 2652db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2662db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } finally { 2672db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (cursor != null) { 2682db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu cursor.close(); 2692db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2702db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2712db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } catch (Exception ex) { 2722db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu loge("[loadCarrierMatchingRules]- ex: " + ex); 2732db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2742db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2752db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 2762db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String getPreferApn() { 2772db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Cursor cursor = mContext.getContentResolver().query( 2782db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapn/subId/" 2792db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + mPhone.getSubId()), /* projection */ new String[]{Telephony.Carriers.APN}, 2802db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /* selection */ null, /* selectionArgs */ null, /* sortOrder */ null); 2812db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu try { 2822db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (cursor != null) { 2832db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (VDBG) { 2842db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[getPreferApn]- " + cursor.getCount() + " Records(s) in DB"); 2852db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2862db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu while (cursor.moveToNext()) { 2872db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu String apn = cursor.getString(cursor.getColumnIndexOrThrow( 2882db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Telephony.Carriers.APN)); 2892db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[getPreferApn]- " + apn); 2902db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return apn; 2912db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2922db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2932db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } catch (Exception ex) { 2942db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu loge("[getPreferApn]- exception: " + ex); 2952db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } finally { 2962db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (cursor != null) { 2972db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu cursor.close(); 2982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 2992db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3002db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return null; 3012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private void updateCarrierIdAndName(int cid, String name) { 3042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu boolean update = false; 3052db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!equals(name, mCarrierName, true)) { 3062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[updateCarrierName] from:" + mCarrierName + " to:" + name); 3072db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierName = name; 3082db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu update = true; 3092db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (cid != mCarrierId) { 3112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[updateCarrierId] from:" + mCarrierId + " to:" + cid); 3122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierId = cid; 3132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu update = true; 3142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (update) { 3162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierIdLocalLog.log("[updateCarrierIdAndName] cid:" + mCarrierId + " name:" 3172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + mCarrierName); 3184431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu final Intent intent = new Intent(TelephonyManager 3194431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu .ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED); 3204431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, mCarrierId); 3214431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu intent.putExtra(TelephonyManager.EXTRA_CARRIER_NAME, mCarrierName); 3224431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId()); 3234431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu mContext.sendBroadcast(intent); 32463d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu 32563d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu // update current subscriptions 32663d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu ContentValues cv = new ContentValues(); 327f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cv.put(CarrierId.CARRIER_ID, mCarrierId); 328f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cv.put(CarrierId.CARRIER_NAME, mCarrierName); 32963d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu mContext.getContentResolver().update( 330f24387f54a080dfc6e72c0511b2b3db757585edffionaxu Uri.withAppendedPath(CarrierId.CONTENT_URI, 33163d0d7aa4fc9f35434345a1f89b93017e564d2cffionaxu Integer.toString(mPhone.getSubId())), cv, null, null); 3322db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3332db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3342db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private CarrierMatchingRule makeCarrierMatchingRule(Cursor cursor) { 3362db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return new CarrierMatchingRule( 337f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.MCCMNC)), 3382db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu cursor.getString(cursor.getColumnIndexOrThrow( 339f24387f54a080dfc6e72c0511b2b3db757585edffionaxu CarrierId.All.IMSI_PREFIX_XPATTERN)), 340769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian cursor.getString(cursor.getColumnIndexOrThrow( 341f24387f54a080dfc6e72c0511b2b3db757585edffionaxu CarrierId.All.ICCID_PREFIX)), 342f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.GID1)), 343f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.GID2)), 344f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.PLMN)), 345f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.SPN)), 346f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.All.APN)), 347f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getInt(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_ID)), 348f24387f54a080dfc6e72c0511b2b3db757585edffionaxu cursor.getString(cursor.getColumnIndexOrThrow(CarrierId.CARRIER_NAME))); 3492db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 3502db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /** 3522db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * carrier matching attributes with corresponding cid 3532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 3542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static class CarrierMatchingRule { 3552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /** 3562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * These scores provide the hierarchical relationship between the attributes, intended to 3572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * resolve conflicts in a deterministic way. The scores are constructed such that a match 3582db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * from a higher tier will beat any subsequent match which does not match at that tier, 3592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * so MCCMNC beats everything else. This avoids problems when two (or more) carriers rule 3602db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * matches as the score helps to find the best match uniquely. e.g., 3612db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * rule 1 {mccmnc, imsi} rule 2 {mccmnc, imsi, gid1} and rule 3 {mccmnc, imsi, gid2} all 3622db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * matches with subscription data. rule 2 wins with the highest matching score. 3632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 364769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian private static final int SCORE_MCCMNC = 1 << 7; 365769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian private static final int SCORE_IMSI_PREFIX = 1 << 6; 366769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian private static final int SCORE_ICCID_PREFIX = 1 << 5; 3672db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_GID1 = 1 << 4; 3682db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_GID2 = 1 << 3; 3692db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_PLMN = 1 << 2; 3702db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_SPN = 1 << 1; 3712db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_APN = 1 << 0; 3722db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3732db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static final int SCORE_INVALID = -1; 3742db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3752db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // carrier matching attributes 3762db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mMccMnc; 3772db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mImsiPrefixPattern; 378769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian private String mIccidPrefix; 3792db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mGid1; 3802db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mGid2; 3812db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mPlmn; 3822db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mSpn; 3832db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mApn; 3842db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3852db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // user-facing carrier name 3862db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private String mName; 3872db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // unique carrier id 3882db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private int mCid; 3892db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 3902db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private int mScore = 0; 3912db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 392769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian CarrierMatchingRule(String mccmnc, String imsiPrefixPattern, String iccidPrefix, 393769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian String gid1, String gid2, String plmn, String spn, String apn, int cid, 394769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian String name) { 3952db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mMccMnc = mccmnc; 3962db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mImsiPrefixPattern = imsiPrefixPattern; 397769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian mIccidPrefix = iccidPrefix; 3982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mGid1 = gid1; 3992db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mGid2 = gid2; 4002db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mPlmn = plmn; 4012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mSpn = spn; 4022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mApn = apn; 4032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCid = cid; 4042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mName = name; 4052db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 4072db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // Calculate matching score. Values which aren't set in the rule are considered "wild". 4082db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // All values in the rule must match in order for the subscription to be considered part of 409769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian // the carrier. Otherwise, a invalid score -1 will be assigned. A match from a higher tier 4102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // will beat any subsequent match which does not match at that tier. When there are multiple 411769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian // matches at the same tier, the match with highest score will be used. 4122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public void match(CarrierMatchingRule subscriptionRule) { 4132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = 0; 4142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mMccMnc != null) { 4152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mMccMnc, mMccMnc, false)) { 4162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4182db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4192db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_MCCMNC; 4202db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mImsiPrefixPattern != null) { 4222db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!imsiPrefixMatch(subscriptionRule.mImsiPrefixPattern, mImsiPrefixPattern)) { 4232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4242db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4252db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4262db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_IMSI_PREFIX; 4272db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 428769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian if (mIccidPrefix != null) { 429769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian if (!iccidPrefixMatch(subscriptionRule.mIccidPrefix, mIccidPrefix)) { 430769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian mScore = SCORE_INVALID; 431769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian return; 432769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian } 433769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian mScore += SCORE_ICCID_PREFIX; 434769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian } 4352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mGid1 != null) { 4362db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // full string match. carrier matching should cover the corner case that gid1 4372db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // with garbage tail due to SIM manufacture issues. 4382db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mGid1, mGid1, true)) { 4392db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4412db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4422db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_GID1; 4432db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4442db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mGid2 != null) { 4452db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // full string match. carrier matching should cover the corner case that gid2 4462db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu // with garbage tail due to SIM manufacture issues. 4472db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mGid2, mGid2, true)) { 4482db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4492db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4502db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_GID2; 4522db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mPlmn != null) { 4542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mPlmn, mPlmn, true)) { 4552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4582db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_PLMN; 4592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4602db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mSpn != null) { 4612db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mSpn, mSpn, true)) { 4622db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4642db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4652db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_SPN; 4662db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4672db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (mApn != null) { 4682db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!CarrierIdentifier.equals(subscriptionRule.mApn, mApn, true)) { 4692db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore = SCORE_INVALID; 4702db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 4712db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4722db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mScore += SCORE_APN; 4732db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4742db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4752db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 4762db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private boolean imsiPrefixMatch(String imsi, String prefixXPattern) { 4772db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (TextUtils.isEmpty(prefixXPattern)) return true; 4782db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (TextUtils.isEmpty(imsi)) return false; 4792db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (imsi.length() < prefixXPattern.length()) { 4802db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return false; 4812db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4822db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu for (int i = 0; i < prefixXPattern.length(); i++) { 4832db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if ((prefixXPattern.charAt(i) != 'x') && (prefixXPattern.charAt(i) != 'X') 4842db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu && (prefixXPattern.charAt(i) != imsi.charAt(i))) { 4852db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return false; 4862db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4872db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4882db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return true; 4892db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 4902db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 491769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian private boolean iccidPrefixMatch(String iccid, String prefix) { 492769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian if (iccid == null || prefix == null) { 493769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian return false; 494769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian } 495769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian return iccid.startsWith(prefix); 496769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian } 497769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian 4982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public String toString() { 4992db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return "[CarrierMatchingRule] -" 5002db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " mccmnc: " + mMccMnc 5012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " gid1: " + mGid1 5022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " gid2: " + mGid2 5032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " plmn: " + mPlmn 5042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " imsi_prefix: " + mImsiPrefixPattern 505769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian + " iccid_prefix" + mIccidPrefix 5062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " spn: " + mSpn 5072db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " apn: " + mApn 5082db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " name: " + mName 5092db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " cid: " + mCid 5102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " score: " + mScore; 5112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu /** 5152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * find the best matching carrier from candidates with matched MCCMNC and notify 5162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu * all interested parties on carrier id change. 5172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu */ 5182db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private void matchCarrier() { 5192db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) { 5202db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[matchCarrier]" + "skip before sim records loaded"); 5212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return; 5222db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String mccmnc = mTelephonyMgr.getSimOperatorNumericForPhone(mPhone.getPhoneId()); 524769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian final String iccid = mPhone.getIccSerialNumber(); 5252db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String gid1 = mPhone.getGroupIdLevel1(); 5262db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String gid2 = mPhone.getGroupIdLevel2(); 5272db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String imsi = mPhone.getSubscriberId(); 5282db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String plmn = mPhone.getPlmn(); 5292db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String spn = mSpn; 5302db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final String apn = mPreferApn; 5312db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5322db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (VDBG) { 5332db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[matchCarrier]" 5348960458652e870ddbaf9eeda1291abed76f0e26ffionaxu + " mnnmnc:" + mccmnc 5352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " gid1: " + gid1 5362db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " gid2: " + gid2 5372db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " imsi: " + Rlog.pii(LOG_TAG, imsi) 538769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian + " iccid: " + Rlog.pii(LOG_TAG, iccid) 5392db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " plmn: " + plmn 5402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " spn: " + spn 5412db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + " apn: " + apn); 5422db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5432db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5442db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu CarrierMatchingRule subscriptionRule = new CarrierMatchingRule( 545769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian mccmnc, imsi, iccid, gid1, gid2, plmn, spn, apn, 546769ab7354530a88cb1b46fdb1bed1e97ec0db4b2sqian TelephonyManager.UNKNOWN_CARRIER_ID, null); 5472db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5482db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu int maxScore = CarrierMatchingRule.SCORE_INVALID; 5492db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu CarrierMatchingRule maxRule = null; 5502db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5512db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu for (CarrierMatchingRule rule : mCarrierMatchingRulesOnMccMnc) { 5522db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu rule.match(subscriptionRule); 5532db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (rule.mScore > maxScore) { 5542db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu maxScore = rule.mScore; 5552db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu maxRule = rule; 5562db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5572db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 55895719cadc5d606bec05b02902f6dc0a8c45f5d58sqian 5592db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (maxScore == CarrierMatchingRule.SCORE_INVALID) { 5604431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu logd("[matchCarrier - no match] cid: " + TelephonyManager.UNKNOWN_CARRIER_ID 5614431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu + " name: " + null); 5624431e1cf9215cf525f221edcbd7559d00b8a0fdffionaxu updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null); 5632db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } else { 5642db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu logd("[matchCarrier] cid: " + maxRule.mCid + " name: " + maxRule.mName); 5652db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu updateCarrierIdAndName(maxRule.mCid, maxRule.mName); 5662db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 56795719cadc5d606bec05b02902f6dc0a8c45f5d58sqian 56895719cadc5d606bec05b02902f6dc0a8c45f5d58sqian /* 56995719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * Write Carrier Identification Matching event, logging with the 5707549b1314bca640223819c29a2ead9f282d2e9f6sqian * carrierId, mccmnc, gid1 and carrier list version to differentiate below cases of metrics: 57195719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * 1) unknown mccmnc - the Carrier Id provider contains no rule that matches the 57295719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * read mccmnc. 57395719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * 2) the Carrier Id provider contains some rule(s) that match the read mccmnc, 57495719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * but the read gid1 is not matched within the highest-scored rule. 57595719cadc5d606bec05b02902f6dc0a8c45f5d58sqian * 3) successfully found a matched carrier id in the provider. 5763d66e817e8258915ca81ff594d688489247873a7fionaxu * 4) use carrier list version to compare the unknown carrier ratio between each version. 57795719cadc5d606bec05b02902f6dc0a8c45f5d58sqian */ 57899a3a76517bfb95ced43a1092578fb00366c2083sqian String unknownGid1ToLog = ((maxScore & CarrierMatchingRule.SCORE_GID1) == 0 57995719cadc5d606bec05b02902f6dc0a8c45f5d58sqian && !TextUtils.isEmpty(subscriptionRule.mGid1)) ? subscriptionRule.mGid1 : null; 5807549b1314bca640223819c29a2ead9f282d2e9f6sqian String unknownMccmncToLog = ((maxScore == CarrierMatchingRule.SCORE_INVALID 5817549b1314bca640223819c29a2ead9f282d2e9f6sqian || (maxScore & CarrierMatchingRule.SCORE_GID1) == 0) 58299a3a76517bfb95ced43a1092578fb00366c2083sqian && !TextUtils.isEmpty(subscriptionRule.mMccMnc)) ? subscriptionRule.mMccMnc : null; 58395719cadc5d606bec05b02902f6dc0a8c45f5d58sqian TelephonyMetrics.getInstance().writeCarrierIdMatchingEvent( 58499a3a76517bfb95ced43a1092578fb00366c2083sqian mPhone.getPhoneId(), getCarrierListVersion(), mCarrierId, 58599a3a76517bfb95ced43a1092578fb00366c2083sqian unknownMccmncToLog, unknownGid1ToLog); 5863d66e817e8258915ca81ff594d688489247873a7fionaxu } 5873d66e817e8258915ca81ff594d688489247873a7fionaxu 5888960458652e870ddbaf9eeda1291abed76f0e26ffionaxu public int getCarrierListVersion() { 5893d66e817e8258915ca81ff594d688489247873a7fionaxu final Cursor cursor = mContext.getContentResolver().query( 590f24387f54a080dfc6e72c0511b2b3db757585edffionaxu Uri.withAppendedPath(CarrierId.All.CONTENT_URI, 5913d66e817e8258915ca81ff594d688489247873a7fionaxu "get_version"), null, null, null); 5923d66e817e8258915ca81ff594d688489247873a7fionaxu cursor.moveToFirst(); 5933d66e817e8258915ca81ff594d688489247873a7fionaxu return cursor.getInt(0); 5942db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5952db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 5962db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public int getCarrierId() { 5972db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return mCarrierId; 5982db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 5992db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6002db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public String getCarrierName() { 6012db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return mCarrierName; 6022db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6032db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6042db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static boolean equals(String a, String b, boolean ignoreCase) { 6052db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (a == null && b == null) return true; 6062db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu if (a != null && b != null) { 6072db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return (ignoreCase) ? a.equalsIgnoreCase(b) : a.equals(b); 6082db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6092db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu return false; 6102db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6112db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6122db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static void logd(String str) { 6132db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Rlog.d(LOG_TAG, str); 6142db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6152db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu private static void loge(String str) { 6162db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu Rlog.e(LOG_TAG, str); 6172db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6182db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 6192db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 6202db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mCarrierIdLocalLogs:"); 6212db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.increaseIndent(); 6222db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu mCarrierIdLocalLog.dump(fd, pw, args); 6232db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.decreaseIndent(); 6242db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6252db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mCarrierId: " + mCarrierId); 6262db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mCarrierName: " + mCarrierName); 6273d66e817e8258915ca81ff594d688489247873a7fionaxu ipw.println("version: " + getCarrierListVersion()); 6282db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6292db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mCarrierMatchingRules on mccmnc: " 6302db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu + mTelephonyMgr.getSimOperatorNumericForPhone(mPhone.getPhoneId())); 6312db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.increaseIndent(); 6322db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu for (CarrierMatchingRule rule : mCarrierMatchingRulesOnMccMnc) { 6332db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println(rule.toString()); 6342db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6352db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.decreaseIndent(); 6362db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu 6372db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mSpn: " + mSpn); 6382db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.println("mPreferApn: " + mPreferApn); 6392db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu ipw.flush(); 6402db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu } 6412db47c1626b17a8f2c1f7f7030931a790c38c25ffionaxu} 642