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

Commit 7a714456 authored by Bonian Chen's avatar Bonian Chen
Browse files

[Settings] Support of Primary IMEI feature

Present primary IMEI information when there're multiple.

Bug: 260188417
Test: local

Change-Id: I7817fed506f8fc4fabd94f004c9a74b2fab25e10
parent 8d13ea9e
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -2470,7 +2470,9 @@
    <!-- About phone, title of EID for multi-sim devices -->
    <string name="eid_multi_sim">EID (sim slot <xliff:g id="eid_slot_id">%1$d</xliff:g>)</string>
    <!-- About phone screen, title for IMEI for multi-sim devices -->
    <string name="imei_multi_sim">IMEI (sim slot %1$d)</string>
    <string name="imei_multi_sim">IMEI (sim slot <xliff:g id="imei_slot_id">%1$d</xliff:g>)</string>
    <!-- About phone screen, title for primary IMEI for multi-sim devices -->
    <string name="imei_multi_sim_primary">IMEI (sim slot <xliff:g id="imei_slot_id_primary">%1$d</xliff:g>) (primary)</string>
    <!-- About phone screen, summary of the MAC address [CHAR LIMIT=80] -->
    <string name="view_saved_network">To view, choose saved network</string>
    <!-- Do not translate. About phone, status item title -->
@@ -2486,7 +2488,9 @@
    <!-- About phone, status item title.  The phone PRL Version of the current device.-->
    <string name="status_prl_version">PRL version</string>
    <!-- About phone screen, title for MEID for multi-sim devices -->
    <string name="meid_multi_sim">MEID (sim slot %1$d)</string>
    <string name="meid_multi_sim">MEID (sim slot <xliff:g id="meid_slot_id">%1$d</xliff:g>)</string>
    <!-- About phone screen, title for primary MEID for multi-sim devices -->
    <string name="meid_multi_sim_primary">MEID (sim slot <xliff:g id="meid_slot_id_primary">%1$d</xliff:g>) (primary)</string>
    <!-- About phone, status item title.  The phone MEID number of the current LTE/CDMA device. [CHAR LIMIT=30] -->
    <string name="status_meid_number">MEID</string>
    <!-- About phone, status item title.  The ICCID of the current LTE device. [CHAR LIMIT=30] -->
+16 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

@SearchIndexable
public class MyDeviceInfoFragment extends DashboardFragment
@@ -79,7 +80,6 @@ public class MyDeviceInfoFragment extends DashboardFragment
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        use(ImeiInfoPreferenceController.class).setHost(this /* parent */);
        use(DeviceNamePreferenceController.class).setHost(this /* parent */);
        mBuildNumberPreferenceController = use(BuildNumberPreferenceController.class);
        mBuildNumberPreferenceController.setHost(this /* parent */);
@@ -126,12 +126,27 @@ public class MyDeviceInfoFragment extends DashboardFragment
        controllers.add(new FccEquipmentIdPreferenceController(context));
        controllers.add(new UptimePreferenceController(context, lifecycle));

        Consumer<String> imeiInfoList = imeiKey -> {
            ImeiInfoPreferenceController imeiRecord =
                    new ImeiInfoPreferenceController(context, imeiKey);
            imeiRecord.init(fragment, slotSimStatus);
            controllers.add(imeiRecord);
        };

        if (fragment != null) {
            imeiInfoList.accept(ImeiInfoPreferenceController.DEFAULT_KEY);
        }

        for (int slotIndex = 0; slotIndex < slotSimStatus.size(); slotIndex ++) {
            SimStatusPreferenceController slotRecord =
                    new SimStatusPreferenceController(context,
                    slotSimStatus.getPreferenceKey(slotIndex));
            slotRecord.init(fragment, slotSimStatus);
            controllers.add(slotRecord);

            if (fragment != null) {
                imeiInfoList.accept(ImeiInfoPreferenceController.DEFAULT_KEY + (1 + slotIndex));
            }
        }

        EidStatus eidStatus = new EidStatus(slotSimStatus, context, executor);
