Loading src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java +83 −21 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY; import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading Loading @@ -134,6 +135,12 @@ public class CarrierPrivilegesTracker extends Handler { */ private static final int ACTION_INITIALIZE_TRACKER = 7; /** * Action to set the test override rule through {@link TelephonyManager#setCarrierTestOverride}. * obj: String of the carrierPrivilegeRules from method setCarrierTestOverride. */ private static final int ACTION_SET_TEST_OVERRIDE_RULE = 8; private final Context mContext; private final Phone mPhone; private final PackageManager mPackageManager; Loading @@ -148,6 +155,11 @@ public class CarrierPrivilegesTracker extends Handler { private final List<UiccAccessRule> mCarrierConfigRules = new ArrayList<>(); // Stores rules for SIM-loaded rules. private final List<UiccAccessRule> mUiccRules = new ArrayList<>(); // Stores rule from test override (through TelephonyManager#setCarrierTestOverride). // - Null list indicates no test override (CC and UICC rules are respected) // - Empty list indicates test override to simulate no rules (CC and UICC rules are ignored) // - Non-empty list indicates test override with specific rules (CC and UICC rules are ignored) @Nullable private List<UiccAccessRule> mTestOverrideRules = null; // Map of PackageName -> Certificate hashes for that Package private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>(); // Map of PackageName -> UIDs for that Package Loading Loading @@ -328,6 +340,11 @@ public class CarrierPrivilegesTracker extends Handler { handleInitializeTracker(); break; } case ACTION_SET_TEST_OVERRIDE_RULE: { String carrierPrivilegeRules = (String) msg.obj; handleSetTestOverrideRules(carrierPrivilegeRules); break; } default: { Rlog.e(TAG, "Received unknown msg type: " + msg.what); break; Loading Loading @@ -478,19 +495,7 @@ public class CarrierPrivilegesTracker extends Handler { mUiccRules.addAll(getSimRules()); // Cache all installed packages and their certs int flags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.GET_SIGNING_CERTIFICATES; List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser( flags, UserHandle.SYSTEM.getIdentifier()); for (PackageInfo pkg : installedPackages) { updateCertsForPackage(pkg); // We shouldn't have any events coming in before initialization, but invalidate the // cache just in case to ensure consistency. getUidsForPackage(pkg.packageName, /* invalidateCache= */ true); } refreshInstalledPackageCache(); // Okay because no registrants exist yet maybeUpdatePrivilegedPackagesAndNotifyRegistrants(); Loading @@ -508,6 +513,22 @@ public class CarrierPrivilegesTracker extends Handler { mLocalLog.log(msg); } private void refreshInstalledPackageCache() { int flags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.GET_SIGNING_CERTIFICATES; List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser( flags, UserHandle.SYSTEM.getIdentifier()); for (PackageInfo pkg : installedPackages) { updateCertsForPackage(pkg); // This may be unnecessary before initialization, but invalidate the cache all the time // just in case to ensure consistency. getUidsForPackage(pkg.packageName, /* invalidateCache= */ true); } } private static <T> String getObfuscatedPackages( Collection<T> packageNames, Function<T, String> obfuscator) { StringJoiner obfuscated = new StringJoiner(", ", "{", "}"); Loading Loading @@ -576,13 +597,21 @@ public class CarrierPrivilegesTracker extends Handler { /** * Returns true iff there is an overlap between the provided certificate hashes and the * certificate hashes stored in mCarrierConfigRules and mUiccRules. * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules. */ private boolean isPackagePrivileged(String pkgName, Set<String> certs) { // Double-nested for loops, but each collection should contain at most 2 elements in nearly // every case. // TODO(b/184382310) find a way to speed this up for (String cert : certs) { // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules if (mTestOverrideRules != null) { for (UiccAccessRule rule : mTestOverrideRules) { if (rule.matches(cert, pkgName)) { return true; } } } else { for (UiccAccessRule rule : mCarrierConfigRules) { if (rule.matches(cert, pkgName)) { return true; Loading @@ -594,6 +623,7 @@ public class CarrierPrivilegesTracker extends Handler { } } } } return false; } Loading Loading @@ -635,6 +665,7 @@ public class CarrierPrivilegesTracker extends Handler { } finally { mPrivilegedPackageInfoLock.readLock().unlock(); } pw.println("CarrierPrivilegesTracker - Test-override rules: " + mTestOverrideRules); pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules); pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules); if (VDBG) { Loading Loading @@ -671,4 +702,35 @@ public class CarrierPrivilegesTracker extends Handler { public void unregisterCarrierPrivilegesListener(Handler handler) { sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler)); } /** * Set test carrier privilege rules which will override the actual rules on both Carrier Config * and SIM. * * <p>{@code carrierPrivilegeRules} can be null, in which case the rules on the Carrier Config * and SIM will be used and any previous overrides will be cleared. * * @see TelephonyManager#setCarrierTestOverride */ public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) { sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules)); } private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) { if (carrierPrivilegeRules == null) { mTestOverrideRules = null; } else if (carrierPrivilegeRules.isEmpty()) { mTestOverrideRules = Collections.emptyList(); } else { mTestOverrideRules = Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig( new String[]{carrierPrivilegeRules})); // TODO(b/215239409): remove the additional cache refresh for test override cases. // Test override doesn't respect if the package for the specified cert has been removed // or hidden since initialization. Refresh the cache again to get the pkg/uid with the // best effort. refreshInstalledPackageCache(); } maybeUpdatePrivilegedPackagesAndNotifyRegistrants(); } } tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java +66 −4 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { private static final String PACKAGE_1 = "android.test.package1"; private static final String PACKAGE_2 = "android.test.package2"; private static final String PACKAGE_3 = "android.test.package3"; private static final Set<String> PRIVILEGED_PACKAGES = Set.of(PACKAGE_1, PACKAGE_2); private static final String CERT_1 = "11223344"; Loading @@ -100,6 +101,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { private static final int UID_1 = 10000001; private static final int UID_2 = 10000002; private static final int UID_3 = 10000003; private static final int[] PRIVILEGED_UIDS = {UID_1, UID_2}; private static final int PM_FLAGS = Loading Loading @@ -187,6 +189,11 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { .thenReturn(installedPackages); } private void setupInstalledPackagesWithFlags(int flags, PackageCertInfo... pkgCertInfos) throws Exception { } /** * Creates and returns a CarrierPrivilegesTracker instance. * Loading @@ -213,7 +220,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2))); setupInstalledPackages( new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1), new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2)); new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2), new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3)); mCarrierPrivilegesTracker = createCarrierPrivilegesTracker(); } Loading @@ -221,7 +229,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2))); setupInstalledPackages( new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1), new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2)); new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2), new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3)); mCarrierPrivilegesTracker = createCarrierPrivilegesTracker(); } Loading Loading @@ -660,6 +669,59 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { verifyCarrierPrivilegesChangedUpdates(List.of()); } @Test public void testSetCarrierTestOverrideWithEmptyRule() throws Exception { // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from CarrierConfig setupCarrierPrivilegesTrackerWithCarrierConfigUids(); // Set test override with EMPTY rule mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(""); mTestableLooper.processAllMessages(); // Expect no package will have privilege at last verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of( new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS), new Pair<>(Set.of(), new int[0]))); // Set test override with null rule to revoke previous test override mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null); mTestableLooper.processAllMessages(); // Expect all privileges from Carrier Config come back verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS))); } @Test public void testSetCarrierTestOverrideWithNonEmptyRule() throws Exception { // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from UICC setupCarrierPrivilegesTrackerWithSimLoadedUids(); // Set test override with non-EMPTY rule (PACKAGE_3) mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(getHash(CERT_3)); mTestableLooper.processAllMessages(); // Expect only PACKAGE_3 will have privilege at last verifyRegistrantUpdates(new int[]{UID_3}, 1 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of( new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS), new Pair<>(Set.of(PACKAGE_3), new int[]{UID_3}))); // Set test override with null rule to revoke previous test override mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null); mTestableLooper.processAllMessages(); // Expect all privileges from UICC come back verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS))); } private void sendCarrierConfigChangedIntent(int subId, int phoneId) { mContext.sendBroadcast( new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED) Loading Loading
src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java +83 −21 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY; import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading Loading @@ -134,6 +135,12 @@ public class CarrierPrivilegesTracker extends Handler { */ private static final int ACTION_INITIALIZE_TRACKER = 7; /** * Action to set the test override rule through {@link TelephonyManager#setCarrierTestOverride}. * obj: String of the carrierPrivilegeRules from method setCarrierTestOverride. */ private static final int ACTION_SET_TEST_OVERRIDE_RULE = 8; private final Context mContext; private final Phone mPhone; private final PackageManager mPackageManager; Loading @@ -148,6 +155,11 @@ public class CarrierPrivilegesTracker extends Handler { private final List<UiccAccessRule> mCarrierConfigRules = new ArrayList<>(); // Stores rules for SIM-loaded rules. private final List<UiccAccessRule> mUiccRules = new ArrayList<>(); // Stores rule from test override (through TelephonyManager#setCarrierTestOverride). // - Null list indicates no test override (CC and UICC rules are respected) // - Empty list indicates test override to simulate no rules (CC and UICC rules are ignored) // - Non-empty list indicates test override with specific rules (CC and UICC rules are ignored) @Nullable private List<UiccAccessRule> mTestOverrideRules = null; // Map of PackageName -> Certificate hashes for that Package private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>(); // Map of PackageName -> UIDs for that Package Loading Loading @@ -328,6 +340,11 @@ public class CarrierPrivilegesTracker extends Handler { handleInitializeTracker(); break; } case ACTION_SET_TEST_OVERRIDE_RULE: { String carrierPrivilegeRules = (String) msg.obj; handleSetTestOverrideRules(carrierPrivilegeRules); break; } default: { Rlog.e(TAG, "Received unknown msg type: " + msg.what); break; Loading Loading @@ -478,19 +495,7 @@ public class CarrierPrivilegesTracker extends Handler { mUiccRules.addAll(getSimRules()); // Cache all installed packages and their certs int flags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.GET_SIGNING_CERTIFICATES; List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser( flags, UserHandle.SYSTEM.getIdentifier()); for (PackageInfo pkg : installedPackages) { updateCertsForPackage(pkg); // We shouldn't have any events coming in before initialization, but invalidate the // cache just in case to ensure consistency. getUidsForPackage(pkg.packageName, /* invalidateCache= */ true); } refreshInstalledPackageCache(); // Okay because no registrants exist yet maybeUpdatePrivilegedPackagesAndNotifyRegistrants(); Loading @@ -508,6 +513,22 @@ public class CarrierPrivilegesTracker extends Handler { mLocalLog.log(msg); } private void refreshInstalledPackageCache() { int flags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.GET_SIGNING_CERTIFICATES; List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser( flags, UserHandle.SYSTEM.getIdentifier()); for (PackageInfo pkg : installedPackages) { updateCertsForPackage(pkg); // This may be unnecessary before initialization, but invalidate the cache all the time // just in case to ensure consistency. getUidsForPackage(pkg.packageName, /* invalidateCache= */ true); } } private static <T> String getObfuscatedPackages( Collection<T> packageNames, Function<T, String> obfuscator) { StringJoiner obfuscated = new StringJoiner(", ", "{", "}"); Loading Loading @@ -576,13 +597,21 @@ public class CarrierPrivilegesTracker extends Handler { /** * Returns true iff there is an overlap between the provided certificate hashes and the * certificate hashes stored in mCarrierConfigRules and mUiccRules. * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules. */ private boolean isPackagePrivileged(String pkgName, Set<String> certs) { // Double-nested for loops, but each collection should contain at most 2 elements in nearly // every case. // TODO(b/184382310) find a way to speed this up for (String cert : certs) { // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules if (mTestOverrideRules != null) { for (UiccAccessRule rule : mTestOverrideRules) { if (rule.matches(cert, pkgName)) { return true; } } } else { for (UiccAccessRule rule : mCarrierConfigRules) { if (rule.matches(cert, pkgName)) { return true; Loading @@ -594,6 +623,7 @@ public class CarrierPrivilegesTracker extends Handler { } } } } return false; } Loading Loading @@ -635,6 +665,7 @@ public class CarrierPrivilegesTracker extends Handler { } finally { mPrivilegedPackageInfoLock.readLock().unlock(); } pw.println("CarrierPrivilegesTracker - Test-override rules: " + mTestOverrideRules); pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules); pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules); if (VDBG) { Loading Loading @@ -671,4 +702,35 @@ public class CarrierPrivilegesTracker extends Handler { public void unregisterCarrierPrivilegesListener(Handler handler) { sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler)); } /** * Set test carrier privilege rules which will override the actual rules on both Carrier Config * and SIM. * * <p>{@code carrierPrivilegeRules} can be null, in which case the rules on the Carrier Config * and SIM will be used and any previous overrides will be cleared. * * @see TelephonyManager#setCarrierTestOverride */ public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) { sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules)); } private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) { if (carrierPrivilegeRules == null) { mTestOverrideRules = null; } else if (carrierPrivilegeRules.isEmpty()) { mTestOverrideRules = Collections.emptyList(); } else { mTestOverrideRules = Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig( new String[]{carrierPrivilegeRules})); // TODO(b/215239409): remove the additional cache refresh for test override cases. // Test override doesn't respect if the package for the specified cert has been removed // or hidden since initialization. Refresh the cache again to get the pkg/uid with the // best effort. refreshInstalledPackageCache(); } maybeUpdatePrivilegedPackagesAndNotifyRegistrants(); } }
tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java +66 −4 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { private static final String PACKAGE_1 = "android.test.package1"; private static final String PACKAGE_2 = "android.test.package2"; private static final String PACKAGE_3 = "android.test.package3"; private static final Set<String> PRIVILEGED_PACKAGES = Set.of(PACKAGE_1, PACKAGE_2); private static final String CERT_1 = "11223344"; Loading @@ -100,6 +101,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { private static final int UID_1 = 10000001; private static final int UID_2 = 10000002; private static final int UID_3 = 10000003; private static final int[] PRIVILEGED_UIDS = {UID_1, UID_2}; private static final int PM_FLAGS = Loading Loading @@ -187,6 +189,11 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { .thenReturn(installedPackages); } private void setupInstalledPackagesWithFlags(int flags, PackageCertInfo... pkgCertInfos) throws Exception { } /** * Creates and returns a CarrierPrivilegesTracker instance. * Loading @@ -213,7 +220,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2))); setupInstalledPackages( new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1), new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2)); new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2), new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3)); mCarrierPrivilegesTracker = createCarrierPrivilegesTracker(); } Loading @@ -221,7 +229,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2))); setupInstalledPackages( new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1), new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2)); new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2), new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3)); mCarrierPrivilegesTracker = createCarrierPrivilegesTracker(); } Loading Loading @@ -660,6 +669,59 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest { verifyCarrierPrivilegesChangedUpdates(List.of()); } @Test public void testSetCarrierTestOverrideWithEmptyRule() throws Exception { // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from CarrierConfig setupCarrierPrivilegesTrackerWithCarrierConfigUids(); // Set test override with EMPTY rule mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(""); mTestableLooper.processAllMessages(); // Expect no package will have privilege at last verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of( new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS), new Pair<>(Set.of(), new int[0]))); // Set test override with null rule to revoke previous test override mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null); mTestableLooper.processAllMessages(); // Expect all privileges from Carrier Config come back verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS))); } @Test public void testSetCarrierTestOverrideWithNonEmptyRule() throws Exception { // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from UICC setupCarrierPrivilegesTrackerWithSimLoadedUids(); // Set test override with non-EMPTY rule (PACKAGE_3) mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(getHash(CERT_3)); mTestableLooper.processAllMessages(); // Expect only PACKAGE_3 will have privilege at last verifyRegistrantUpdates(new int[]{UID_3}, 1 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of( new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS), new Pair<>(Set.of(PACKAGE_3), new int[]{UID_3}))); // Set test override with null rule to revoke previous test override mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null); mTestableLooper.processAllMessages(); // Expect all privileges from UICC come back verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */); verifyCarrierPrivilegesChangedUpdates( List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS))); } private void sendCarrierConfigChangedIntent(int subId, int phoneId) { mContext.sendBroadcast( new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED) Loading