From 3adafdcc8395c32317007ea116c1c6d6c6bf824d Mon Sep 17 00:00:00 2001 From: jeffreyhuang Date: Wed, 8 Nov 2017 14:43:34 -0800 Subject: [PATCH 1/3] Dynamic preferences for IMEI - Support N-sim devices for imei preference Bug: 36458278 Test: make RunSettingsRoboTests -j40 Change-Id: I0dda78b44e0c64ddd69c9a30e90c49f03b2260f3 --- res/values/strings.xml | 8 +- res/xml/device_info_settings_v2.xml | 24 +-- .../android/settings/DeviceInfoSettings.java | 9 +- .../AbstractImeiInfoPreferenceController.java | 99 ------------ .../ImeiInfoDualSimPreferenceController.java | 57 ------- .../imei/ImeiInfoPreferenceControllerV2.java | 98 ++++++++++-- ...tractImeiInfoPreferenceControllerTest.java | 143 ------------------ ...eiInfoDualSimPreferenceControllerTest.java | 89 ----------- .../ImeiInfoPreferenceControllerV2Test.java | 105 ++++++++++--- 9 files changed, 190 insertions(+), 442 deletions(-) delete mode 100644 src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceController.java delete mode 100644 src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 4582bc4797b..675bfcd43ad 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2664,9 +2664,7 @@ Unmount SD card, view available storage - IMEI (sim slot 1) - - IMEI (sim slot 2) + IMEI (sim slot %1$d) IMEI @@ -2688,9 +2686,7 @@ PRL version - MEID (sim slot 1) - - MEID (sim slot 2) + MEID (sim slot %1$d) MEID diff --git a/res/xml/device_info_settings_v2.xml b/res/xml/device_info_settings_v2.xml index 5957c1adca2..77ead2c5f16 100644 --- a/res/xml/device_info_settings_v2.xml +++ b/res/xml/device_info_settings_v2.xml @@ -25,18 +25,21 @@ @@ -44,32 +47,29 @@ - + - - - @@ -77,12 +77,14 @@ @@ -90,6 +92,7 @@ @@ -97,6 +100,7 @@ @@ -104,6 +108,7 @@ @@ -111,6 +116,7 @@ diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java index 5c266454e7e..f4939f6c3b2 100644 --- a/src/com/android/settings/DeviceInfoSettings.java +++ b/src/com/android/settings/DeviceInfoSettings.java @@ -34,17 +34,16 @@ import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController; import com.android.settings.deviceinfo.FeedbackPreferenceController; import com.android.settings.deviceinfo.FirmwareVersionPreferenceController; import com.android.settings.deviceinfo.IpAddressPreferenceController; -import com.android.settings.deviceinfo.WifiMacAddressPreferenceController; -import com.android.settings.deviceinfo.imei.ImeiInfoDualSimPreferenceController; -import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2; import com.android.settings.deviceinfo.KernelVersionPreferenceController; import com.android.settings.deviceinfo.ManualPreferenceController; import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController; import com.android.settings.deviceinfo.SafetyInfoPreferenceController; import com.android.settings.deviceinfo.SecurityPatchPreferenceController; +import com.android.settings.deviceinfo.WifiMacAddressPreferenceController; +import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceControllerV2; +import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2; import com.android.settings.deviceinfo.simstatus.SimStatusDualSimPreferenceController; import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceControllerV2; -import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceControllerV2; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settingslib.core.AbstractPreferenceController; @@ -140,8 +139,6 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable { controllers.add(new ImeiInfoPreferenceControllerV2(context, fragment)); - controllers.add(new ImeiInfoDualSimPreferenceController(context, fragment)); - controllers.add(new FirmwareVersionPreferenceControllerV2(context, fragment)); controllers.add(new IpAddressPreferenceController(context, lifecycle)); diff --git a/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceController.java b/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceController.java deleted file mode 100644 index a9871a0f76a..00000000000 --- a/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceController.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.imei; - -import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; - -import android.app.Fragment; -import android.content.Context; -import android.support.annotation.VisibleForTesting; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; -import android.telephony.TelephonyManager; -import android.text.TextUtils; - -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController; - -/** - * Controller that manages preference for single and dual sim devices. - */ -public abstract class AbstractImeiInfoPreferenceController extends - AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin { - - protected final boolean mIsMultiSim; - protected final TelephonyManager mTelephonyManager; - - private Preference mPreference; - private Fragment mFragment; - - public AbstractImeiInfoPreferenceController(Context context, Fragment fragment) { - super(context); - - mFragment = fragment; - mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - mIsMultiSim = mTelephonyManager.getPhoneCount() > 1; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(getPreferenceKey()); - if (mPreference == null) { - return; - } - final int phoneType = mTelephonyManager.getPhoneType(); - if (phoneType == PHONE_TYPE_CDMA) { - mPreference.setTitle(getTitleForCdmaPhone()); - mPreference.setSummary(getMeid()); - } else { - // GSM phone - mPreference.setTitle(getTitleForGsmPhone()); - mPreference.setSummary(mTelephonyManager.getImei(getSimSlot())); - } - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { - return false; - } - - ImeiInfoDialogFragment.show(mFragment, getSimSlot(), mPreference.getTitle().toString()); - return true; - } - - /** - * @return The preference title for phones based on CDMA technology. - */ - protected abstract String getTitleForCdmaPhone(); - - /** - * @return The preference title for phones based on GSM technology. - */ - protected abstract String getTitleForGsmPhone(); - - /** - * @return The sim slot to retrieve IMEI/CDMA information about. - */ - protected abstract int getSimSlot(); - - @VisibleForTesting - String getMeid() { - return mTelephonyManager.getMeid(getSimSlot()); - } -} diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceController.java deleted file mode 100644 index 61d99b966f0..00000000000 --- a/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceController.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.imei; - -import android.app.Fragment; -import android.content.Context; - -import com.android.settings.R; - -public class ImeiInfoDualSimPreferenceController extends AbstractImeiInfoPreferenceController { - - private static final String KEY_IMEI_INFO_DUAL_SIM = "imei_info_sim_slot_2"; - private static final int SIM_SLOT = 1; - - public ImeiInfoDualSimPreferenceController(Context context, Fragment fragment) { - super(context, fragment); - } - - @Override - public boolean isAvailable() { - return super.isAvailable() && mIsMultiSim; - } - - @Override - public String getPreferenceKey() { - return KEY_IMEI_INFO_DUAL_SIM; - } - - @Override - protected String getTitleForCdmaPhone() { - return mContext.getResources().getString(R.string.meid_multi_sim_sim_slot_2); - } - - @Override - protected String getTitleForGsmPhone() { - return mContext.getResources().getString(R.string.imei_multi_sim_slot_2); - } - - @Override - protected int getSimSlot() { - return SIM_SLOT; - } -} diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2.java index 74448bb123e..dcc6db6c5aa 100644 --- a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2.java +++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2.java @@ -16,19 +16,41 @@ package com.android.settings.deviceinfo.imei; +import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; + import android.app.Fragment; import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.telephony.TelephonyManager; import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController; -public class ImeiInfoPreferenceControllerV2 extends AbstractImeiInfoPreferenceController { +import java.util.ArrayList; +import java.util.List; - public static final int SIM_SLOT = 0; +/** + * Controller that manages preference for single and multi sim devices. + */ +public class ImeiInfoPreferenceControllerV2 extends + AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin { - private static final String KEY_IMEI_INFO = "imei_info_sim_slot_1"; + private static final String KEY_IMEI_INFO = "imei_info"; + + private final boolean mIsMultiSim; + private final TelephonyManager mTelephonyManager; + private final List mPreferenceList = new ArrayList<>(); + private final Fragment mFragment; public ImeiInfoPreferenceControllerV2(Context context, Fragment fragment) { - super(context, fragment); + super(context); + + mFragment = fragment; + mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + mIsMultiSim = mTelephonyManager.getPhoneCount() > 1; } @Override @@ -37,19 +59,69 @@ public class ImeiInfoPreferenceControllerV2 extends AbstractImeiInfoPreferenceCo } @Override - protected String getTitleForCdmaPhone() { - return mIsMultiSim ? mContext.getResources().getString(R.string.meid_multi_sim_sim_slot_1) - : mContext.getResources().getString(R.string.status_meid_number); + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + final Preference preference = screen.findPreference(getPreferenceKey()); + if (!isAvailable() || preference == null || !preference.isVisible()) { + return; + } + + mPreferenceList.add(preference); + updatePreference(preference, 0 /* sim slot */); + + 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.setOrder(imeiPreferenceOrder + simSlotNumber); + multiSimPreference.setKey(KEY_IMEI_INFO + simSlotNumber); + screen.addPreference(multiSimPreference); + mPreferenceList.add(multiSimPreference); + updatePreference(multiSimPreference, simSlotNumber); + } } @Override - protected String getTitleForGsmPhone() { - return mIsMultiSim ? mContext.getResources().getString(R.string.imei_multi_sim_slot_1) - : mContext.getResources().getString(R.string.status_imei); + public boolean handlePreferenceTreeClick(Preference preference) { + final int simSlot = mPreferenceList.indexOf(preference); + if (simSlot == -1) { + return false; + } + + ImeiInfoDialogFragment.show(mFragment, simSlot, preference.getTitle().toString()); + return true; } - @Override - protected int getSimSlot() { - return SIM_SLOT; + private void updatePreference(Preference preference, int simSlot) { + final int phoneType = mTelephonyManager.getPhoneType(); + if (phoneType == PHONE_TYPE_CDMA) { + preference.setTitle(getTitleForCdmaPhone(simSlot)); + preference.setSummary(getMeid(simSlot)); + } else { + // GSM phone + preference.setTitle(getTitleForGsmPhone(simSlot)); + preference.setSummary(mTelephonyManager.getImei(simSlot)); + } + } + + private CharSequence getTitleForGsmPhone(int simSlot) { + return mIsMultiSim ? mContext.getString(R.string.imei_multi_sim, simSlot + 1) + : mContext.getString(R.string.status_imei); + } + + private CharSequence getTitleForCdmaPhone(int simSlot) { + return mIsMultiSim ? mContext.getString(R.string.meid_multi_sim, simSlot + 1) + : mContext.getString(R.string.status_meid_number); + } + + @VisibleForTesting + String getMeid(int simSlot) { + return mTelephonyManager.getMeid(simSlot); + } + + @VisibleForTesting + Preference createNewPreference(Context context) { + return new Preference(context); } } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceControllerTest.java deleted file mode 100644 index 51e6005d743..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/imei/AbstractImeiInfoPreferenceControllerTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.imei; - -import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; -import static android.telephony.TelephonyManager.PHONE_TYPE_GSM; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.Context; -import android.os.UserManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; -import android.telephony.TelephonyManager; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class AbstractImeiInfoPreferenceControllerTest { - - @Mock - private Preference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private UserManager mUserManager; - @Mock - private Fragment mFragment; - - private Context mContext; - private AbstractImeiInfoPreferenceControllerImpl mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = new AbstractImeiInfoPreferenceControllerImpl(mContext, mFragment); - ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); - } - - @Test - public void displayPreference_cdmaPhone_shouldSetCdmaTitleAndMeid() { - mController = spy(mController); - final String meid = "125132215123"; - when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_CDMA); - doReturn(meid).when(mController).getMeid(); - - mController.displayPreference(mScreen); - - verify(mPreference).setTitle(mController.getTitleForCdmaPhone()); - verify(mPreference).setSummary(meid); - } - - @Test - public void displayPreference_gsmPhone_shouldSetGsmTitleAndImei() { - final String imei = "125132215123"; - when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_GSM); - when(mTelephonyManager.getImei(anyInt())).thenReturn(imei); - - mController.displayPreference(mScreen); - - verify(mPreference).setTitle(mController.getTitleForGsmPhone()); - verify(mPreference).setSummary(imei); - } - - @Test - public void handlePreferenceTreeClick_shouldStartDialogFragment() { - when(mFragment.getChildFragmentManager()).thenReturn( - mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)); - when(mPreference.getTitle()).thenReturn("SomeTitle"); - mController.displayPreference(mScreen); - - mController.handlePreferenceTreeClick(mPreference); - - verify(mFragment).getChildFragmentManager(); - } - - public class AbstractImeiInfoPreferenceControllerImpl extends - AbstractImeiInfoPreferenceController { - - public AbstractImeiInfoPreferenceControllerImpl(Context context, Fragment fragment) { - super(context, fragment); - } - - @Override - public String getPreferenceKey() { - return "foobar"; - } - - @Override - protected String getTitleForCdmaPhone() { - return "foo"; - } - - @Override - protected String getTitleForGsmPhone() { - return "bar"; - } - - @Override - protected int getSimSlot() { - return 0; - } - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceControllerTest.java deleted file mode 100644 index ce99ee4f718..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoDualSimPreferenceControllerTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.imei; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.app.Fragment; -import android.content.Context; -import android.os.UserManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; -import android.telephony.TelephonyManager; - -import com.android.settings.R; -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class ImeiInfoDualSimPreferenceControllerTest { - - @Mock - private Preference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private UserManager mUserManager; - @Mock - private Fragment mFragment; - - private Context mContext; - private ImeiInfoDualSimPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = new ImeiInfoDualSimPreferenceController(mContext, mFragment); - ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); - } - - @Test - public void getTitleForCdmaPhone_shouldReturnCdmaMultiSimString() { - ReflectionHelpers.setField(mController, "mIsMultiSim", true); - - assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString( - R.string.meid_multi_sim_sim_slot_2)); - } - - @Test - public void getTitleForGsmPhone_shouldReturnGsmMultiSimString() { - ReflectionHelpers.setField(mController, "mIsMultiSim", true); - - assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString( - R.string.imei_multi_sim_slot_2)); - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2Test.java index 233e27e77a4..3fed5890ef5 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2Test.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceControllerV2Test.java @@ -16,13 +16,19 @@ package com.android.settings.deviceinfo.imei; -import static com.google.common.truth.Truth.assertThat; +import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; +import static android.telephony.TelephonyManager.PHONE_TYPE_GSM; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Fragment; +import android.app.FragmentManager; import android.content.Context; import android.os.UserManager; import android.support.v7.preference.Preference; @@ -36,6 +42,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -49,6 +56,8 @@ public class ImeiInfoPreferenceControllerV2Test { @Mock private Preference mPreference; @Mock + private Preference mSecondSimPreference; + @Mock private PreferenceScreen mScreen; @Mock private TelephonyManager mTelephonyManager; @@ -65,41 +74,97 @@ public class ImeiInfoPreferenceControllerV2Test { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = new ImeiInfoPreferenceControllerV2(mContext, mFragment); + mController = spy(new ImeiInfoPreferenceControllerV2(mContext, mFragment)); + doReturn(true).when(mController).isAvailable(); + when(mScreen.getContext()).thenReturn(mContext); + doReturn(mSecondSimPreference).when(mController).createNewPreference(mContext); ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + final String prefKey = mController.getPreferenceKey(); + when(mPreference.getKey()).thenReturn(prefKey); + when(mPreference.isVisible()).thenReturn(true); } @Test - public void getTitleForCdmaPhone_noMultiSim_shouldReturnCdmaNoMultiSimString() { - ReflectionHelpers.setField(mController, "mIsMultiSim", false); - - assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString( - R.string.status_meid_number)); - } - - @Test - public void getTitleForCdmaPhone_multiSim_shouldReturnCdmaMultiSimString() { + public void displayPreference_multiSimGsm_shouldAddSecondPreference() { ReflectionHelpers.setField(mController, "mIsMultiSim", true); + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_GSM); - assertThat(mController.getTitleForCdmaPhone()).isEqualTo(mContext.getResources().getString( - R.string.meid_multi_sim_sim_slot_1)); + mController.displayPreference(mScreen); + + verify(mScreen).addPreference(mSecondSimPreference); } @Test - public void getTitleForGsmPhone_noMultiSim_shouldReturnGsmNoMultiSimString() { + public void displayPreference_singleSimCdmaPhone_shouldSetSingleSimCdmaTitleAndMeid() { ReflectionHelpers.setField(mController, "mIsMultiSim", false); + final String meid = "125132215123"; + when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_CDMA); + doReturn(meid).when(mController).getMeid(anyInt()); - assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString( - R.string.status_imei)); + mController.displayPreference(mScreen); + + verify(mPreference).setTitle(mContext.getString(R.string.status_meid_number)); + verify(mPreference).setSummary(meid); } @Test - public void getTitleForGsmPhone_multiSim_shouldReturnGsmMultiSimString() { + public void displayPreference_multiSimCdmaPhone_shouldSetMultiSimCdmaTitleAndMeid() { ReflectionHelpers.setField(mController, "mIsMultiSim", true); + final String meid = "125132215123"; + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_CDMA); + doReturn(meid).when(mController).getMeid(anyInt()); - assertThat(mController.getTitleForGsmPhone()).isEqualTo(mContext.getResources().getString( - R.string.imei_multi_sim_slot_1)); + mController.displayPreference(mScreen); + + verify(mPreference).setTitle(mContext.getString(R.string.meid_multi_sim, 1 /* sim slot */)); + verify(mSecondSimPreference).setTitle( + mContext.getString(R.string.meid_multi_sim, 2 /* sim slot */)); + verify(mPreference).setSummary(meid); + verify(mSecondSimPreference).setSummary(meid); + } + + @Test + public void displayPreference_singleSimGsmPhone_shouldSetSingleSimGsmTitleAndImei() { + ReflectionHelpers.setField(mController, "mIsMultiSim", false); + final String imei = "125132215123"; + when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_GSM); + when(mTelephonyManager.getImei(anyInt())).thenReturn(imei); + + mController.displayPreference(mScreen); + + verify(mPreference).setTitle(mContext.getString(R.string.status_imei)); + verify(mPreference).setSummary(imei); + } + + @Test + public void displayPreference_multiSimGsmPhone_shouldSetMultiSimGsmTitleAndImei() { + ReflectionHelpers.setField(mController, "mIsMultiSim", true); + final String imei = "125132215123"; + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + when(mTelephonyManager.getPhoneType()).thenReturn(PHONE_TYPE_GSM); + when(mTelephonyManager.getImei(anyInt())).thenReturn(imei); + + mController.displayPreference(mScreen); + + verify(mPreference).setTitle(mContext.getString(R.string.imei_multi_sim, 1 /* sim slot */)); + verify(mSecondSimPreference).setTitle( + mContext.getString(R.string.imei_multi_sim, 2 /* sim slot */)); + verify(mPreference).setSummary(imei); + verify(mSecondSimPreference).setSummary(imei); + } + + @Test + public void handlePreferenceTreeClick_shouldStartDialogFragment() { + when(mFragment.getChildFragmentManager()).thenReturn( + mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)); + when(mPreference.getTitle()).thenReturn("SomeTitle"); + mController.displayPreference(mScreen); + + mController.handlePreferenceTreeClick(mPreference); + + verify(mFragment).getChildFragmentManager(); } } From 34c2387faae46288c00abd6910205c130774daa8 Mon Sep 17 00:00:00 2001 From: jeffreyhuang Date: Wed, 8 Nov 2017 15:53:43 -0800 Subject: [PATCH 2/3] Dynamic preferences for sim status - Support N-sim devices for sim status preference Bug: 36458278 Test: make RunSettingsRoboTests -j40 Change-Id: I0cea3f765f89c30a6595631ed501ab1c0010b736 --- res/values/strings.xml | 4 +- res/xml/device_info_settings_v2.xml | 12 +- .../android/settings/DeviceInfoSettings.java | 3 - ...AbstractSimStatusPreferenceController.java | 98 --------------- .../SimStatusDualSimPreferenceController.java | 52 -------- .../SimStatusPreferenceControllerV2.java | 105 +++++++++++++--- ...ractSimStatusPreferenceControllerTest.java | 113 ------------------ ...StatusDualSimPreferenceControllerTest.java | 93 -------------- .../SimStatusPreferenceControllerV2Test.java | 66 ++++++++-- 9 files changed, 147 insertions(+), 399 deletions(-) delete mode 100644 src/com/android/settings/deviceinfo/simstatus/AbstractSimStatusPreferenceController.java delete mode 100644 src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/simstatus/AbstractSimStatusPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 675bfcd43ad..ad0550f47f9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6441,9 +6441,7 @@ SIM status - SIM status (sim slot 1) - - SIM status (sim slot 2) + SIM status (sim slot %1$d) Call back from default SIM diff --git a/res/xml/device_info_settings_v2.xml b/res/xml/device_info_settings_v2.xml index 77ead2c5f16..9a48e96b4be 100644 --- a/res/xml/device_info_settings_v2.xml +++ b/res/xml/device_info_settings_v2.xml @@ -29,21 +29,13 @@ android:title="@string/status_number" android:summary="@string/summary_placeholder"/> - + - - - - 1; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(getPreferenceKey()); - if (mPreference == null) { - return; - } - - mPreference.setTitle(getPreferenceTitle()); - mPreference.setSummary(getCarrierName()); - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { - return false; - } - - SimStatusDialogFragment.show(mFragment, getSimSlot(), getPreferenceTitle()); - return true; - } - - /** - * @return The preference title for the displayed preference. - */ - protected abstract String getPreferenceTitle(); - - /** - * @return The sim slot to retrieve sim status information about. - */ - protected abstract int getSimSlot(); - - private CharSequence getCarrierName() { - final List subscriptionInfoList = - mSubscriptionManager.getActiveSubscriptionInfoList(); - if (subscriptionInfoList != null) { - for (SubscriptionInfo info : subscriptionInfoList) { - if (info.getSimSlotIndex() == getSimSlot()) { - return info.getCarrierName(); - } - } - } - return mContext.getText(R.string.device_info_not_available); - } -} diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceController.java deleted file mode 100644 index ce73a294247..00000000000 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceController.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.simstatus; - -import android.app.Fragment; -import android.content.Context; - -import com.android.settings.R; - -public class SimStatusDualSimPreferenceController extends AbstractSimStatusPreferenceController { - - private static final int SIM_SLOT = 1; - private static final String SIM_STATUS_DUAL_SIM_KEY = "sim_status_sim_2"; - - public SimStatusDualSimPreferenceController(Context context, Fragment fragment) { - super(context, fragment); - } - - @Override - public boolean isAvailable() { - return super.isAvailable() && mIsMultiSim; - } - - @Override - protected String getPreferenceTitle() { - return mContext.getResources().getString(R.string.sim_status_title_sim_slot_2); - } - - @Override - protected int getSimSlot() { - return SIM_SLOT; - } - - @Override - public String getPreferenceKey() { - return SIM_STATUS_DUAL_SIM_KEY; - } -} diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2.java index ee16eac5bf3..55493dc3ba0 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2.java @@ -18,32 +18,107 @@ package com.android.settings.deviceinfo.simstatus; import android.app.Fragment; import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController; -public class SimStatusPreferenceControllerV2 extends AbstractSimStatusPreferenceController { +import java.util.ArrayList; +import java.util.List; - public static final int SIM_SLOT = 0; +public class SimStatusPreferenceControllerV2 extends + AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin { - private static final String KEY_SIM_1_STATUS = "sim_status_sim_1"; + private static final String KEY_SIM_STATUS = "sim_status"; + + private final TelephonyManager mTelephonyManager; + private final SubscriptionManager mSubscriptionManager; + private final Fragment mFragment; + private final List mPreferenceList = new ArrayList<>(); public SimStatusPreferenceControllerV2(Context context, Fragment fragment) { - super(context, fragment); - } + super(context); - @Override - protected String getPreferenceTitle() { - return mIsMultiSim ? mContext.getResources().getString(R.string.sim_status_title_sim_slot_1) - : mContext.getResources().getString(R.string.sim_status_title); - } - - @Override - protected int getSimSlot() { - return SIM_SLOT; + mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + mSubscriptionManager = (SubscriptionManager) context.getSystemService( + Context.TELEPHONY_SUBSCRIPTION_SERVICE); + mFragment = fragment; } @Override public String getPreferenceKey() { - return KEY_SIM_1_STATUS; + return KEY_SIM_STATUS; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + final Preference preference = screen.findPreference(getPreferenceKey()); + if (!isAvailable() || preference == null || !preference.isVisible()) { + return; + } + + mPreferenceList.add(preference); + + final int simStatusOrder = 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.setOrder(simStatusOrder + simSlotNumber); + multiSimPreference.setKey(KEY_SIM_STATUS + simSlotNumber); + screen.addPreference(multiSimPreference); + mPreferenceList.add(multiSimPreference); + } + } + + @Override + public void updateState(Preference preference) { + for (int simSlotNumber = 0; simSlotNumber < mPreferenceList.size(); simSlotNumber++) { + final Preference simStatusPreference = mPreferenceList.get(simSlotNumber); + simStatusPreference.setTitle(getPreferenceTitle(simSlotNumber /* sim slot */)); + simStatusPreference.setSummary(getCarrierName(simSlotNumber /* sim slot */)); + } + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + final int simSlot = mPreferenceList.indexOf(preference); + if (simSlot == -1) { + return false; + } + + SimStatusDialogFragment.show(mFragment, simSlot, getPreferenceTitle(simSlot)); + return true; + } + + private String getPreferenceTitle(int simSlot) { + return mTelephonyManager.getPhoneCount() > 1 ? mContext.getString( + R.string.sim_status_title_sim_slot, simSlot + 1) : mContext.getString( + R.string.sim_status_title); + } + + private CharSequence getCarrierName(int simSlot) { + final List subscriptionInfoList = + mSubscriptionManager.getActiveSubscriptionInfoList(); + if (subscriptionInfoList != null) { + for (SubscriptionInfo info : subscriptionInfoList) { + if (info.getSimSlotIndex() == simSlot) { + return info.getCarrierName(); + } + } + } + return mContext.getText(R.string.device_info_not_available); + } + + @VisibleForTesting + Preference createNewPreference(Context context) { + return new Preference(context); } } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/AbstractSimStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/AbstractSimStatusPreferenceControllerTest.java deleted file mode 100644 index ee749d085d3..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/AbstractSimStatusPreferenceControllerTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.simstatus; - -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.Context; -import android.os.UserManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class AbstractSimStatusPreferenceControllerTest { - - @Mock - private Preference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private UserManager mUserManager; - @Mock - private Fragment mFragment; - - private Context mContext; - private AbstractSimStatusPreferenceControllerImpl mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = new AbstractSimStatusPreferenceControllerImpl(mContext, mFragment); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); - } - - @Test - public void displayPreference_shouldSetTitleAndSummary() { - mController.displayPreference(mScreen); - - verify(mPreference).setTitle(mController.getPreferenceTitle()); - verify(mPreference).setSummary(anyString()); - } - - @Test - public void handlePreferenceTreeClick_shouldStartDialogFragment() { - when(mFragment.getChildFragmentManager()).thenReturn( - mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)); - when(mPreference.getTitle()).thenReturn("foo"); - mController.displayPreference(mScreen); - - mController.handlePreferenceTreeClick(mPreference); - - verify(mFragment).getChildFragmentManager(); - } - - public class AbstractSimStatusPreferenceControllerImpl extends - AbstractSimStatusPreferenceController { - - public AbstractSimStatusPreferenceControllerImpl(Context context, Fragment fragment) { - super(context, fragment); - } - - @Override - public String getPreferenceKey() { - return "foo"; - } - - @Override - protected String getPreferenceTitle() { - return "bar"; - } - - @Override - protected int getSimSlot() { - return 0; - } - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceControllerTest.java deleted file mode 100644 index 0845bfa95e9..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDualSimPreferenceControllerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo.simstatus; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.app.Fragment; -import android.content.Context; -import android.net.ConnectivityManager; -import android.os.UserManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; -import android.telephony.TelephonyManager; - -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import com.google.common.truth.Truth; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class SimStatusDualSimPreferenceControllerTest { - - @Mock - private Preference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private TelephonyManager mTelephonyManager; - @Mock - private UserManager mUserManager; - @Mock - private ConnectivityManager mConnectivityManager; - @Mock - private Fragment mFragment; - - private Context mContext; - private SimStatusDualSimPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - doReturn(mConnectivityManager).when(mContext).getSystemService(ConnectivityManager.class); - when(mUserManager.isAdminUser()).thenReturn(true); - when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn( - true); - mController = new SimStatusDualSimPreferenceController(mContext, mFragment); - ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); - } - - @Test - public void isAvailable_multiSim_shouldBeTrue() { - ReflectionHelpers.setField(mController, "mIsMultiSim", true); - - Truth.assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void isAvailable_notMultiSim_shouldBeFalse() { - ReflectionHelpers.setField(mController, "mIsMultiSim", false); - - Truth.assertThat(mController.isAvailable()).isFalse(); - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2Test.java index 3282c3c85f7..53324b579a2 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2Test.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerV2Test.java @@ -16,13 +16,16 @@ package com.android.settings.deviceinfo.simstatus; -import static com.google.common.truth.Truth.assertThat; - +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Fragment; +import android.app.FragmentManager; import android.content.Context; import android.os.UserManager; import android.support.v7.preference.Preference; @@ -31,11 +34,13 @@ import android.telephony.TelephonyManager; import com.android.settings.R; import com.android.settings.TestConfig; +import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceControllerV2; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -49,6 +54,8 @@ public class SimStatusPreferenceControllerV2Test { @Mock private Preference mPreference; @Mock + private Preference mSecondSimPreference; + @Mock private PreferenceScreen mScreen; @Mock private TelephonyManager mTelephonyManager; @@ -65,25 +72,60 @@ public class SimStatusPreferenceControllerV2Test { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = new SimStatusPreferenceControllerV2(mContext, mFragment); + mController = spy(new SimStatusPreferenceControllerV2(mContext, mFragment)); + doReturn(true).when(mController).isAvailable(); + when(mScreen.getContext()).thenReturn(mContext); + doReturn(mSecondSimPreference).when(mController).createNewPreference(mContext); ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + final String prefKey = mController.getPreferenceKey(); + when(mPreference.getKey()).thenReturn(prefKey); + when(mPreference.isVisible()).thenReturn(true); } @Test - public void getPreferenceTitle_noMultiSim_shouldReturnSingleSimString() { - ReflectionHelpers.setField(mController, "mIsMultiSim", false); + public void displayPreference_multiSim_shouldAddSecondPreference() { + when(mTelephonyManager.getPhoneCount()).thenReturn(2); - assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString( - R.string.sim_status_title)); + mController.displayPreference(mScreen); + + verify(mScreen).addPreference(mSecondSimPreference); } @Test - public void getPreferenceTitle_multiSim_shouldReturnMultiSimString() { - ReflectionHelpers.setField(mController, "mIsMultiSim", true); + public void updateState_singleSim_shouldSetSingleSimTitleAndSummary() { + when(mTelephonyManager.getPhoneCount()).thenReturn(1); + mController.displayPreference(mScreen); - assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString( - R.string.sim_status_title_sim_slot_1)); + mController.updateState(mPreference); + + verify(mPreference).setTitle(mContext.getString(R.string.sim_status_title)); + verify(mPreference).setSummary(anyString()); + } + + @Test + public void updateState_multiSim_shouldSetMultiSimTitleAndSummary() { + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + mController.displayPreference(mScreen); + + mController.updateState(mPreference); + + verify(mPreference).setTitle( + mContext.getString(R.string.sim_status_title_sim_slot, 1 /* sim slot */)); + verify(mSecondSimPreference).setTitle( + mContext.getString(R.string.sim_status_title_sim_slot, 2 /* sim slot */)); + verify(mPreference).setSummary(anyString()); + verify(mSecondSimPreference).setSummary(anyString()); + } + + @Test + public void handlePreferenceTreeClick_shouldStartDialogFragment() { + when(mFragment.getChildFragmentManager()).thenReturn( + mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)); + mController.displayPreference(mScreen); + + mController.handlePreferenceTreeClick(mPreference); + + verify(mFragment).getChildFragmentManager(); } } From ba76fbeb3b05c764f51386fa8814089d518cbcb6 Mon Sep 17 00:00:00 2001 From: jeffreyhuang Date: Thu, 9 Nov 2017 12:15:05 -0800 Subject: [PATCH 3/3] Phone number in about phone v2 - Introduce preference controller to manage phone number - Add new strings for multi sim devices Bug: 36458278 Test: make RunSettingsRoboTests -j40 Change-Id: Ibf5dc65ba67969b6eeb095b8d202ef8a5faf16ca --- res/values/strings.xml | 4 + .../android/settings/DeviceInfoSettings.java | 3 +- .../PhoneNumberPreferenceController.java | 128 ++++++++++++++++++ .../PhoneNumberPreferenceControllerTest.java | 114 ++++++++++++++++ 4 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index ad0550f47f9..de75fc7dbd7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2675,6 +2675,10 @@ MDN Phone number + + MDN (sim slot %1$d) + + Phone number (sim slot %1$d) MDN on SIM diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java index 63253da9db9..42cac986bc8 100644 --- a/src/com/android/settings/DeviceInfoSettings.java +++ b/src/com/android/settings/DeviceInfoSettings.java @@ -36,6 +36,7 @@ import com.android.settings.deviceinfo.FirmwareVersionPreferenceController; import com.android.settings.deviceinfo.IpAddressPreferenceController; import com.android.settings.deviceinfo.KernelVersionPreferenceController; import com.android.settings.deviceinfo.ManualPreferenceController; +import com.android.settings.deviceinfo.PhoneNumberPreferenceController; import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController; import com.android.settings.deviceinfo.SafetyInfoPreferenceController; import com.android.settings.deviceinfo.SecurityPatchPreferenceController; @@ -128,7 +129,7 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable { final List controllers = new ArrayList<>(); // Device name - // Phone number + controllers.add(new PhoneNumberPreferenceController(context)); controllers.add(new SimStatusPreferenceControllerV2(context, fragment)); diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java new file mode 100644 index 00000000000..5edac0fa5a9 --- /dev/null +++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo; + +import android.content.Context; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; + +import com.android.settings.R; +import com.android.settingslib.DeviceInfoUtils; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.ArrayList; +import java.util.List; + +public class PhoneNumberPreferenceController extends AbstractPreferenceController { + + private final static String KEY_PHONE_NUMBER = "phone_number"; + + private final TelephonyManager mTelephonyManager; + private final SubscriptionManager mSubscriptionManager; + private final List mPreferenceList = new ArrayList<>(); + + public PhoneNumberPreferenceController(Context context) { + super(context); + mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + mSubscriptionManager = (SubscriptionManager) context.getSystemService( + Context.TELEPHONY_SUBSCRIPTION_SERVICE); + } + + @Override + public String getPreferenceKey() { + return KEY_PHONE_NUMBER; + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + final Preference preference = screen.findPreference(getPreferenceKey()); + mPreferenceList.add(preference); + + final int phonePreferenceOrder = 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.setOrder(phonePreferenceOrder + simSlotNumber); + multiSimPreference.setKey(KEY_PHONE_NUMBER + simSlotNumber); + screen.addPreference(multiSimPreference); + mPreferenceList.add(multiSimPreference); + } + } + + @Override + public void updateState(Preference preference) { + for (int simSlotNumber = 0; simSlotNumber < mPreferenceList.size(); simSlotNumber++) { + final Preference simStatusPreference = mPreferenceList.get(simSlotNumber); + simStatusPreference.setTitle(getPreferenceTitle(simSlotNumber)); + simStatusPreference.setSummary(getPhoneNumber(simSlotNumber)); + } + } + + private CharSequence getPhoneNumber(int simSlot) { + final SubscriptionInfo subscriptionInfo = getSubscriptionInfo(simSlot); + if (subscriptionInfo == null) { + return mContext.getString(R.string.device_info_default); + } + + return getFormattedPhoneNumber(subscriptionInfo); + } + + private CharSequence getPreferenceTitle(int simSlot) { + return mTelephonyManager.getPhoneCount() > 1 ? mContext.getString( + R.string.status_number_sim_slot, simSlot + 1) : mContext.getString( + R.string.status_number); + } + + @VisibleForTesting + SubscriptionInfo getSubscriptionInfo(int simSlot) { + final List subscriptionInfoList = + mSubscriptionManager.getActiveSubscriptionInfoList(); + if (subscriptionInfoList != null) { + for (SubscriptionInfo info : subscriptionInfoList) { + if (info.getSimSlotIndex() == simSlot) { + return info; + } + } + } + return null; + } + + @VisibleForTesting + CharSequence getFormattedPhoneNumber(SubscriptionInfo subscriptionInfo) { + final String phoneNumber = DeviceInfoUtils.getFormattedPhoneNumber(mContext, + subscriptionInfo); + return TextUtils.isEmpty(phoneNumber) ? mContext.getString(R.string.device_info_default) + : phoneNumber; + } + + @VisibleForTesting + Preference createNewPreference(Context context) { + return new Preference(context); + } +} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java new file mode 100644 index 00000000000..37c814ab5cd --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.telephony.SubscriptionInfo; +import android.telephony.TelephonyManager; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O) +public class PhoneNumberPreferenceControllerTest { + + @Mock + private Preference mPreference; + @Mock + private Preference mSecondPreference; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private SubscriptionInfo mSubscriptionInfo; + @Mock + private PreferenceScreen mScreen; + + private Context mContext; + private PhoneNumberPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = spy(new PhoneNumberPreferenceController(mContext)); + ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); + final String prefKey = mController.getPreferenceKey(); + when(mScreen.findPreference(prefKey)).thenReturn(mPreference); + when(mScreen.getContext()).thenReturn(mContext); + doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt()); + doReturn(mSecondPreference).when(mController).createNewPreference(mContext); + when(mPreference.isVisible()).thenReturn(true); + } + + @Test + public void displayPreference_multiSim_shouldAddSecondPreference() { + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + + mController.displayPreference(mScreen); + + verify(mScreen).addPreference(mSecondPreference); + } + + @Test + public void updateState_singleSim_shouldUpdateTitleAndPhoneNumber() { + final String phoneNumber = "1111111111"; + doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo); + when(mTelephonyManager.getPhoneCount()).thenReturn(1); + mController.displayPreference(mScreen); + + mController.updateState(mPreference); + + verify(mPreference).setTitle(mContext.getString(R.string.status_number)); + verify(mPreference).setSummary(phoneNumber); + } + + @Test + public void updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() { + final String phoneNumber = "1111111111"; + doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo); + when(mTelephonyManager.getPhoneCount()).thenReturn(2); + mController.displayPreference(mScreen); + + mController.updateState(mPreference); + + verify(mPreference).setTitle( + mContext.getString(R.string.status_number_sim_slot, 1 /* sim slot */)); + verify(mPreference).setSummary(phoneNumber); + verify(mSecondPreference).setTitle( + mContext.getString(R.string.status_number_sim_slot, 2 /* sim slot */)); + verify(mSecondPreference).setSummary(phoneNumber); + } +}