Loading src/com/android/settings/network/apn/ApnEditor.java +25 −5 Original line number Diff line number Diff line Loading @@ -78,7 +78,8 @@ public class ApnEditor extends SettingsPreferenceFragment private static final String KEY_MVNO_TYPE = "mvno_type"; private static final String KEY_PASSWORD = "apn_password"; private static final int MENU_DELETE = Menu.FIRST; @VisibleForTesting static final int MENU_DELETE = Menu.FIRST; private static final int MENU_SAVE = Menu.FIRST + 1; private static final int MENU_CANCEL = Menu.FIRST + 2; Loading Loading @@ -148,6 +149,17 @@ public class ApnEditor extends SettingsPreferenceFragment String mDefaultApnRoamingProtocol; private String[] mReadOnlyApnFields; private boolean mReadOnlyApn; /** * The APN deletion feature within menu is aligned with the APN adding feature. * Having only one of them could lead to a UX which not that make sense from user's * perspective. * * mIsAddApnAllowed stores the configuration value reading from * CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL to support the presentation * control of the menu options. When false, delete option would be invisible to * the end user. */ private boolean mIsAddApnAllowed; private Uri mCarrierUri; private boolean mIsCarrierIdApn; Loading Loading @@ -282,7 +294,7 @@ public class ApnEditor extends SettingsPreferenceFragment SubscriptionManager.INVALID_SUBSCRIPTION_ID); initApnEditorUi(); getCarrierCustomizedConfig(); getCarrierCustomizedConfig(getContext()); Uri uri = null; if (action.equals(Intent.ACTION_EDIT)) { Loading Loading @@ -826,7 +838,8 @@ public class ApnEditor extends SettingsPreferenceFragment public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); // If it's a new APN, then cancel will delete the new entry in onPause if (!mNewApn && !mReadOnlyApn) { // If APN add is not allowed, delete might lead to issue regarding recovery if (!mNewApn && !mReadOnlyApn && mIsAddApnAllowed) { menu.add(0, MENU_DELETE, 0, R.string.menu_delete) .setIcon(R.drawable.ic_delete); } Loading Loading @@ -1319,13 +1332,15 @@ public class ApnEditor extends SettingsPreferenceFragment mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data"); } private void getCarrierCustomizedConfig() { @VisibleForTesting protected void getCarrierCustomizedConfig(Context context) { mReadOnlyApn = false; mReadOnlyApnTypes = null; mReadOnlyApnFields = null; mIsAddApnAllowed = true; final CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager != null) { final PersistableBundle b = configManager.getConfigForSubId(mSubId); if (b != null) { Loading Loading @@ -1357,6 +1372,11 @@ public class ApnEditor extends SettingsPreferenceFragment Log.d(TAG, "onCreate: default apn roaming protocol: " + mDefaultApnRoamingProtocol); } mIsAddApnAllowed = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL); if (!mIsAddApnAllowed) { Log.d(TAG, "onCreate: not allow to add new APN"); } } } } Loading tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java +25 −5 Original line number Diff line number Diff line Loading @@ -17,14 +17,15 @@ package com.android.settings.network.apn; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.ContentResolver; Loading @@ -34,22 +35,21 @@ import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import androidx.fragment.app.FragmentActivity; import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.MultiSelectListPreference; import androidx.preference.SwitchPreference; import com.android.settings.R; import com.android.settings.network.ProxySubscriptionManager; import com.android.settings.network.apn.ApnEditor.ApnData; import com.android.settings.testutils.shadow.ShadowFragment; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -103,13 +103,15 @@ public class ApnEditorTest { private FragmentActivity mActivity; @Mock private ProxySubscriptionManager mProxySubscriptionMgr; @Mock private CarrierConfigManager mCarrierConfigManager; @Captor private ArgumentCaptor<Uri> mUriCaptor; private ApnEditor mApnEditorUT; private Context mContext; private Resources mResources; private PersistableBundle mBundle = new PersistableBundle(); @Before public void setUp() { Loading @@ -127,6 +129,10 @@ public class ApnEditorTest { doReturn(mContext.getTheme()).when(mActivity).getTheme(); doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver(); doReturn(mCarrierConfigManager).when(mContext) .getSystemService(Context.CARRIER_CONFIG_SERVICE); doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); setMockPreference(mContext); mApnEditorUT.mApnData = new FakeApnData(APN_DATA); mApnEditorUT.sNotSet = "Not Set"; Loading Loading @@ -379,6 +385,20 @@ public class ApnEditorTest { verify(mApnEditorUT).finish(); } @Test public void testDeleteApnData_shouldNotPresentMenuWhenNotSupportAdding() { mBundle.putBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL, false); MenuItem item = Mockito.mock(MenuItem.class); Menu menu = Mockito.mock(Menu.class); doReturn(item).when(menu).add(anyInt(), anyInt(), anyInt(), anyInt()); mApnEditorUT.getCarrierCustomizedConfig(mContext); mApnEditorUT.onCreateOptionsMenu(menu, null); verify(menu, times(0)).add(anyInt(), eq(ApnEditor.MENU_DELETE), anyInt(), anyInt()); } @Test(expected = ClassCastException.class) public void testApnData_invalidIntegerType_throwsInvalidTypeException() { // GIVEN a ApnData constructed from cursor Loading Loading
src/com/android/settings/network/apn/ApnEditor.java +25 −5 Original line number Diff line number Diff line Loading @@ -78,7 +78,8 @@ public class ApnEditor extends SettingsPreferenceFragment private static final String KEY_MVNO_TYPE = "mvno_type"; private static final String KEY_PASSWORD = "apn_password"; private static final int MENU_DELETE = Menu.FIRST; @VisibleForTesting static final int MENU_DELETE = Menu.FIRST; private static final int MENU_SAVE = Menu.FIRST + 1; private static final int MENU_CANCEL = Menu.FIRST + 2; Loading Loading @@ -148,6 +149,17 @@ public class ApnEditor extends SettingsPreferenceFragment String mDefaultApnRoamingProtocol; private String[] mReadOnlyApnFields; private boolean mReadOnlyApn; /** * The APN deletion feature within menu is aligned with the APN adding feature. * Having only one of them could lead to a UX which not that make sense from user's * perspective. * * mIsAddApnAllowed stores the configuration value reading from * CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL to support the presentation * control of the menu options. When false, delete option would be invisible to * the end user. */ private boolean mIsAddApnAllowed; private Uri mCarrierUri; private boolean mIsCarrierIdApn; Loading Loading @@ -282,7 +294,7 @@ public class ApnEditor extends SettingsPreferenceFragment SubscriptionManager.INVALID_SUBSCRIPTION_ID); initApnEditorUi(); getCarrierCustomizedConfig(); getCarrierCustomizedConfig(getContext()); Uri uri = null; if (action.equals(Intent.ACTION_EDIT)) { Loading Loading @@ -826,7 +838,8 @@ public class ApnEditor extends SettingsPreferenceFragment public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); // If it's a new APN, then cancel will delete the new entry in onPause if (!mNewApn && !mReadOnlyApn) { // If APN add is not allowed, delete might lead to issue regarding recovery if (!mNewApn && !mReadOnlyApn && mIsAddApnAllowed) { menu.add(0, MENU_DELETE, 0, R.string.menu_delete) .setIcon(R.drawable.ic_delete); } Loading Loading @@ -1319,13 +1332,15 @@ public class ApnEditor extends SettingsPreferenceFragment mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data"); } private void getCarrierCustomizedConfig() { @VisibleForTesting protected void getCarrierCustomizedConfig(Context context) { mReadOnlyApn = false; mReadOnlyApnTypes = null; mReadOnlyApnFields = null; mIsAddApnAllowed = true; final CarrierConfigManager configManager = (CarrierConfigManager) getSystemService(Context.CARRIER_CONFIG_SERVICE); context.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager != null) { final PersistableBundle b = configManager.getConfigForSubId(mSubId); if (b != null) { Loading Loading @@ -1357,6 +1372,11 @@ public class ApnEditor extends SettingsPreferenceFragment Log.d(TAG, "onCreate: default apn roaming protocol: " + mDefaultApnRoamingProtocol); } mIsAddApnAllowed = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL); if (!mIsAddApnAllowed) { Log.d(TAG, "onCreate: not allow to add new APN"); } } } } Loading
tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java +25 −5 Original line number Diff line number Diff line Loading @@ -17,14 +17,15 @@ package com.android.settings.network.apn; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.ContentResolver; Loading @@ -34,22 +35,21 @@ import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import androidx.fragment.app.FragmentActivity; import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.MultiSelectListPreference; import androidx.preference.SwitchPreference; import com.android.settings.R; import com.android.settings.network.ProxySubscriptionManager; import com.android.settings.network.apn.ApnEditor.ApnData; import com.android.settings.testutils.shadow.ShadowFragment; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -103,13 +103,15 @@ public class ApnEditorTest { private FragmentActivity mActivity; @Mock private ProxySubscriptionManager mProxySubscriptionMgr; @Mock private CarrierConfigManager mCarrierConfigManager; @Captor private ArgumentCaptor<Uri> mUriCaptor; private ApnEditor mApnEditorUT; private Context mContext; private Resources mResources; private PersistableBundle mBundle = new PersistableBundle(); @Before public void setUp() { Loading @@ -127,6 +129,10 @@ public class ApnEditorTest { doReturn(mContext.getTheme()).when(mActivity).getTheme(); doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver(); doReturn(mCarrierConfigManager).when(mContext) .getSystemService(Context.CARRIER_CONFIG_SERVICE); doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt()); setMockPreference(mContext); mApnEditorUT.mApnData = new FakeApnData(APN_DATA); mApnEditorUT.sNotSet = "Not Set"; Loading Loading @@ -379,6 +385,20 @@ public class ApnEditorTest { verify(mApnEditorUT).finish(); } @Test public void testDeleteApnData_shouldNotPresentMenuWhenNotSupportAdding() { mBundle.putBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL, false); MenuItem item = Mockito.mock(MenuItem.class); Menu menu = Mockito.mock(Menu.class); doReturn(item).when(menu).add(anyInt(), anyInt(), anyInt(), anyInt()); mApnEditorUT.getCarrierCustomizedConfig(mContext); mApnEditorUT.onCreateOptionsMenu(menu, null); verify(menu, times(0)).add(anyInt(), eq(ApnEditor.MENU_DELETE), anyInt(), anyInt()); } @Test(expected = ClassCastException.class) public void testApnData_invalidIntegerType_throwsInvalidTypeException() { // GIVEN a ApnData constructed from cursor Loading