diff --git a/res/values/strings.xml b/res/values/strings.xml index 9d3bf70010e..18cd6bf6af4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2452,7 +2452,9 @@ EID (sim slot %1$d) - IMEI (sim slot %1$d) + IMEI (sim slot %1$d) + + IMEI (sim slot %1$d) (primary) To view, choose saved network @@ -2468,7 +2470,9 @@ PRL version - MEID (sim slot %1$d) + MEID (sim slot %1$d) + + MEID (sim slot %1$d) (primary) MEID diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java index 991ad25a457..5e5e2abce82 100644 --- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java @@ -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 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); diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java index a5019f896cf..13c5989a1dd 100644 --- a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java +++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java @@ -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 KEY_PREFERENCE_CATEGORY = "device_detail_category"; + private static final String TAG = "ImeiInfoPreferenceController"; - private final boolean mIsMultiSim; - private final TelephonyManager mTelephonyManager; - private final List mPreferenceList = new ArrayList<>(); + private static final String KEY_PREFERENCE_CATEGORY = "device_detail_category"; + public static final String DEFAULT_KEY = "imei_info"; + + 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); - - mPreferenceList.add(preference); - updatePreference(preference, 0 /* simSlot */); - - 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); + 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); + + int imeiPreferenceOrder = preference.getOrder(); + screen.removePreference(preference); + preference.setVisible(false); + + // 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); } - private CharSequence getTitle(int simSlot) { - final int phoneType = getPhoneType(simSlot); - return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot) - : getTitleForGsmPhone(simSlot); + 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 int getPhoneType(int slotIndex) { - SubscriptionInfo subInfo = SubscriptionManager.from(mContext) - .getActiveSubscriptionInfoForSimSlotIndex(slotIndex); + private CharSequence getTitle(int simSlot) { + boolean isPrimaryImei = isMultiSim() && isPrimaryImei(simSlot); + final int phoneType = getPhoneType(simSlot); + return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot, isPrimaryImei) + : getTitleForGsmPhone(simSlot, isPrimaryImei); + } + + public int getPhoneType(int slotIndex) { + SubscriptionInfo subInfo = getSubscriptionInfo(slotIndex); return mTelephonyManager.getCurrentPhoneType(subInfo != null ? subInfo.getSubscriptionId() : SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerTest.java index f7970cf9ce8..f3a935820ac 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerTest.java @@ -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); } - @Test - public void displayPreference_multiSimGsm_shouldAddSecondPreference() { - ReflectionHelpers.setField(mController, "mIsMultiSim", true); - when(mTelephonyManager.getPhoneCount()).thenReturn(2); - when(mTelephonyManager.getCurrentPhoneType(anyInt())).thenReturn(PHONE_TYPE_GSM); + 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); - mController.displayPreference(mScreen); + when(mScreen.findPreference(key)).thenReturn(preference); + when(preference.getKey()).thenReturn(key); + when(preference.isVisible()).thenReturn(true); + return controller; + } - verify(mCategory).addPreference(mSecondSimPreference); + 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() { + setupPhoneCount(2, PHONE_TYPE_GSM, PHONE_TYPE_GSM); + + mDefaultController.displayPreference(mScreen); + + verify(mCategory).addPreference(mSecondSimPreference); + } + @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 void mockService(String serviceName, Class serviceClass, T service) { + when(mContext.getSystemServiceName(serviceClass)).thenReturn(serviceName); + when(mContext.getSystemService(serviceName)).thenReturn(service); + } }