Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +43 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package com.android.systemui.statusbar.policy; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; import static com.android.internal.telephony.PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -35,6 +38,7 @@ import android.os.Looper; import android.os.PersistableBundle; import android.provider.Settings; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; Loading Loading @@ -96,6 +100,16 @@ public class NetworkControllerImpl extends BroadcastReceiver private final CurrentUserTracker mUserTracker; private Config mConfig; private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mActiveMobileDataSubscription = subId; doUpdateMobileControllers(); } }; private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Subcontrollers. @VisibleForTesting final WifiSignalController mWifiSignalController; Loading Loading @@ -269,6 +283,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mSubscriptionListener = new SubListener(); } mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener); mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); // broadcasts IntentFilter filter = new IntentFilter(); Loading Loading @@ -513,6 +528,7 @@ public class NetworkControllerImpl extends BroadcastReceiver @VisibleForTesting void handleConfigurationChanged() { updateMobileControllers(); for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController controller = mMobileSignalControllers.valueAt(i); controller.setConfiguration(mConfig); Loading @@ -527,13 +543,39 @@ public class NetworkControllerImpl extends BroadcastReceiver doUpdateMobileControllers(); } private void filterMobileSubscriptionInSameGroup(List<SubscriptionInfo> subscriptions) { if (subscriptions.size() == MAX_PHONE_COUNT_DUAL_SIM) { SubscriptionInfo info1 = subscriptions.get(0); SubscriptionInfo info2 = subscriptions.get(1); if (info1.getGroupUuid() != null && info1.getGroupUuid().equals(info2.getGroupUuid())) { // If both subscriptions are primary, show both. if (!info1.isOpportunistic() && !info2.isOpportunistic()) return; // If carrier required, always show signal bar of primary subscription. // Otherwise, show whichever subscription is currently active for Internet. boolean alwaysShowPrimary = CarrierConfigManager.getDefaultConfig() .getBoolean(CarrierConfigManager .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN); if (alwaysShowPrimary) { subscriptions.remove(info1.isOpportunistic() ? info1 : info2); } else { subscriptions.remove(info1.getSubscriptionId() == mActiveMobileDataSubscription ? info2 : info1); } } } } @VisibleForTesting void doUpdateMobileControllers() { List<SubscriptionInfo> subscriptions = mSubscriptionManager .getActiveSubscriptionInfoList(true); .getActiveSubscriptionInfoList(false); if (subscriptions == null) { subscriptions = Collections.emptyList(); } filterMobileSubscriptionInSameGroup(subscriptions); // If there have been no relevant changes to any of the subscriptions, we can leave as is. if (hasCorrectMobileControllers(subscriptions)) { // Even if the controllers are correct, make sure we have the right no sims state. Loading telephony/java/android/telephony/CarrierConfigManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -2489,6 +2489,18 @@ public class CarrierConfigManager { public static final String KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY = "emergency_number_prefix_string_array"; /** * Indicates when a carrier has a primary subscription and an opportunistic subscription active, * and when Internet data is switched to opportunistic network, whether to still show * signal bar of primary network. By default it will be false, meaning whenever data * is going over opportunistic network, signal bar will reflect signal strength and rat * icon of that network. * * @hide */ public static final String KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN = "always_show_primary_signal_bar_in_opportunistic_network_boolean"; /** * Determines whether the carrier wants to cancel the cs reject notification automatically * when the voice registration state changes. Loading Loading @@ -2930,6 +2942,8 @@ public class CarrierConfigManager { "connected_mmwave:None,connected:5G,not_restricted:None,restricted:None"); sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); } /** Loading telephony/java/android/telephony/SubscriptionManager.java +16 −21 Original line number Diff line number Diff line Loading @@ -1271,7 +1271,7 @@ public class SubscriptionManager { if (!userVisibleOnly || activeList == null) { return activeList; } else { return activeList.stream().filter(subInfo -> !shouldHideSubscription(subInfo)) return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo)) .collect(Collectors.toList()); } } Loading Loading @@ -2877,32 +2877,27 @@ public class SubscriptionManager { } /** * Whether system UI should hide a subscription. If it's a bundled opportunistic * subscription, it shouldn't show up in anywhere in Settings app, dialer app, * or status bar. Exception is if caller is carrier app, in which case they will * Whether a subscription is visible to API caller. If it's a bundled opportunistic * subscription, it should be hidden anywhere in Settings, dialer, status bar etc. * Exception is if caller owns carrier privilege, in which case they will * want to see their own hidden subscriptions. * * @param info the subscriptionInfo to check against. * @return true if this subscription should be hidden. * @return true if this subscription should be visible to the API caller. * * @hide */ public boolean shouldHideSubscription(SubscriptionInfo info) { private boolean isSubscriptionVisible(SubscriptionInfo info) { if (info == null) return false; // If hasCarrierPrivileges or canManageSubscription returns true, it means caller // has carrier privilege. boolean hasCarrierPrivilegePermission = (info.isEmbedded() && canManageSubscription(info)) || TelephonyManager.from(mContext).hasCarrierPrivileges(info.getSubscriptionId()); return isInvisibleSubscription(info) && !hasCarrierPrivilegePermission; } // If subscription is NOT grouped opportunistic subscription, it's visible. if (TextUtils.isEmpty(info.getGroupUuid()) || !info.isOpportunistic()) return true; /** * @hide */ public static boolean isInvisibleSubscription(SubscriptionInfo info) { return info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic(); // If the caller is the carrier app and owns the subscription, it should be visible // to the caller. boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext) .hasCarrierPrivileges(info.getSubscriptionId()) || (info.isEmbedded() && canManageSubscription(info)); return hasCarrierPrivilegePermission; } /** Loading Loading @@ -2930,7 +2925,7 @@ public class SubscriptionManager { for (SubscriptionInfo info : availableList) { // Opportunistic subscriptions are considered invisible // to users so they should never be returned. if (isInvisibleSubscription(info)) continue; if (!isSubscriptionVisible(info)) continue; String groupUuid = info.getGroupUuid(); if (groupUuid == null) { Loading @@ -2952,7 +2947,7 @@ public class SubscriptionManager { } /** * Enabled or disable a subscription. This is currently used in the settings page. * Enables or disables a subscription. This is currently used in the settings page. * * <p> * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +43 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,9 @@ package com.android.systemui.statusbar.policy; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; import static com.android.internal.telephony.PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -35,6 +38,7 @@ import android.os.Looper; import android.os.PersistableBundle; import android.provider.Settings; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; Loading Loading @@ -96,6 +100,16 @@ public class NetworkControllerImpl extends BroadcastReceiver private final CurrentUserTracker mUserTracker; private Config mConfig; private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mActiveMobileDataSubscription = subId; doUpdateMobileControllers(); } }; private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Subcontrollers. @VisibleForTesting final WifiSignalController mWifiSignalController; Loading Loading @@ -269,6 +283,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mSubscriptionListener = new SubListener(); } mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener); mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); // broadcasts IntentFilter filter = new IntentFilter(); Loading Loading @@ -513,6 +528,7 @@ public class NetworkControllerImpl extends BroadcastReceiver @VisibleForTesting void handleConfigurationChanged() { updateMobileControllers(); for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController controller = mMobileSignalControllers.valueAt(i); controller.setConfiguration(mConfig); Loading @@ -527,13 +543,39 @@ public class NetworkControllerImpl extends BroadcastReceiver doUpdateMobileControllers(); } private void filterMobileSubscriptionInSameGroup(List<SubscriptionInfo> subscriptions) { if (subscriptions.size() == MAX_PHONE_COUNT_DUAL_SIM) { SubscriptionInfo info1 = subscriptions.get(0); SubscriptionInfo info2 = subscriptions.get(1); if (info1.getGroupUuid() != null && info1.getGroupUuid().equals(info2.getGroupUuid())) { // If both subscriptions are primary, show both. if (!info1.isOpportunistic() && !info2.isOpportunistic()) return; // If carrier required, always show signal bar of primary subscription. // Otherwise, show whichever subscription is currently active for Internet. boolean alwaysShowPrimary = CarrierConfigManager.getDefaultConfig() .getBoolean(CarrierConfigManager .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN); if (alwaysShowPrimary) { subscriptions.remove(info1.isOpportunistic() ? info1 : info2); } else { subscriptions.remove(info1.getSubscriptionId() == mActiveMobileDataSubscription ? info2 : info1); } } } } @VisibleForTesting void doUpdateMobileControllers() { List<SubscriptionInfo> subscriptions = mSubscriptionManager .getActiveSubscriptionInfoList(true); .getActiveSubscriptionInfoList(false); if (subscriptions == null) { subscriptions = Collections.emptyList(); } filterMobileSubscriptionInSameGroup(subscriptions); // If there have been no relevant changes to any of the subscriptions, we can leave as is. if (hasCorrectMobileControllers(subscriptions)) { // Even if the controllers are correct, make sure we have the right no sims state. Loading
telephony/java/android/telephony/CarrierConfigManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -2489,6 +2489,18 @@ public class CarrierConfigManager { public static final String KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY = "emergency_number_prefix_string_array"; /** * Indicates when a carrier has a primary subscription and an opportunistic subscription active, * and when Internet data is switched to opportunistic network, whether to still show * signal bar of primary network. By default it will be false, meaning whenever data * is going over opportunistic network, signal bar will reflect signal strength and rat * icon of that network. * * @hide */ public static final String KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN = "always_show_primary_signal_bar_in_opportunistic_network_boolean"; /** * Determines whether the carrier wants to cancel the cs reject notification automatically * when the voice registration state changes. Loading Loading @@ -2930,6 +2942,8 @@ public class CarrierConfigManager { "connected_mmwave:None,connected:5G,not_restricted:None,restricted:None"); sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); } /** Loading
telephony/java/android/telephony/SubscriptionManager.java +16 −21 Original line number Diff line number Diff line Loading @@ -1271,7 +1271,7 @@ public class SubscriptionManager { if (!userVisibleOnly || activeList == null) { return activeList; } else { return activeList.stream().filter(subInfo -> !shouldHideSubscription(subInfo)) return activeList.stream().filter(subInfo -> isSubscriptionVisible(subInfo)) .collect(Collectors.toList()); } } Loading Loading @@ -2877,32 +2877,27 @@ public class SubscriptionManager { } /** * Whether system UI should hide a subscription. If it's a bundled opportunistic * subscription, it shouldn't show up in anywhere in Settings app, dialer app, * or status bar. Exception is if caller is carrier app, in which case they will * Whether a subscription is visible to API caller. If it's a bundled opportunistic * subscription, it should be hidden anywhere in Settings, dialer, status bar etc. * Exception is if caller owns carrier privilege, in which case they will * want to see their own hidden subscriptions. * * @param info the subscriptionInfo to check against. * @return true if this subscription should be hidden. * @return true if this subscription should be visible to the API caller. * * @hide */ public boolean shouldHideSubscription(SubscriptionInfo info) { private boolean isSubscriptionVisible(SubscriptionInfo info) { if (info == null) return false; // If hasCarrierPrivileges or canManageSubscription returns true, it means caller // has carrier privilege. boolean hasCarrierPrivilegePermission = (info.isEmbedded() && canManageSubscription(info)) || TelephonyManager.from(mContext).hasCarrierPrivileges(info.getSubscriptionId()); return isInvisibleSubscription(info) && !hasCarrierPrivilegePermission; } // If subscription is NOT grouped opportunistic subscription, it's visible. if (TextUtils.isEmpty(info.getGroupUuid()) || !info.isOpportunistic()) return true; /** * @hide */ public static boolean isInvisibleSubscription(SubscriptionInfo info) { return info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic(); // If the caller is the carrier app and owns the subscription, it should be visible // to the caller. boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext) .hasCarrierPrivileges(info.getSubscriptionId()) || (info.isEmbedded() && canManageSubscription(info)); return hasCarrierPrivilegePermission; } /** Loading Loading @@ -2930,7 +2925,7 @@ public class SubscriptionManager { for (SubscriptionInfo info : availableList) { // Opportunistic subscriptions are considered invisible // to users so they should never be returned. if (isInvisibleSubscription(info)) continue; if (!isSubscriptionVisible(info)) continue; String groupUuid = info.getGroupUuid(); if (groupUuid == null) { Loading @@ -2952,7 +2947,7 @@ public class SubscriptionManager { } /** * Enabled or disable a subscription. This is currently used in the settings page. * Enables or disables a subscription. This is currently used in the settings page. * * <p> * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required Loading