Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9324b48 authored by Bonian Chen's avatar Bonian Chen Committed by Gerrit Code Review
Browse files

Merge "[Settings] Replacing accessing of PhoneConstants$DataState"

parents 9c79dfb4 8845af8a
Loading
Loading
Loading
Loading
+44 −26
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Telephony;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.PreciseDataConnectionState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -52,8 +54,6 @@ import android.widget.Toast;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;

import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -107,6 +107,7 @@ public class ApnSettings extends RestrictedSettingsFragment
    private static boolean mRestoreDefaultApnMode;

    private UserManager mUserManager;
    private TelephonyManager mTelephonyManager;
    private RestoreApnUiHandler mRestoreApnUiHandler;
    private RestoreApnProcessHandler mRestoreApnProcessHandler;
    private HandlerThread mRestoreDefaultApnThread;
@@ -130,32 +131,35 @@ public class ApnSettings extends RestrictedSettingsFragment
        super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(
                    TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
                PhoneConstants.DataState state = getMobileDataState(intent);
                switch (state) {
                case CONNECTED:
        public void onPreciseDataConnectionStateChanged(
                PreciseDataConnectionState dataConnectionState) {
            if (dataConnectionState.getState() == TelephonyManager.DATA_CONNECTED) {
                if (!mRestoreDefaultApnMode) {
                    fillList();
                } else {
                    showDialog(DIALOG_RESTORE_DEFAULTAPN);
                }
                    break;
            }
            } else if(intent.getAction().equals(
        }
    };

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(
                    TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED)) {
                if (!mRestoreDefaultApnMode) {
                    int extraSubId = intent.getIntExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID,
                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
                    if (SubscriptionManager.isValidSubscriptionId(extraSubId) &&
                            mPhoneId == SubscriptionManager.getPhoneId(extraSubId) &&
                            extraSubId != mSubId) {
                    if (SubscriptionManager.isValidSubscriptionId(extraSubId)
                            && mPhoneId == SubscriptionUtil.getPhoneId(context, extraSubId)
                            && extraSubId != mSubId) {
                        // subscription has changed
                        mSubId = extraSubId;
                        mSubscriptionInfo = getSubscriptionInfo(mSubId);
                        restartPhoneStateListener(mSubId);
                    }
                    fillList();
                }
@@ -163,13 +167,22 @@ public class ApnSettings extends RestrictedSettingsFragment
        }
    };

    private static PhoneConstants.DataState getMobileDataState(Intent intent) {
        String str = intent.getStringExtra(PhoneConstants.STATE_KEY);
        if (str != null) {
            return Enum.valueOf(PhoneConstants.DataState.class, str);
        } else {
            return PhoneConstants.DataState.DISCONNECTED;
    private void restartPhoneStateListener(int subId) {
        if (mRestoreDefaultApnMode) {
            return;
        }

        final TelephonyManager updatedTelephonyManager =
                mTelephonyManager.createForSubscriptionId(subId);

        // restart monitoring when subscription has been changed
        mTelephonyManager.listen(mPhoneStateListener,
                PhoneStateListener.LISTEN_NONE);

        mTelephonyManager = updatedTelephonyManager;

        mTelephonyManager.listen(mPhoneStateListener,
                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE);
    }

    @Override
@@ -183,14 +196,14 @@ public class ApnSettings extends RestrictedSettingsFragment
        final Activity activity = getActivity();
        mSubId = activity.getIntent().getIntExtra(SUB_ID,
                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        mPhoneId = SubscriptionManager.getPhoneId(mSubId);
        mPhoneId = SubscriptionUtil.getPhoneId(activity, mSubId);
        mIntentFilter = new IntentFilter(
                TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
        mIntentFilter.addAction(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
                TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);

        setIfOnlyAvailableForAdmins(true);

        mSubscriptionInfo = getSubscriptionInfo(mSubId);
        mTelephonyManager = activity.getSystemService(TelephonyManager.class);

        CarrierConfigManager configManager = (CarrierConfigManager)
                getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -235,6 +248,8 @@ public class ApnSettings extends RestrictedSettingsFragment

        getActivity().registerReceiver(mReceiver, mIntentFilter);

        restartPhoneStateListener(mSubId);

        if (!mRestoreDefaultApnMode) {
            fillList();
        }
@@ -249,6 +264,9 @@ public class ApnSettings extends RestrictedSettingsFragment
        }

        getActivity().unregisterReceiver(mReceiver);

        mTelephonyManager.listen(mPhoneStateListener,
                PhoneStateListener.LISTEN_NONE);
    }

    @Override
+185 −10
Original line number Diff line number Diff line
@@ -16,15 +16,18 @@

package com.android.settings.network;

import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;

import static com.android.internal.util.CollectionUtils.emptyIfNull;

import android.content.Context;
import android.os.ParcelUuid;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UiccSlotInfo;
import android.text.TextUtils;

import androidx.annotation.VisibleForTesting;

@@ -66,6 +69,12 @@ public class SubscriptionUtil {
                slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT;
    }

    /**
     * Get all of the subscriptions which is available to display to the user.
     *
     * @param context {@code Context}
     * @return list of {@code SubscriptionInfo}
     */
    public static List<SubscriptionInfo> getAvailableSubscriptions(Context context) {
        if (sAvailableResultsForTesting != null) {
            return sAvailableResultsForTesting;
@@ -73,12 +82,12 @@ public class SubscriptionUtil {
        final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class);
        final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);

        List<SubscriptionInfo> subscriptions =
        final List<SubscriptionInfo> subscriptions =
                new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));

        // Look for inactive but present physical SIMs that are missing from the selectable list.
        final List<UiccSlotInfo> missing = new ArrayList<>();
        UiccSlotInfo[] slotsInfo =  telMgr.getUiccSlotsInfo();
        final UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo();
        for (int i = 0; slotsInfo != null && i < slotsInfo.length; i++) {
            final UiccSlotInfo slotInfo = slotsInfo[i];
            if (isInactiveInsertedPSim(slotInfo)) {
@@ -92,20 +101,164 @@ public class SubscriptionUtil {
                }
            }
        }
        if (!missing.isEmpty()) {
        if (missing.isEmpty()) {
            return subscriptions;
        }
        for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
            for (UiccSlotInfo slotInfo : missing) {
                    if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() &&
                    info.getCardString().equals(slotInfo.getCardId())) {
                if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx()
                        && info.getCardString().equals(slotInfo.getCardId())) {
                    subscriptions.add(info);
                    break;
                }
            }
        }
        }
        return subscriptions;
    }

    /**
     * Get subscription which is available to be displayed to the user
     * per subscription id.
     *
     * @param context {@code Context}
     * @param subscriptionManager The ProxySubscriptionManager for accessing subcription
     *         information
     * @param subId The id of subscription to be retrieved
     * @return {@code SubscriptionInfo} based on the given subscription id. Null of subscription
     *         is invalid or not allowed to be displayed to the user.
     */
    public static SubscriptionInfo getAvailableSubscription(Context context,
            ProxySubscriptionManager subscriptionManager, int subId) {
        final SubscriptionInfo subInfo = subscriptionManager.getAccessibleSubscriptionInfo(subId);
        if (subInfo == null) {
            return null;
        }

        final ParcelUuid groupUuid = subInfo.getGroupUuid();

        if (groupUuid != null) {
            if (isPrimarySubscriptionWithinSameUuid(getUiccSlotsInfo(context), groupUuid,
                    subscriptionManager.getAccessibleSubscriptionsInfo(), subId)) {
                return subInfo;
            }
            return null;
        }

        if (subInfo.isEmbedded()) {
            return subInfo;
        }

        // Look for physical SIM which presented in slots no mater active or not.
        final UiccSlotInfo[] slotsInfo = getUiccSlotsInfo(context);
        if (slotsInfo == null) {
            return null;
        }
        for (UiccSlotInfo slotInfo : slotsInfo) {
            if ((!slotInfo.getIsEuicc())
                    && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT)
                    && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex())
                    && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) {
                return subInfo;
            }
        }
        return null;
    }

    private static UiccSlotInfo [] getUiccSlotsInfo(Context context) {
        final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
        return telMgr.getUiccSlotsInfo();
    }

    private static boolean isPrimarySubscriptionWithinSameUuid(UiccSlotInfo[] slotsInfo,
            ParcelUuid groupUuid, List<SubscriptionInfo> subscriptions, int subId) {
        // only interested in subscriptions with this group UUID
        final ArrayList<SubscriptionInfo> physicalSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> nonOpportunisticSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> activeSlotSubInfoList =
                new ArrayList<SubscriptionInfo>();
        final ArrayList<SubscriptionInfo> inactiveSlotSubInfoList =
                new ArrayList<SubscriptionInfo>();
        for (SubscriptionInfo subInfo : subscriptions) {
            if (groupUuid.equals(subInfo.getGroupUuid())) {
                if (!subInfo.isEmbedded()) {
                    physicalSubInfoList.add(subInfo);
                } else  {
                    if (!subInfo.isOpportunistic()) {
                        nonOpportunisticSubInfoList.add(subInfo);
                    }
                    if (subInfo.getSimSlotIndex()
                            != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
                        activeSlotSubInfoList.add(subInfo);
                    } else {
                        inactiveSlotSubInfoList.add(subInfo);
                    }
                }
            }
        }

        // find any physical SIM which is currently inserted within logical slot
        // and which is our target subscription
        if ((slotsInfo != null) && (physicalSubInfoList.size() > 0)) {
            final SubscriptionInfo subInfo = searchForSubscriptionId(physicalSubInfoList, subId);
            if (subInfo == null) {
                return false;
            }
            // verify if subscription is inserted within slot
            for (UiccSlotInfo slotInfo : slotsInfo) {
                if ((slotInfo != null) && (!slotInfo.getIsEuicc())
                        && (slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT)
                        && (slotInfo.getLogicalSlotIdx() == subInfo.getSimSlotIndex())
                        && TextUtils.equals(slotInfo.getCardId(), subInfo.getCardString())) {
                    return true;
                }
            }
            return false;
        }

        // When all of the eSIM profiles are opprtunistic and no physical SIM,
        // first opportunistic subscriptions with same group UUID can be primary.
        if (nonOpportunisticSubInfoList.size() <= 0) {
            if (physicalSubInfoList.size() > 0) {
                return false;
            }
            if (activeSlotSubInfoList.size() > 0) {
                return (activeSlotSubInfoList.get(0).getSubscriptionId() == subId);
            }
            return (inactiveSlotSubInfoList.get(0).getSubscriptionId() == subId);
        }

        // Allow non-opportunistic + active eSIM subscription as primary
        int numberOfActiveNonOpportunisticSubs = 0;
        boolean isTargetNonOpportunistic = false;
        for (SubscriptionInfo subInfo : nonOpportunisticSubInfoList) {
            final boolean isTargetSubInfo = (subInfo.getSubscriptionId() == subId);
            if (subInfo.getSimSlotIndex() != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
                if (isTargetSubInfo) {
                    return true;
                }
                numberOfActiveNonOpportunisticSubs++;
            } else {
                isTargetNonOpportunistic |= isTargetSubInfo;
            }
        }
        if (numberOfActiveNonOpportunisticSubs > 0) {
            return false;
        }
        return isTargetNonOpportunistic;
    }

    private static SubscriptionInfo searchForSubscriptionId(List<SubscriptionInfo> subInfoList,
            int subscriptionId) {
        for (SubscriptionInfo subInfo : subInfoList) {
            if (subInfo.getSubscriptionId() == subscriptionId) {
                return subInfo;
            }
        }
        return null;
    }

    public static String getDisplayName(SubscriptionInfo info) {
        final CharSequence name = info.getDisplayName();
        if (name != null) {
@@ -113,4 +266,26 @@ public class SubscriptionUtil {
        }
        return "";
    }

    /**
     * Whether Settings should show a "Use SIM" toggle in pSIM detailed page.
     */
    public static boolean showToggleForPhysicalSim(SubscriptionManager subMgr) {
        return subMgr.canDisablePhysicalSubscription();
    }

    /**
     * Get phoneId or logical slot index for a subId if active, or INVALID_PHONE_INDEX if inactive.
     */
    public static int getPhoneId(Context context, int subId) {
        final SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
        if (subManager == null) {
            return INVALID_SIM_SLOT_INDEX;
        }
        final SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId);
        if (info == null) {
            return INVALID_SIM_SLOT_INDEX;
        }
        return info.getSimSlotIndex();
    }
}