From c27b674e3858f7032f4c5c77f682d44588f98881 Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Thu, 6 Oct 2022 17:15:04 +0800 Subject: [PATCH 1/2] [MEP] the user can't enable the psim when revmovable esim is enabled The isRemovableSimEnabled method at ToggleSubscriptionDialogActivity UI is for psim, not esim. It should skip the revmovable esim slot. Bug: 251384644 Test: build pass. atest UiccSlotUtilTest Change-Id: I11d0f9528961ec5e47cd8682cf9b6bb988a5700f --- .../settings/network/UiccSlotUtil.java | 27 +++- .../ToggleSubscriptionDialogActivity.java | 16 +- .../settings/network/UiccSlotUtilTest.java | 144 ++++++++++++++++++ 3 files changed, 171 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java index 7ba2e0f8ed0..6c1dad7dab8 100644 --- a/src/com/android/settings/network/UiccSlotUtil.java +++ b/src/com/android/settings/network/UiccSlotUtil.java @@ -28,7 +28,6 @@ import android.telephony.UiccSlotMapping; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.telephony.uicc.UiccController; import com.android.settingslib.utils.ThreadUtils; import com.google.common.collect.ImmutableList; @@ -270,6 +269,7 @@ public class UiccSlotUtil { if (slotId == INVALID_PHYSICAL_SLOT_ID) { for (int i = 0; i < slots.length; i++) { if (slots[i].isRemovable() + && !slots[i].getIsEuicc() && !slots[i].getPorts().stream().findFirst().get().isActive() && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_ERROR && slots[i].getCardStateInfo() != UiccSlotInfo.CARD_STATE_INFO_RESTRICTED) { @@ -410,4 +410,29 @@ public class UiccSlotUtil { .findFirst() .orElse(INVALID_LOGICAL_SLOT_ID); } + + /** + * Return whether the removable psim is enabled. + * + * @param telMgr is a TelephonyManager. + * @return whether the removable psim is enabled. + */ + public static boolean isRemovableSimEnabled(TelephonyManager telMgr) { + if (telMgr == null) { + return false; + } + ImmutableList slotInfos = UiccSlotUtil.getSlotInfos(telMgr); + boolean isRemovableSimEnabled = + slotInfos.stream() + .anyMatch( + slot -> slot != null + && slot.isRemovable() + && !slot.getIsEuicc() + && slot.getPorts().stream().anyMatch( + port -> port.isActive()) + && slot.getCardStateInfo() + == UiccSlotInfo.CARD_STATE_INFO_PRESENT); + Log.i(TAG, "isRemovableSimEnabled: " + isRemovableSimEnabled); + return isRemovableSimEnabled; + } } diff --git a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java index a878cb3ebd3..6fa803d0433 100644 --- a/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java +++ b/src/com/android/settings/network/telephony/ToggleSubscriptionDialogActivity.java @@ -24,7 +24,6 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; -import android.telephony.UiccSlotInfo; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -39,8 +38,6 @@ import com.android.settings.network.SwitchToRemovableSlotSidecar; import com.android.settings.network.UiccSlotUtil; import com.android.settings.sim.SimActivationNotifier; -import com.google.common.collect.ImmutableList; - import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -586,18 +583,7 @@ public class ToggleSubscriptionDialogActivity extends SubscriptionActionDialogAc } private boolean isRemovableSimEnabled() { - ImmutableList slotInfos = UiccSlotUtil.getSlotInfos(mTelMgr); - boolean isRemovableSimEnabled = - slotInfos.stream() - .anyMatch( - slot -> slot != null - && slot.isRemovable() - && slot.getPorts().stream().anyMatch( - port -> port.isActive()) - && slot.getCardStateInfo() - == UiccSlotInfo.CARD_STATE_INFO_PRESENT); - Log.i(TAG, "isRemovableSimEnabled: " + isRemovableSimEnabled); - return isRemovableSimEnabled; + return UiccSlotUtil.isRemovableSimEnabled(mTelMgr); } private boolean isMultipleEnabledProfilesSupported() { diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java index 526fc0c8d18..887f3004618 100644 --- a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java +++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java @@ -632,6 +632,106 @@ public class UiccSlotUtilTest { assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex); } + @Test + public void isRemovableSimEnabled_noPsim_returnsFalse() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + oneSimSlotDeviceActiveEsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isFalse(); + } + + @Test + public void isRemovableSimEnabled_activeRemovableEsimAndInactivePsim_returnsFalse() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceActiveRemovableEsimInactivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isFalse(); + } + + @Test + public void isRemovableSimEnabled_activeRemovableEsimAndActivePsim_returnsTrue() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceActivePsimActiveRemovableEsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isTrue(); + } + + @Test + public void isRemovableSimEnabled_inactiveRemovableEsimAndActivePsim_returnsTrue() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceInactiveRemovableEsimActivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isTrue(); + } + + @Test + public void isRemovableSimEnabled_twoActiveRemovableEsimsAndInactivePsim_returnsFalse() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceTwoActiveRemovableEsimsInactivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isFalse(); + } + + @Test + public void isRemovableSimEnabled_oneActiveOneInactiveRemovableEsimActivePsim_returnsTrue() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceOneActiveOneInactiveRemovableEsimsActivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isTrue(); + } + + @Test + public void isRemovableSimEnabled_activePsim_returnsTrue() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + oneSimSlotDeviceActivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isTrue(); + } + + @Test + public void isRemovableSimEnabled_inactivePsim_returnsFalse() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + oneSimSlotDeviceinactivePsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isFalse(); + } + + @Test + public void isRemovableSimEnabled_activeEsimAndActivePsim_returnsTrue() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceActivePsimActiveEsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isTrue(); + } + + @Test + public void isRemovableSimEnabled_activeEsimAndInactivePsim_returnsFalse() { + when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( + twoSimSlotsDeviceInactivePsimActiveEsim()); + + boolean testSlot = UiccSlotUtil.isRemovableSimEnabled(mTelephonyManager); + + assertThat(testSlot).isFalse(); + } + private void compareTwoUiccSlotMappings(Collection testUiccSlotMappings, Collection verifyUiccSlotMappings) { assertThat(testUiccSlotMappings.size()).isEqualTo(verifyUiccSlotMappings.size()); @@ -786,6 +886,10 @@ public class UiccSlotUtilTest { return new UiccSlotInfo[]{createUiccSlotInfo(true, false, 1, true)}; } + private UiccSlotInfo[] oneSimSlotDeviceinactivePsim() { + return new UiccSlotInfo[]{createUiccSlotInfo(false, true, -1, false)}; + } + private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveEsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(false, true, 0, true), @@ -804,6 +908,30 @@ public class UiccSlotUtilTest { createUiccSlotInfo(true, true, 1, true)}; } + private UiccSlotInfo[] twoSimSlotsDeviceActiveRemovableEsimInactivePsim() { + return new UiccSlotInfo[]{ + createUiccSlotInfo(true, true, 0, true), + createUiccSlotInfo(false, true, -1, false)}; + } + + private UiccSlotInfo[] twoSimSlotsDeviceInactiveRemovableEsimActivePsim() { + return new UiccSlotInfo[]{ + createUiccSlotInfo(true, true, -1, false), + createUiccSlotInfo(false, true, 0, true)}; + } + + private UiccSlotInfo[] twoSimSlotsDeviceTwoActiveRemovableEsimsInactivePsim() { + return new UiccSlotInfo[]{ + createUiccSlotInfoForRemovableEsimMep(0, true, 1, true), + createUiccSlotInfo(false, true, -1, false)}; + } + + private UiccSlotInfo[] twoSimSlotsDeviceOneActiveOneInactiveRemovableEsimsActivePsim() { + return new UiccSlotInfo[]{ + createUiccSlotInfoForRemovableEsimMep(1, true, -1, false), + createUiccSlotInfo(false, true, 0, true)}; + } + private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActivePsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(true, false, 0, true), @@ -866,4 +994,20 @@ public class UiccSlotUtilTest { logicalSlotIdx2 /* logicalSlotIdx */, isActiveEsim2 /* isActive */))); } + + private UiccSlotInfo createUiccSlotInfoForRemovableEsimMep(int logicalSlotIdx1, + boolean isActiveEsim1, int logicalSlotIdx2, boolean isActiveEsim2) { + return new UiccSlotInfo( + true, /* isEuicc */ + "123", /* cardId */ + CARD_STATE_INFO_PRESENT, /* cardStateInfo */ + true, /* isExtendApduSupported */ + true, /* isRemovable */ + Arrays.asList( + new UiccPortInfo("" /* iccId */, 0 /* portIdx */, + logicalSlotIdx1 /* logicalSlotIdx */, isActiveEsim1 /* isActive */), + new UiccPortInfo("" /* iccId */, 1 /* portIdx */, + logicalSlotIdx2 /* logicalSlotIdx */, + isActiveEsim2 /* isActive */))); + } } From 51f838ba4bc4bdac61419c71fc9e6ff2f470341e Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Mon, 17 Oct 2022 22:14:34 -0400 Subject: [PATCH 2/2] Update dream summary when dream suppressed by bedtime mode Bug: 246472225 Test: enabled bedtime mode, verified settings summary updated Test: make -j64 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.dream.WhenToDreamPreferenceControllerTest" Change-Id: I4de12f636975b1bdf36898f7a530fde2f55644d4 --- res/values/strings.xml | 2 + .../ScreenSaverPreferenceController.java | 11 +++- .../WhenToDreamPreferenceController.java | 22 +++++++- .../WhenToDreamPreferenceControllerTest.java | 55 ++++++++++++++++--- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 458f6fc40d1..818689d0fc4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3359,6 +3359,8 @@ Screen saver screensaver + + Unavailable because bedtime mode is on Use screen saver diff --git a/src/com/android/settings/display/ScreenSaverPreferenceController.java b/src/com/android/settings/display/ScreenSaverPreferenceController.java index 676a567f202..de1aaea0bd8 100644 --- a/src/com/android/settings/display/ScreenSaverPreferenceController.java +++ b/src/com/android/settings/display/ScreenSaverPreferenceController.java @@ -18,6 +18,7 @@ import android.os.UserManager; import androidx.preference.Preference; +import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dream.DreamSettings; import com.android.settingslib.core.AbstractPreferenceController; @@ -26,9 +27,12 @@ public class ScreenSaverPreferenceController extends AbstractPreferenceControlle PreferenceControllerMixin { private static final String KEY_SCREEN_SAVER = "screensaver"; + private final boolean mDreamsDisabledByAmbientModeSuppression; public ScreenSaverPreferenceController(Context context) { super(context); + mDreamsDisabledByAmbientModeSuppression = context.getResources().getBoolean( + com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig); } @Override @@ -47,7 +51,12 @@ public class ScreenSaverPreferenceController extends AbstractPreferenceControlle @Override public void updateState(Preference preference) { - preference.setSummary(DreamSettings.getSummaryTextWithDreamName(mContext)); + if (mDreamsDisabledByAmbientModeSuppression + && AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime(mContext)) { + preference.setSummary(R.string.screensaver_settings_when_to_dream_bedtime); + } else { + preference.setSummary(DreamSettings.getSummaryTextWithDreamName(mContext)); + } } private boolean isSystemUser() { diff --git a/src/com/android/settings/dream/WhenToDreamPreferenceController.java b/src/com/android/settings/dream/WhenToDreamPreferenceController.java index 4108e850538..02ae6a75f39 100644 --- a/src/com/android/settings/dream/WhenToDreamPreferenceController.java +++ b/src/com/android/settings/dream/WhenToDreamPreferenceController.java @@ -20,7 +20,10 @@ import android.content.Context; import androidx.preference.Preference; +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.dream.DreamBackend; @@ -29,19 +32,34 @@ public class WhenToDreamPreferenceController extends AbstractPreferenceControlle private static final String WHEN_TO_START = "when_to_start"; private final DreamBackend mBackend; + private final boolean mDreamsDisabledByAmbientModeSuppression; WhenToDreamPreferenceController(Context context) { + this(context, context.getResources().getBoolean( + com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig)); + } + + @VisibleForTesting + WhenToDreamPreferenceController(Context context, + boolean dreamsDisabledByAmbientModeSuppression) { super(context); mBackend = DreamBackend.getInstance(context); + mDreamsDisabledByAmbientModeSuppression = dreamsDisabledByAmbientModeSuppression; } @Override public void updateState(Preference preference) { super.updateState(preference); - int resId = DreamSettings.getDreamSettingDescriptionResId(mBackend.getWhenToDreamSetting()); - preference.setSummary(preference.getContext().getString(resId)); + if (mDreamsDisabledByAmbientModeSuppression + && AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime(mContext)) { + preference.setSummary(R.string.screensaver_settings_when_to_dream_bedtime); + } else { + final int resId = DreamSettings.getDreamSettingDescriptionResId( + mBackend.getWhenToDreamSetting()); + preference.setSummary(resId); + } } @Override diff --git a/tests/robotests/src/com/android/settings/dream/WhenToDreamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/dream/WhenToDreamPreferenceControllerTest.java index 3305cded8ad..458c5c6ceee 100644 --- a/tests/robotests/src/com/android/settings/dream/WhenToDreamPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/dream/WhenToDreamPreferenceControllerTest.java @@ -16,15 +16,24 @@ package com.android.settings.dream; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; 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.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.PowerManager; import androidx.preference.Preference; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; +import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController; import com.android.settingslib.dream.DreamBackend; import com.android.settingslib.dream.DreamBackend.WhenToDream; @@ -38,32 +47,64 @@ import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class WhenToDreamPreferenceControllerTest { + private static final String TEST_PACKAGE = "com.android.test"; private WhenToDreamPreferenceController mController; private Context mContext; @Mock private DreamBackend mBackend; + @Mock + private PowerManager mPowerManager; + @Mock + private PackageManager mPackageManager; + @Mock + private ApplicationInfo mApplicationInfo; @Before - public void setup() { + public void setup() throws Exception { MockitoAnnotations.initMocks(this); - mContext = ApplicationProvider.getApplicationContext(); - mController = new WhenToDreamPreferenceController(mContext); + mContext = spy(ApplicationProvider.getApplicationContext()); + mController = new WhenToDreamPreferenceController(mContext, true); ReflectionHelpers.setField(mController, "mBackend", mBackend); + when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager); + when(mPowerManager.isAmbientDisplaySuppressedForTokenByApp(anyString(), anyInt())) + .thenReturn(false); + + mApplicationInfo.uid = 1; + when(mContext.getString( + com.android.internal.R.string.config_defaultWellbeingPackage)).thenReturn( + TEST_PACKAGE); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mPackageManager.getApplicationInfo(TEST_PACKAGE, /* flag= */ 0)).thenReturn( + mApplicationInfo); } @Test - public void updateSummary() { + public void testUpdateSummary() { // Don't have to test the other settings because DreamSettings tests that all // @WhenToDream values map to the correct ResId final @WhenToDream int testSetting = DreamBackend.WHILE_CHARGING; final Preference mockPref = mock(Preference.class); when(mockPref.getContext()).thenReturn(mContext); when(mBackend.getWhenToDreamSetting()).thenReturn(testSetting); - final String expectedString = - mContext.getString(DreamSettings.getDreamSettingDescriptionResId(testSetting)); + final int expectedResId = DreamSettings.getDreamSettingDescriptionResId(testSetting); mController.updateState(mockPref); - verify(mockPref).setSummary(expectedString); + verify(mockPref).setSummary(expectedResId); + } + + @Test + public void testBedtimeModeSuppression() { + final Preference mockPref = mock(Preference.class); + when(mockPref.getContext()).thenReturn(mContext); + when(mBackend.getWhenToDreamSetting()).thenReturn(DreamBackend.WHILE_CHARGING); + when(mPowerManager.isAmbientDisplaySuppressedForTokenByApp(anyString(), anyInt())) + .thenReturn(true); + + assertTrue(AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime(mContext)); + + mController.updateState(mockPref); + verify(mockPref).setSummary(R.string.screensaver_settings_when_to_dream_bedtime); } }