+80 −49
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.UserManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
@@ -33,70 +34,80 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.deviceinfo.PhoneNumberSummaryPreference;
import com.android.settings.deviceinfo.simstatus.SlotSimStatus;
import com.android.settings.network.SubscriptionUtil;
import com.android.settingslib.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Controller that manages preference for single and multi sim devices.
 */
public class ImeiInfoPreferenceController extends BasePreferenceController {

    private static final String TAG = "ImeiInfoPreferenceController";

    private static final String KEY_PREFERENCE_CATEGORY = "device_detail_category";
    public static final String DEFAULT_KEY = "imei_info";

    private final boolean mIsMultiSim;
    private final TelephonyManager mTelephonyManager;
    private final List<Preference> mPreferenceList = new ArrayList<>();
    private TelephonyManager mTelephonyManager;
    private Fragment mFragment;
    private SlotSimStatus mSlotSimStatus;

    public ImeiInfoPreferenceController(Context context, String key) {
        super(context, key);
        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        mIsMultiSim = mTelephonyManager.getPhoneCount() > 1;
    }

    public void setHost(Fragment fragment) {
    public void init(Fragment fragment, SlotSimStatus slotSimStatus) {
        mFragment = fragment;
        mSlotSimStatus = slotSimStatus;
    }

    private boolean isMultiSim() {
        return (mSlotSimStatus != null) && (mSlotSimStatus.size() > 1);
    }

    private int keyToSlotIndex(String key) {
        int simSlot = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
        try {
            simSlot = Integer.valueOf(key.replace(DEFAULT_KEY, "")) - 1;
        } catch (Exception exception) {
            Log.i(TAG, "Invalid key : " + key);
        }
        return simSlot;
    }

    private SubscriptionInfo getSubscriptionInfo(int simSlot) {
        return (mSlotSimStatus == null) ? null : mSlotSimStatus.getSubscriptionInfo(simSlot);
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        if (!SubscriptionUtil.isSimHardwareVisible(mContext)) {
        if ((!SubscriptionUtil.isSimHardwareVisible(mContext)) || (mSlotSimStatus == null)) {
            return;
        }
        final Preference preference = screen.findPreference(getPreferenceKey());
        final PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY);
        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
        Preference preference = screen.findPreference(DEFAULT_KEY);
        if (!isAvailable() || preference == null || !preference.isVisible()) {
            return;
        }
        PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY);

        mPreferenceList.add(preference);
        updatePreference(preference, 0 /* simSlot */);
        int imeiPreferenceOrder = preference.getOrder();
        screen.removePreference(preference);
        preference.setVisible(false);

        final int imeiPreferenceOrder = preference.getOrder();
        // Add additional preferences for each sim in the device
        for (int simSlotNumber = 1; simSlotNumber < mTelephonyManager.getPhoneCount();
                simSlotNumber++) {
            final Preference multiSimPreference = createNewPreference(screen.getContext());
            multiSimPreference.setCopyingEnabled(true);
            multiSimPreference.setOrder(imeiPreferenceOrder + simSlotNumber);
            multiSimPreference.setKey(getPreferenceKey() + simSlotNumber);
            category.addPreference(multiSimPreference);
            mPreferenceList.add(multiSimPreference);
            updatePreference(multiSimPreference, simSlotNumber);
        // Add additional preferences for each imei slot in the device
        for (int simSlotNumber = 0; simSlotNumber < mSlotSimStatus.size(); simSlotNumber++) {
            Preference multiImeiPreference = createNewPreference(screen.getContext());
            multiImeiPreference.setOrder(imeiPreferenceOrder + 1 + simSlotNumber);
            multiImeiPreference.setKey(DEFAULT_KEY + (1 + simSlotNumber));
            category.addPreference(multiImeiPreference);
       }
    }

    @Override
    public void updateState(Preference preference) {
        if (preference == null) {
            return;
        }
        int size = mPreferenceList.size();
        for (int i = 0; i < size; i++) {
            Preference pref = mPreferenceList.get(i);
            updatePreference(pref, i);
        }
        updatePreference(preference, keyToSlotIndex(preference.getKey()));
    }

    @Override
@@ -112,8 +123,8 @@ public class ImeiInfoPreferenceController extends BasePreferenceController {

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        final int simSlot = mPreferenceList.indexOf(preference);
        if (simSlot == -1) {
        final int simSlot = keyToSlotIndex(preference.getKey());
        if (simSlot < 0) {
            return false;
        }

@@ -124,9 +135,10 @@ public class ImeiInfoPreferenceController extends BasePreferenceController {

    @Override
    public int getAvailabilityStatus() {
        return SubscriptionUtil.isSimHardwareVisible(mContext) &&
                mContext.getSystemService(UserManager.class).isAdminUser()
                && !Utils.isWifiOnly(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
        boolean isAvailable = SubscriptionUtil.isSimHardwareVisible(mContext) &&
                mContext.getSystemService(UserManager.class).isAdminUser() &&
                !Utils.isWifiOnly(mContext);
        return isAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }

    @Override
@@ -135,29 +147,48 @@ public class ImeiInfoPreferenceController extends BasePreferenceController {
    }

    private void updatePreference(Preference preference, int simSlot) {
        SubscriptionInfo subInfo = getSubscriptionInfo(simSlot);
        preference.setEnabled(subInfo != null);
        preference.setCopyingEnabled(subInfo != null);
        preference.setTitle(getTitle(simSlot));
        preference.setSummary(getSummary());
    }

    private CharSequence getTitleForGsmPhone(int simSlot) {
        return mIsMultiSim ? mContext.getString(R.string.imei_multi_sim, simSlot + 1)
    private CharSequence getTitleForGsmPhone(int simSlot, boolean isPrimaryImei) {
        int titleId = isPrimaryImei ? R.string.imei_multi_sim_primary : R.string.imei_multi_sim;
        return isMultiSim() ? mContext.getString(titleId, simSlot + 1)
                : mContext.getString(R.string.status_imei);
    }

    private CharSequence getTitleForCdmaPhone(int simSlot) {
        return mIsMultiSim ? mContext.getString(R.string.meid_multi_sim, simSlot + 1)
    private CharSequence getTitleForCdmaPhone(int simSlot, boolean isPrimaryImei) {
        int titleId = isPrimaryImei ? R.string.meid_multi_sim_primary : R.string.meid_multi_sim;
        return isMultiSim() ? mContext.getString(titleId, simSlot + 1)
                : mContext.getString(R.string.status_meid_number);
    }

    protected boolean isPrimaryImei(int simSlot) {
        CharSequence imei = getSummary(simSlot);
        if (imei == null) {
            return false;
        }
        String primaryImei = null;
        try {
            primaryImei = mTelephonyManager.getPrimaryImei();
        } catch (Exception exception) {
            Log.i(TAG, "PrimaryImei not available. " + exception);
        }
        return (primaryImei != null) && primaryImei.equals(imei.toString());
    }

    private CharSequence getTitle(int simSlot) {
        boolean isPrimaryImei = isMultiSim() && isPrimaryImei(simSlot);
        final int phoneType = getPhoneType(simSlot);
        return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot)
                : getTitleForGsmPhone(simSlot);
        return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot, isPrimaryImei)
                : getTitleForGsmPhone(simSlot, isPrimaryImei);
    }

    private int getPhoneType(int slotIndex) {
        SubscriptionInfo subInfo = SubscriptionManager.from(mContext)
                .getActiveSubscriptionInfoForSimSlotIndex(slotIndex);
    public int getPhoneType(int slotIndex) {
        SubscriptionInfo subInfo = getSubscriptionInfo(slotIndex);
        return mTelephonyManager.getCurrentPhoneType(subInfo != null ? subInfo.getSubscriptionId()
                : SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
    }
+66 −39
Original line number Diff line number Diff line
@@ -18,10 +18,9 @@ package com.android.settings.deviceinfo.imei;

import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
import static android.telephony.TelephonyManager.PHONE_TYPE_GSM;

import static android.telephony.TelephonyManager.PHONE_TYPE_NONE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -32,15 +31,13 @@ import android.content.Context;
import android.content.res.Resources;
import android.os.UserManager;
import android.telephony.TelephonyManager;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;

import com.android.settings.deviceinfo.simstatus.SlotSimStatus;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -50,7 +47,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;

@RunWith(RobolectricTestRunner.class)
public class ImeiInfoPreferenceControllerTest {
@@ -72,7 +68,9 @@ public class ImeiInfoPreferenceControllerTest {

    private Context mContext;
    private Resources mResources;
    private ImeiInfoPreferenceController mDefaultController;
    private ImeiInfoPreferenceController mController;
    private ImeiInfoPreferenceController mSecondController;

    @Before
    public void setUp() {
@@ -83,56 +81,77 @@ public class ImeiInfoPreferenceControllerTest {
        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(true);

        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
        mController = spy(new ImeiInfoPreferenceController(mContext, "imei_info"));
        mController.setHost(mFragment);
        doReturn(AVAILABLE).when(mController).getAvailabilityStatus();
        mockService(Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager);
        mockService(Context.USER_SERVICE, UserManager.class, mUserManager);

        when(mScreen.getContext()).thenReturn(mContext);
        doReturn(mSecondSimPreference).when(mController).createNewPreference(mContext);
        final String categoryKey = "device_detail_category";
        when(mScreen.findPreference(categoryKey)).thenReturn(mCategory);
        ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
        final String prefKey = mController.getPreferenceKey();
        when(mPreference.getKey()).thenReturn(prefKey);
        when(mPreference.isVisible()).thenReturn(true);
    }

    private ImeiInfoPreferenceController createPreferenceController(SlotSimStatus slotSimStatus,
        String key, Preference preference, int phoneType) {
        ImeiInfoPreferenceController controller =
                spy(new ImeiInfoPreferenceController(mContext, key) {
                    public int getPhoneType(int slotId) {
                        return phoneType;
                    }
                });
        controller.init(mFragment, slotSimStatus);
        doReturn(AVAILABLE).when(controller).getAvailabilityStatus();
        doReturn(preference).when(controller).createNewPreference(mContext);

        when(mScreen.findPreference(key)).thenReturn(preference);
        when(preference.getKey()).thenReturn(key);
        when(preference.isVisible()).thenReturn(true);
        return controller;
    }

    private void setupPhoneCount(int count, int phoneType1, int phoneType2) {
        when(mTelephonyManager.getPhoneCount()).thenReturn(count);

        SlotSimStatus slotSimStatus = new SlotSimStatus(mContext);
        mController = createPreferenceController(slotSimStatus,
                "imei_info1", mPreference, phoneType1);
        mSecondController = createPreferenceController(slotSimStatus,
                "imei_info2", mSecondSimPreference, phoneType2);
    }

    @Ignore
    @Test
    public void displayPreference_multiSimGsm_shouldAddSecondPreference() {
        ReflectionHelpers.setField(mController, "mIsMultiSim", true);
        when(mTelephonyManager.getPhoneCount()).thenReturn(2);
        when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_GSM);
        setupPhoneCount(2, PHONE_TYPE_GSM, PHONE_TYPE_GSM);

        mController.displayPreference(mScreen);
        mDefaultController.displayPreference(mScreen);

        verify(mCategory).addPreference(mSecondSimPreference);
    }

    @Ignore
    @Test
    public void displayPreference_singleSimCdmaPhone_shouldSetSingleSimCdmaTitleAndMeid() {
        ReflectionHelpers.setField(mController, "mIsMultiSim", false);
        final String meid = "125132215123";
        when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_CDMA);
        setupPhoneCount(1, PHONE_TYPE_CDMA, PHONE_TYPE_NONE);

        final String meid = "Tap to show info";
        when(mTelephonyManager.getMeid(anyInt())).thenReturn(meid);

        mController.displayPreference(mScreen);
        mController.updateState(mPreference);

        verify(mPreference).setTitle(mContext.getString(R.string.status_meid_number));
        verify(mPreference).setSummary(meid);
    }

    @Ignore
    @Test
    public void displayPreference_multiSimCdmaPhone_shouldSetMultiSimCdmaTitleAndMeid() {
        ReflectionHelpers.setField(mController, "mIsMultiSim", true);
        final String meid = "125132215123";
        when(mTelephonyManager.getPhoneCount()).thenReturn(2);
        when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_CDMA);
        setupPhoneCount(2, PHONE_TYPE_CDMA, PHONE_TYPE_CDMA);

        final String meid = "Tap to show info";
        when(mTelephonyManager.getMeid(anyInt())).thenReturn(meid);

        mController.displayPreference(mScreen);
        mController.updateState(mPreference);
        mSecondController.displayPreference(mScreen);
        mSecondController.updateState(mSecondSimPreference);

        verify(mPreference).setTitle(mContext.getString(R.string.meid_multi_sim, 1 /* sim slot */));
        verify(mSecondSimPreference).setTitle(
@@ -141,30 +160,31 @@ public class ImeiInfoPreferenceControllerTest {
        verify(mSecondSimPreference).setSummary(meid);
    }

    @Ignore
    @Test
    public void displayPreference_singleSimGsmPhone_shouldSetSingleSimGsmTitleAndImei() {
        ReflectionHelpers.setField(mController, "mIsMultiSim", false);
        final String imei = "125132215123";
        when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_GSM);
        setupPhoneCount(1, PHONE_TYPE_GSM, PHONE_TYPE_NONE);

        final String imei = "Tap to show info";
        when(mTelephonyManager.getImei(anyInt())).thenReturn(imei);

        mController.displayPreference(mScreen);
        mController.updateState(mPreference);

        verify(mPreference).setTitle(mContext.getString(R.string.status_imei));
        verify(mPreference).setSummary(imei);
    }

    @Ignore
    @Test
    public void displayPreference_multiSimGsmPhone_shouldSetMultiSimGsmTitleAndImei() {
        ReflectionHelpers.setField(mController, "mIsMultiSim", true);
        final String imei = "125132215123";
        when(mTelephonyManager.getPhoneCount()).thenReturn(2);
        when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_GSM);
        setupPhoneCount(2, PHONE_TYPE_GSM, PHONE_TYPE_GSM);

        final String imei = "Tap to show info";
        when(mTelephonyManager.getImei(anyInt())).thenReturn(imei);

        mController.displayPreference(mScreen);
        mController.updateState(mPreference);
        mSecondController.displayPreference(mScreen);
        mSecondController.updateState(mSecondSimPreference);

        verify(mPreference).setTitle(mContext.getString(R.string.imei_multi_sim, 1 /* sim slot */));
        verify(mSecondSimPreference).setTitle(
@@ -175,6 +195,8 @@ public class ImeiInfoPreferenceControllerTest {

    @Test
    public void handlePreferenceTreeClick_shouldStartDialogFragment() {
        setupPhoneCount(1, PHONE_TYPE_GSM, PHONE_TYPE_NONE);

        when(mFragment.getChildFragmentManager())
                .thenReturn(mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
        when(mPreference.getTitle()).thenReturn("SomeTitle");
@@ -184,4 +206,9 @@ public class ImeiInfoPreferenceControllerTest {

        verify(mFragment).getChildFragmentManager();
    }

    private <T> void mockService(String serviceName, Class<T> serviceClass, T service) {
        when(mContext.getSystemServiceName(serviceClass)).thenReturn(serviceName);
        when(mContext.getSystemService(serviceName)).thenReturn(service);
    }
}