[Settings] Not allow APN delete when adding is not an option
When not allowing APN to add, user may not be able to recover easily when delete it. Therefore, avoid from APN to be deleted when adding is not allowed. Bug: 243664439 Bug: 200875858 Test: local, robolectric Change-Id: I5cf984000244b4ad901c6a4977a1368279323e0a
This commit is contained in:
@@ -78,7 +78,8 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
private static final String KEY_MVNO_TYPE = "mvno_type";
|
private static final String KEY_MVNO_TYPE = "mvno_type";
|
||||||
private static final String KEY_PASSWORD = "apn_password";
|
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_SAVE = Menu.FIRST + 1;
|
||||||
private static final int MENU_CANCEL = Menu.FIRST + 2;
|
private static final int MENU_CANCEL = Menu.FIRST + 2;
|
||||||
|
|
||||||
@@ -148,6 +149,17 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
String mDefaultApnRoamingProtocol;
|
String mDefaultApnRoamingProtocol;
|
||||||
private String[] mReadOnlyApnFields;
|
private String[] mReadOnlyApnFields;
|
||||||
private boolean mReadOnlyApn;
|
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 Uri mCarrierUri;
|
||||||
private boolean mIsCarrierIdApn;
|
private boolean mIsCarrierIdApn;
|
||||||
|
|
||||||
@@ -282,7 +294,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
|
||||||
initApnEditorUi();
|
initApnEditorUi();
|
||||||
getCarrierCustomizedConfig();
|
getCarrierCustomizedConfig(getContext());
|
||||||
|
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
if (action.equals(Intent.ACTION_EDIT)) {
|
if (action.equals(Intent.ACTION_EDIT)) {
|
||||||
@@ -826,7 +838,8 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
// If it's a new APN, then cancel will delete the new entry in onPause
|
// 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)
|
menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
|
||||||
.setIcon(R.drawable.ic_delete);
|
.setIcon(R.drawable.ic_delete);
|
||||||
}
|
}
|
||||||
@@ -1319,13 +1332,15 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
|
mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getCarrierCustomizedConfig() {
|
@VisibleForTesting
|
||||||
|
protected void getCarrierCustomizedConfig(Context context) {
|
||||||
mReadOnlyApn = false;
|
mReadOnlyApn = false;
|
||||||
mReadOnlyApnTypes = null;
|
mReadOnlyApnTypes = null;
|
||||||
mReadOnlyApnFields = null;
|
mReadOnlyApnFields = null;
|
||||||
|
mIsAddApnAllowed = true;
|
||||||
|
|
||||||
final CarrierConfigManager configManager = (CarrierConfigManager)
|
final CarrierConfigManager configManager = (CarrierConfigManager)
|
||||||
getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
||||||
if (configManager != null) {
|
if (configManager != null) {
|
||||||
final PersistableBundle b = configManager.getConfigForSubId(mSubId);
|
final PersistableBundle b = configManager.getConfigForSubId(mSubId);
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
@@ -1357,6 +1372,11 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
Log.d(TAG, "onCreate: default apn roaming protocol: "
|
Log.d(TAG, "onCreate: default apn roaming protocol: "
|
||||||
+ mDefaultApnRoamingProtocol);
|
+ mDefaultApnRoamingProtocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mIsAddApnAllowed = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL);
|
||||||
|
if (!mIsAddApnAllowed) {
|
||||||
|
Log.d(TAG, "onCreate: not allow to add new APN");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,14 +17,15 @@
|
|||||||
package com.android.settings.network.apn;
|
package com.android.settings.network.apn;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@@ -34,22 +35,21 @@ import android.content.Intent;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
|
import android.telephony.CarrierConfigManager;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.preference.EditTextPreference;
|
import androidx.preference.EditTextPreference;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.MultiSelectListPreference;
|
import androidx.preference.MultiSelectListPreference;
|
||||||
import androidx.preference.SwitchPreference;
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.network.ProxySubscriptionManager;
|
import com.android.settings.network.ProxySubscriptionManager;
|
||||||
import com.android.settings.network.apn.ApnEditor.ApnData;
|
import com.android.settings.network.apn.ApnEditor.ApnData;
|
||||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -103,13 +103,15 @@ public class ApnEditorTest {
|
|||||||
private FragmentActivity mActivity;
|
private FragmentActivity mActivity;
|
||||||
@Mock
|
@Mock
|
||||||
private ProxySubscriptionManager mProxySubscriptionMgr;
|
private ProxySubscriptionManager mProxySubscriptionMgr;
|
||||||
|
@Mock
|
||||||
|
private CarrierConfigManager mCarrierConfigManager;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<Uri> mUriCaptor;
|
private ArgumentCaptor<Uri> mUriCaptor;
|
||||||
|
|
||||||
private ApnEditor mApnEditorUT;
|
private ApnEditor mApnEditorUT;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
|
private PersistableBundle mBundle = new PersistableBundle();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -127,6 +129,10 @@ public class ApnEditorTest {
|
|||||||
doReturn(mContext.getTheme()).when(mActivity).getTheme();
|
doReturn(mContext.getTheme()).when(mActivity).getTheme();
|
||||||
doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
|
doReturn(mContext.getContentResolver()).when(mActivity).getContentResolver();
|
||||||
|
|
||||||
|
doReturn(mCarrierConfigManager).when(mContext)
|
||||||
|
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
||||||
|
doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
|
||||||
|
|
||||||
setMockPreference(mContext);
|
setMockPreference(mContext);
|
||||||
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
||||||
mApnEditorUT.sNotSet = "Not Set";
|
mApnEditorUT.sNotSet = "Not Set";
|
||||||
@@ -379,6 +385,20 @@ public class ApnEditorTest {
|
|||||||
verify(mApnEditorUT).finish();
|
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)
|
@Test(expected = ClassCastException.class)
|
||||||
public void testApnData_invalidIntegerType_throwsInvalidTypeException() {
|
public void testApnData_invalidIntegerType_throwsInvalidTypeException() {
|
||||||
// GIVEN a ApnData constructed from cursor
|
// GIVEN a ApnData constructed from cursor
|
||||||
|
Reference in New Issue
Block a user