Merge "Fixed ApnEditor issue"
This commit is contained in:
committed by
Android (Google) Code Review
commit
811a0ad404
@@ -5709,9 +5709,6 @@
|
|||||||
<string name="admin_disabled_other_options">Other options are disabled by your admin</string>
|
<string name="admin_disabled_other_options">Other options are disabled by your admin</string>
|
||||||
<string name="admin_more_details">More details</string>
|
<string name="admin_more_details">More details</string>
|
||||||
|
|
||||||
<!-- Name to assign to a Network Access Point that was saved without a name -->
|
|
||||||
<string name="untitled_apn">Untitled</string>
|
|
||||||
|
|
||||||
<string name="sound_category_sound_title">General</string>
|
<string name="sound_category_sound_title">General</string>
|
||||||
<string name="notification_log_title">Notification log</string>
|
<string name="notification_log_title">Notification log</string>
|
||||||
|
|
||||||
|
@@ -18,11 +18,9 @@ package com.android.settings;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -52,17 +50,17 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
|
||||||
import static android.content.Context.TELEPHONY_SERVICE;
|
import static android.content.Context.TELEPHONY_SERVICE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: After loading all changes, please move this to network package.
|
* TODO(b/77339683): After loading all changes, please move this to network package.
|
||||||
*/
|
*/
|
||||||
public class ApnEditor extends SettingsPreferenceFragment
|
public class ApnEditor extends SettingsPreferenceFragment
|
||||||
implements OnPreferenceChangeListener, OnKeyListener {
|
implements OnPreferenceChangeListener, OnKeyListener {
|
||||||
@@ -70,7 +68,6 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
private final static String TAG = ApnEditor.class.getSimpleName();
|
private final static String TAG = ApnEditor.class.getSimpleName();
|
||||||
private final static boolean VDBG = false; // STOPSHIP if true
|
private final static boolean VDBG = false; // STOPSHIP if true
|
||||||
|
|
||||||
private final static String SAVED_POS = "pos";
|
|
||||||
private final static String KEY_AUTH_TYPE = "auth_type";
|
private final static String KEY_AUTH_TYPE = "auth_type";
|
||||||
private final static String KEY_PROTOCOL = "apn_protocol";
|
private final static String KEY_PROTOCOL = "apn_protocol";
|
||||||
private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol";
|
private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol";
|
||||||
@@ -83,37 +80,57 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
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;
|
||||||
|
|
||||||
private static String sNotSet;
|
@VisibleForTesting
|
||||||
private EditTextPreference mName;
|
static String sNotSet;
|
||||||
private EditTextPreference mApn;
|
@VisibleForTesting
|
||||||
private EditTextPreference mProxy;
|
EditTextPreference mName;
|
||||||
private EditTextPreference mPort;
|
@VisibleForTesting
|
||||||
private EditTextPreference mUser;
|
EditTextPreference mApn;
|
||||||
private EditTextPreference mServer;
|
@VisibleForTesting
|
||||||
private EditTextPreference mPassword;
|
EditTextPreference mProxy;
|
||||||
private EditTextPreference mMmsc;
|
@VisibleForTesting
|
||||||
private EditTextPreference mMcc;
|
EditTextPreference mPort;
|
||||||
private EditTextPreference mMnc;
|
@VisibleForTesting
|
||||||
private EditTextPreference mMmsProxy;
|
EditTextPreference mUser;
|
||||||
private EditTextPreference mMmsPort;
|
@VisibleForTesting
|
||||||
private ListPreference mAuthType;
|
EditTextPreference mServer;
|
||||||
private EditTextPreference mApnType;
|
@VisibleForTesting
|
||||||
private ListPreference mProtocol;
|
EditTextPreference mPassword;
|
||||||
private ListPreference mRoamingProtocol;
|
@VisibleForTesting
|
||||||
private SwitchPreference mCarrierEnabled;
|
EditTextPreference mMmsc;
|
||||||
private MultiSelectListPreference mBearerMulti;
|
@VisibleForTesting
|
||||||
private ListPreference mMvnoType;
|
EditTextPreference mMcc;
|
||||||
private EditTextPreference mMvnoMatchData;
|
@VisibleForTesting
|
||||||
|
EditTextPreference mMnc;
|
||||||
|
@VisibleForTesting
|
||||||
|
EditTextPreference mMmsProxy;
|
||||||
|
@VisibleForTesting
|
||||||
|
EditTextPreference mMmsPort;
|
||||||
|
@VisibleForTesting
|
||||||
|
ListPreference mAuthType;
|
||||||
|
@VisibleForTesting
|
||||||
|
EditTextPreference mApnType;
|
||||||
|
@VisibleForTesting
|
||||||
|
ListPreference mProtocol;
|
||||||
|
@VisibleForTesting
|
||||||
|
ListPreference mRoamingProtocol;
|
||||||
|
@VisibleForTesting
|
||||||
|
SwitchPreference mCarrierEnabled;
|
||||||
|
@VisibleForTesting
|
||||||
|
MultiSelectListPreference mBearerMulti;
|
||||||
|
@VisibleForTesting
|
||||||
|
ListPreference mMvnoType;
|
||||||
|
@VisibleForTesting
|
||||||
|
EditTextPreference mMvnoMatchData;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
ApnData mApnData;
|
||||||
|
|
||||||
private String mCurMnc;
|
private String mCurMnc;
|
||||||
private String mCurMcc;
|
private String mCurMcc;
|
||||||
|
|
||||||
private Uri mUri;
|
|
||||||
private Cursor mCursor;
|
|
||||||
private boolean mNewApn;
|
private boolean mNewApn;
|
||||||
private boolean mFirstTime;
|
|
||||||
private int mSubId;
|
private int mSubId;
|
||||||
private Resources mRes;
|
|
||||||
private TelephonyManager mTelephonyManager;
|
private TelephonyManager mTelephonyManager;
|
||||||
private int mBearerInitialVal = 0;
|
private int mBearerInitialVal = 0;
|
||||||
private String mMvnoTypeStr;
|
private String mMvnoTypeStr;
|
||||||
@@ -121,6 +138,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
private String[] mReadOnlyApnTypes;
|
private String[] mReadOnlyApnTypes;
|
||||||
private String[] mReadOnlyApnFields;
|
private String[] mReadOnlyApnFields;
|
||||||
private boolean mReadOnlyApn;
|
private boolean mReadOnlyApn;
|
||||||
|
private Uri mCarrierUri;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard projection for the interesting columns of a normal note.
|
* Standard projection for the interesting columns of a normal note.
|
||||||
@@ -154,22 +172,27 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
};
|
};
|
||||||
|
|
||||||
private static final int ID_INDEX = 0;
|
private static final int ID_INDEX = 0;
|
||||||
private static final int NAME_INDEX = 1;
|
@VisibleForTesting
|
||||||
private static final int APN_INDEX = 2;
|
static final int NAME_INDEX = 1;
|
||||||
|
@VisibleForTesting
|
||||||
|
static final int APN_INDEX = 2;
|
||||||
private static final int PROXY_INDEX = 3;
|
private static final int PROXY_INDEX = 3;
|
||||||
private static final int PORT_INDEX = 4;
|
private static final int PORT_INDEX = 4;
|
||||||
private static final int USER_INDEX = 5;
|
private static final int USER_INDEX = 5;
|
||||||
private static final int SERVER_INDEX = 6;
|
private static final int SERVER_INDEX = 6;
|
||||||
private static final int PASSWORD_INDEX = 7;
|
private static final int PASSWORD_INDEX = 7;
|
||||||
private static final int MMSC_INDEX = 8;
|
private static final int MMSC_INDEX = 8;
|
||||||
private static final int MCC_INDEX = 9;
|
@VisibleForTesting
|
||||||
private static final int MNC_INDEX = 10;
|
static final int MCC_INDEX = 9;
|
||||||
|
@VisibleForTesting
|
||||||
|
static final int MNC_INDEX = 10;
|
||||||
private static final int MMSPROXY_INDEX = 12;
|
private static final int MMSPROXY_INDEX = 12;
|
||||||
private static final int MMSPORT_INDEX = 13;
|
private static final int MMSPORT_INDEX = 13;
|
||||||
private static final int AUTH_TYPE_INDEX = 14;
|
private static final int AUTH_TYPE_INDEX = 14;
|
||||||
private static final int TYPE_INDEX = 15;
|
private static final int TYPE_INDEX = 15;
|
||||||
private static final int PROTOCOL_INDEX = 16;
|
private static final int PROTOCOL_INDEX = 16;
|
||||||
private static final int CARRIER_ENABLED_INDEX = 17;
|
@VisibleForTesting
|
||||||
|
static final int CARRIER_ENABLED_INDEX = 17;
|
||||||
private static final int BEARER_INDEX = 18;
|
private static final int BEARER_INDEX = 18;
|
||||||
private static final int BEARER_BITMASK_INDEX = 19;
|
private static final int BEARER_BITMASK_INDEX = 19;
|
||||||
private static final int ROAMING_PROTOCOL_INDEX = 20;
|
private static final int ROAMING_PROTOCOL_INDEX = 20;
|
||||||
@@ -178,7 +201,6 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
private static final int EDITED_INDEX = 23;
|
private static final int EDITED_INDEX = 23;
|
||||||
private static final int USER_EDITABLE_INDEX = 24;
|
private static final int USER_EDITABLE_INDEX = 24;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@@ -207,14 +229,11 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE);
|
mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE);
|
||||||
mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
|
mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
|
||||||
|
|
||||||
mRes = getResources();
|
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
mSubId = intent.getIntExtra(ApnSettings.SUB_ID,
|
mSubId = intent.getIntExtra(ApnSettings.SUB_ID,
|
||||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
|
||||||
mFirstTime = icicle == null;
|
|
||||||
mReadOnlyApn = false;
|
mReadOnlyApn = false;
|
||||||
mReadOnlyApnTypes = null;
|
mReadOnlyApnTypes = null;
|
||||||
mReadOnlyApnFields = null;
|
mReadOnlyApnFields = null;
|
||||||
@@ -236,61 +255,47 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uri uri = null;
|
||||||
if (action.equals(Intent.ACTION_EDIT)) {
|
if (action.equals(Intent.ACTION_EDIT)) {
|
||||||
Uri uri = intent.getData();
|
uri = intent.getData();
|
||||||
if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
|
if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
|
||||||
Log.e(TAG, "Edit request not for carrier table. Uri: " + uri);
|
Log.e(TAG, "Edit request not for carrier table. Uri: " + uri);
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mUri = uri;
|
|
||||||
} else if (action.equals(Intent.ACTION_INSERT)) {
|
} else if (action.equals(Intent.ACTION_INSERT)) {
|
||||||
if (mFirstTime || icicle.getInt(SAVED_POS) == 0) {
|
mCarrierUri = intent.getData();
|
||||||
Uri uri = intent.getData();
|
if (!mCarrierUri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
|
||||||
if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
|
Log.e(TAG, "Insert request not for carrier table. Uri: " + mCarrierUri);
|
||||||
Log.e(TAG, "Insert request not for carrier table. Uri: " + uri);
|
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ContentValues contentValues = new ContentValues();
|
|
||||||
contentValues.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
|
|
||||||
mUri = getContentResolver().insert(uri, contentValues);
|
|
||||||
} else {
|
|
||||||
mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI,
|
|
||||||
icicle.getInt(SAVED_POS));
|
|
||||||
}
|
|
||||||
mNewApn = true;
|
mNewApn = true;
|
||||||
mMvnoTypeStr = intent.getStringExtra(ApnSettings.MVNO_TYPE);
|
mMvnoTypeStr = intent.getStringExtra(ApnSettings.MVNO_TYPE);
|
||||||
mMvnoMatchDataStr = intent.getStringExtra(ApnSettings.MVNO_MATCH_DATA);
|
mMvnoMatchDataStr = intent.getStringExtra(ApnSettings.MVNO_MATCH_DATA);
|
||||||
// If we were unable to create a new note, then just finish
|
|
||||||
// this activity. A RESULT_CANCELED will be sent back to the
|
|
||||||
// original activity if they requested a result.
|
|
||||||
if (mUri == null) {
|
|
||||||
Log.w(TAG, "Failed to insert new telephony provider into "
|
|
||||||
+ getIntent().getData());
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The new entry was created, so assume all will end well and
|
|
||||||
// set the result to be returned.
|
|
||||||
setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCursor = getActivity().managedQuery(mUri, sProjection, null, null);
|
// Creates an ApnData to store the apn data temporary, so that we don't need the cursor to
|
||||||
mCursor.moveToFirst();
|
// get the apn data. The uri is null if the action is ACTION_INSERT, that mean there is no
|
||||||
|
// record in the database, so create a empty ApnData to represent a empty row of database.
|
||||||
|
if (uri != null) {
|
||||||
|
mApnData = getApnDataFromUri(uri);
|
||||||
|
} else {
|
||||||
|
mApnData = new ApnData(sProjection.length);
|
||||||
|
}
|
||||||
|
|
||||||
mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
|
mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
|
||||||
|
|
||||||
Log.d(TAG, "onCreate: EDITED " + mCursor.getInt(EDITED_INDEX));
|
boolean isUserEdited = mApnData.getInteger(EDITED_INDEX, Telephony.Carriers.USER_EDITED)
|
||||||
|
== Telephony.Carriers.USER_EDITED;
|
||||||
|
|
||||||
|
Log.d(TAG, "onCreate: EDITED " + isUserEdited);
|
||||||
// if it's not a USER_EDITED apn, check if it's read-only
|
// if it's not a USER_EDITED apn, check if it's read-only
|
||||||
if (mCursor.getInt(EDITED_INDEX) != Telephony.Carriers.USER_EDITED &&
|
if (!isUserEdited && (mApnData.getInteger(USER_EDITABLE_INDEX, 1) == 0
|
||||||
(mCursor.getInt(USER_EDITABLE_INDEX) == 0 ||
|
|| apnTypesMatch(mReadOnlyApnTypes, mApnData.getString(TYPE_INDEX)))) {
|
||||||
apnTypesMatch(mReadOnlyApnTypes, mCursor.getString(TYPE_INDEX)))) {
|
|
||||||
Log.d(TAG, "onCreate: apnTypesMatch; read-only APN");
|
Log.d(TAG, "onCreate: apnTypesMatch; read-only APN");
|
||||||
mReadOnlyApn = true;
|
mReadOnlyApn = true;
|
||||||
disableAllFields();
|
disableAllFields();
|
||||||
@@ -302,12 +307,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this);
|
getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
fillUI(icicle == null);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
fillUi();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -462,50 +462,23 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
return MetricsEvent.APN_EDITOR;
|
return MetricsEvent.APN_EDITOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@VisibleForTesting
|
||||||
public void onResume() {
|
void fillUI(boolean firstTime) {
|
||||||
super.onResume();
|
if (firstTime) {
|
||||||
|
|
||||||
if (mUri == null && mNewApn) {
|
|
||||||
// The URI could have been deleted when activity is paused,
|
|
||||||
// therefore, it needs to be restored.
|
|
||||||
ContentValues contentValues = new ContentValues();
|
|
||||||
contentValues.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
|
|
||||||
mUri = getContentResolver().insert(getIntent().getData(), contentValues);
|
|
||||||
if (mUri == null) {
|
|
||||||
Log.w(TAG, "Failed to insert new telephony provider into "
|
|
||||||
+ getIntent().getData());
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mCursor = getActivity().managedQuery(mUri, sProjection, null, null);
|
|
||||||
mCursor.moveToFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillUi() {
|
|
||||||
if (mFirstTime) {
|
|
||||||
mFirstTime = false;
|
|
||||||
// Fill in all the values from the db in both text editor and summary
|
// Fill in all the values from the db in both text editor and summary
|
||||||
mName.setText(mCursor.getString(NAME_INDEX));
|
mName.setText(mApnData.getString(NAME_INDEX));
|
||||||
mApn.setText(mCursor.getString(APN_INDEX));
|
mApn.setText(mApnData.getString(APN_INDEX));
|
||||||
mProxy.setText(mCursor.getString(PROXY_INDEX));
|
mProxy.setText(mApnData.getString(PROXY_INDEX));
|
||||||
mPort.setText(mCursor.getString(PORT_INDEX));
|
mPort.setText(mApnData.getString(PORT_INDEX));
|
||||||
mUser.setText(mCursor.getString(USER_INDEX));
|
mUser.setText(mApnData.getString(USER_INDEX));
|
||||||
mServer.setText(mCursor.getString(SERVER_INDEX));
|
mServer.setText(mApnData.getString(SERVER_INDEX));
|
||||||
mPassword.setText(mCursor.getString(PASSWORD_INDEX));
|
mPassword.setText(mApnData.getString(PASSWORD_INDEX));
|
||||||
mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
|
mMmsProxy.setText(mApnData.getString(MMSPROXY_INDEX));
|
||||||
mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
|
mMmsPort.setText(mApnData.getString(MMSPORT_INDEX));
|
||||||
mMmsc.setText(mCursor.getString(MMSC_INDEX));
|
mMmsc.setText(mApnData.getString(MMSC_INDEX));
|
||||||
mMcc.setText(mCursor.getString(MCC_INDEX));
|
mMcc.setText(mApnData.getString(MCC_INDEX));
|
||||||
mMnc.setText(mCursor.getString(MNC_INDEX));
|
mMnc.setText(mApnData.getString(MNC_INDEX));
|
||||||
mApnType.setText(mCursor.getString(TYPE_INDEX));
|
mApnType.setText(mApnData.getString(TYPE_INDEX));
|
||||||
if (mNewApn) {
|
if (mNewApn) {
|
||||||
String numeric = mTelephonyManager.getSimOperator(mSubId);
|
String numeric = mTelephonyManager.getSimOperator(mSubId);
|
||||||
// MCC is first 3 chars and then in 2 - 3 chars of MNC
|
// MCC is first 3 chars and then in 2 - 3 chars of MNC
|
||||||
@@ -521,20 +494,20 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
mCurMcc = mcc;
|
mCurMcc = mcc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int authVal = mCursor.getInt(AUTH_TYPE_INDEX);
|
int authVal = mApnData.getInteger(AUTH_TYPE_INDEX, -1);
|
||||||
if (authVal != -1) {
|
if (authVal != -1) {
|
||||||
mAuthType.setValueIndex(authVal);
|
mAuthType.setValueIndex(authVal);
|
||||||
} else {
|
} else {
|
||||||
mAuthType.setValue(null);
|
mAuthType.setValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX));
|
mProtocol.setValue(mApnData.getString(PROTOCOL_INDEX));
|
||||||
mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX));
|
mRoamingProtocol.setValue(mApnData.getString(ROAMING_PROTOCOL_INDEX));
|
||||||
mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1);
|
mCarrierEnabled.setChecked(mApnData.getInteger(CARRIER_ENABLED_INDEX, 1) == 1);
|
||||||
mBearerInitialVal = mCursor.getInt(BEARER_INDEX);
|
mBearerInitialVal = mApnData.getInteger(BEARER_INDEX, 0);
|
||||||
|
|
||||||
HashSet<String> bearers = new HashSet<String>();
|
HashSet<String> bearers = new HashSet<String>();
|
||||||
int bearerBitmask = mCursor.getInt(BEARER_BITMASK_INDEX);
|
int bearerBitmask = mApnData.getInteger(BEARER_BITMASK_INDEX, 0);
|
||||||
if (bearerBitmask == 0) {
|
if (bearerBitmask == 0) {
|
||||||
if (mBearerInitialVal == 0) {
|
if (mBearerInitialVal == 0) {
|
||||||
bearers.add("" + 0);
|
bearers.add("" + 0);
|
||||||
@@ -556,9 +529,9 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
mBearerMulti.setValues(bearers);
|
mBearerMulti.setValues(bearers);
|
||||||
|
|
||||||
mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX));
|
mMvnoType.setValue(mApnData.getString(MVNO_TYPE_INDEX));
|
||||||
mMvnoMatchData.setEnabled(false);
|
mMvnoMatchData.setEnabled(false);
|
||||||
mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX));
|
mMvnoMatchData.setText(mApnData.getString(MVNO_MATCH_DATA_INDEX));
|
||||||
if (mNewApn && mMvnoTypeStr != null && mMvnoMatchDataStr != null) {
|
if (mNewApn && mMvnoTypeStr != null && mMvnoMatchDataStr != null) {
|
||||||
mMvnoType.setValue(mMvnoTypeStr);
|
mMvnoType.setValue(mMvnoTypeStr);
|
||||||
mMvnoMatchData.setText(mMvnoMatchDataStr);
|
mMvnoMatchData.setText(mMvnoMatchDataStr);
|
||||||
@@ -584,7 +557,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
int authValIndex = Integer.parseInt(authVal);
|
int authValIndex = Integer.parseInt(authVal);
|
||||||
mAuthType.setValueIndex(authValIndex);
|
mAuthType.setValueIndex(authValIndex);
|
||||||
|
|
||||||
String []values = mRes.getStringArray(R.array.apn_auth_entries);
|
String[] values = getResources().getStringArray(R.array.apn_auth_entries);
|
||||||
mAuthType.setSummary(values[authValIndex]);
|
mAuthType.setSummary(values[authValIndex]);
|
||||||
} else {
|
} else {
|
||||||
mAuthType.setSummary(sNotSet);
|
mAuthType.setSummary(sNotSet);
|
||||||
@@ -617,7 +590,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
if (protocolIndex == -1) {
|
if (protocolIndex == -1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
String[] values = mRes.getStringArray(R.array.apn_protocol_entries);
|
String[] values = getResources().getStringArray(R.array.apn_protocol_entries);
|
||||||
try {
|
try {
|
||||||
return values[protocolIndex];
|
return values[protocolIndex];
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
@@ -631,7 +604,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
if (mBearerIndex == -1) {
|
if (mBearerIndex == -1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
String[] values = mRes.getStringArray(R.array.bearer_entries);
|
String[] values = getResources().getStringArray(R.array.bearer_entries);
|
||||||
try {
|
try {
|
||||||
return values[mBearerIndex];
|
return values[mBearerIndex];
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
@@ -641,7 +614,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String bearerMultiDescription(Set<String> raw) {
|
private String bearerMultiDescription(Set<String> raw) {
|
||||||
String[] values = mRes.getStringArray(R.array.bearer_entries);
|
String[] values = getResources().getStringArray(R.array.bearer_entries);
|
||||||
StringBuilder retVal = new StringBuilder();
|
StringBuilder retVal = new StringBuilder();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String bearer : raw) {
|
for (String bearer : raw) {
|
||||||
@@ -671,7 +644,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
if (mvnoIndex == -1) {
|
if (mvnoIndex == -1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
String[] values = mRes.getStringArray(R.array.mvno_type_entries);
|
String[] values = getResources().getStringArray(R.array.mvno_type_entries);
|
||||||
boolean mvnoMatchDataUneditable =
|
boolean mvnoMatchDataUneditable =
|
||||||
mReadOnlyApn || (mReadOnlyApnFields != null
|
mReadOnlyApn || (mReadOnlyApnFields != null
|
||||||
&& Arrays.asList(mReadOnlyApnFields)
|
&& Arrays.asList(mReadOnlyApnFields)
|
||||||
@@ -703,7 +676,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
int index = Integer.parseInt((String) newValue);
|
int index = Integer.parseInt((String) newValue);
|
||||||
mAuthType.setValueIndex(index);
|
mAuthType.setValueIndex(index);
|
||||||
|
|
||||||
String[] values = mRes.getStringArray(R.array.apn_auth_entries);
|
String[] values = getResources().getStringArray(R.array.apn_auth_entries);
|
||||||
mAuthType.setSummary(values[index]);
|
mAuthType.setSummary(values[index]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -766,21 +739,20 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_DELETE:
|
case MENU_DELETE:
|
||||||
deleteApn();
|
deleteApn();
|
||||||
|
finish();
|
||||||
return true;
|
return true;
|
||||||
case MENU_SAVE:
|
case MENU_SAVE:
|
||||||
if (validateAndSave(false)) {
|
if (validateAndSaveApnData()) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case MENU_CANCEL:
|
case MENU_CANCEL:
|
||||||
if (mNewApn) {
|
|
||||||
getContentResolver().delete(mUri, null, null);
|
|
||||||
}
|
|
||||||
finish();
|
finish();
|
||||||
return true;
|
return true;
|
||||||
}
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
@@ -790,11 +762,20 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
view.requestFocus();
|
view.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to save the apn data when pressed the back button. An error message will be displayed if
|
||||||
|
* the apn data is invalid.
|
||||||
|
*
|
||||||
|
* TODO(b/77339593): Try to keep the same behavior between back button and up navigate button.
|
||||||
|
* We will save the valid apn data to the database when pressed the back button, but discard all
|
||||||
|
* user changed when pressed the up navigate button.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
|
if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case KeyEvent.KEYCODE_BACK: {
|
case KeyEvent.KEYCODE_BACK: {
|
||||||
if (validateAndSave(false)) {
|
if (validateAndSaveApnData()) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -803,62 +784,70 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle icicle) {
|
|
||||||
super.onSaveInstanceState(icicle);
|
|
||||||
if (validateAndSave(true)) {
|
|
||||||
icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add key, value to cv and compare the value against the value at index in mCursor. Return true
|
* Add key, value to {@code cv} and compare the value against the value at index in
|
||||||
* if values are different. assumeDiff indicates if values can be assumed different in which
|
* {@link #mApnData}.
|
||||||
* case no comparison is needed.
|
*
|
||||||
* @return true if value is different from the value at index in mCursor
|
* <p>
|
||||||
|
* The key, value will not add to {@code cv} if value is null.
|
||||||
|
*
|
||||||
|
* @return true if values are different. {@code assumeDiff} indicates if values can be assumed
|
||||||
|
* different in which case no comparison is needed.
|
||||||
*/
|
*/
|
||||||
boolean setStringValueAndCheckIfDiff(ContentValues cv, String key, String value,
|
boolean setStringValueAndCheckIfDiff(
|
||||||
boolean assumeDiff, int index) {
|
ContentValues cv, String key, String value, boolean assumeDiff, int index) {
|
||||||
cv.put(key, value);
|
String valueFromLocalCache = mApnData.getString(index);
|
||||||
String valueFromCursor = mCursor.getString(index);
|
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.d(TAG, "setStringValueAndCheckIfDiff: assumeDiff: " + assumeDiff
|
Log.d(TAG, "setStringValueAndCheckIfDiff: assumeDiff: " + assumeDiff
|
||||||
+ " key: " + key
|
+ " key: " + key
|
||||||
+ " value: '" + value
|
+ " value: '" + value
|
||||||
+ "' valueFromCursor: '" + valueFromCursor + "'");
|
+ "' valueFromDb: '" + valueFromLocalCache + "'");
|
||||||
}
|
}
|
||||||
return assumeDiff
|
boolean isDiff = assumeDiff
|
||||||
|| !((TextUtils.isEmpty(value) && TextUtils.isEmpty(valueFromCursor))
|
|| !((TextUtils.isEmpty(value) && TextUtils.isEmpty(valueFromLocalCache))
|
||||||
|| (value != null && value.equals(valueFromCursor)));
|
|| (value != null && value.equals(valueFromLocalCache)));
|
||||||
|
|
||||||
|
if (isDiff && value != null) {
|
||||||
|
cv.put(key, value);
|
||||||
|
}
|
||||||
|
return isDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add key, value to cv and compare the value against the value at index in mCursor. Return true
|
* Add key, value to {@code cv} and compare the value against the value at index in
|
||||||
* if values are different. assumeDiff indicates if values can be assumed different in which
|
* {@link #mApnData}.
|
||||||
* case no comparison is needed.
|
*
|
||||||
* @return true if value is different from the value at index in mCursor
|
* @return true if values are different. {@code assumeDiff} indicates if values can be assumed
|
||||||
|
* different in which case no comparison is needed.
|
||||||
*/
|
*/
|
||||||
boolean setIntValueAndCheckIfDiff(ContentValues cv, String key, int value,
|
boolean setIntValueAndCheckIfDiff(
|
||||||
boolean assumeDiff, int index) {
|
ContentValues cv, String key, int value, boolean assumeDiff, int index) {
|
||||||
cv.put(key, value);
|
Integer valueFromLocalCache = mApnData.getInteger(index);
|
||||||
int valueFromCursor = mCursor.getInt(index);
|
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.d(TAG, "setIntValueAndCheckIfDiff: assumeDiff: " + assumeDiff
|
Log.d(TAG, "setIntValueAndCheckIfDiff: assumeDiff: " + assumeDiff
|
||||||
+ " key: " + key
|
+ " key: " + key
|
||||||
+ " value: '" + value
|
+ " value: '" + value
|
||||||
+ "' valueFromCursor: '" + valueFromCursor + "'");
|
+ "' valueFromDb: '" + valueFromLocalCache + "'");
|
||||||
}
|
}
|
||||||
return assumeDiff || value != valueFromCursor;
|
|
||||||
|
boolean isDiff = assumeDiff || value != valueFromLocalCache;
|
||||||
|
if (isDiff) {
|
||||||
|
cv.put(key, value);
|
||||||
|
}
|
||||||
|
return isDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the key fields' validity and save if valid.
|
* Validates the apn data and save it to the database if it's valid.
|
||||||
* @param force save even if the fields are not valid, if the app is
|
*
|
||||||
* being suspended
|
* <p>
|
||||||
* @return true if there's no error
|
* A dialog with error message will be displayed if the APN data is invalid.
|
||||||
|
*
|
||||||
|
* @return true if there is no error
|
||||||
*/
|
*/
|
||||||
private boolean validateAndSave(boolean force) {
|
@VisibleForTesting
|
||||||
// nothing to do if it's a read only APN
|
boolean validateAndSaveApnData() {
|
||||||
|
// Nothing to do if it's a read only APN
|
||||||
if (mReadOnlyApn) {
|
if (mReadOnlyApn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -868,21 +857,9 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
String mcc = checkNotSet(mMcc.getText());
|
String mcc = checkNotSet(mMcc.getText());
|
||||||
String mnc = checkNotSet(mMnc.getText());
|
String mnc = checkNotSet(mMnc.getText());
|
||||||
|
|
||||||
if (getErrorMsg() != null && !force) {
|
String errorMsg = validateApnData();
|
||||||
ErrorDialog.showError(this);
|
if (errorMsg != null) {
|
||||||
return false;
|
showError();
|
||||||
}
|
|
||||||
|
|
||||||
if (!mCursor.moveToFirst()) {
|
|
||||||
Log.w(TAG,
|
|
||||||
"Could not go to the first row in the Cursor when saving data.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's a new APN and a name or apn haven't been entered, then erase the entry
|
|
||||||
if (force && mNewApn && name.length() < 1 && apn.length() < 1) {
|
|
||||||
getContentResolver().delete(mUri, null, null);
|
|
||||||
mUri = null;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,12 +867,9 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
// call update() if it's a new APN. If not, check if any field differs from the db value;
|
// call update() if it's a new APN. If not, check if any field differs from the db value;
|
||||||
// if any diff is found update() should be called
|
// if any diff is found update() should be called
|
||||||
boolean callUpdate = mNewApn;
|
boolean callUpdate = mNewApn;
|
||||||
|
|
||||||
// Add a dummy name "Untitled", if the user exits the screen without adding a name but
|
|
||||||
// entered other information worth keeping.
|
|
||||||
callUpdate = setStringValueAndCheckIfDiff(values,
|
callUpdate = setStringValueAndCheckIfDiff(values,
|
||||||
Telephony.Carriers.NAME,
|
Telephony.Carriers.NAME,
|
||||||
name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name,
|
name,
|
||||||
callUpdate,
|
callUpdate,
|
||||||
NAME_INDEX);
|
NAME_INDEX);
|
||||||
|
|
||||||
@@ -1054,15 +1028,38 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
values.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
|
values.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
|
||||||
|
|
||||||
if (callUpdate) {
|
if (callUpdate) {
|
||||||
getContentResolver().update(mUri, values, null, null);
|
final Uri uri = mApnData.getUri() == null ? mCarrierUri : mApnData.getUri();
|
||||||
|
updateApnDataToDatabase(uri, values);
|
||||||
} else {
|
} else {
|
||||||
if (VDBG) Log.d(TAG, "validateAndSave: not calling update()");
|
if (VDBG) Log.d(TAG, "validateAndSaveApnData: not calling update()");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getErrorMsg() {
|
private void updateApnDataToDatabase(Uri uri, ContentValues values) {
|
||||||
|
ThreadUtils.postOnBackgroundThread(() -> {
|
||||||
|
if (uri.equals(mCarrierUri)) {
|
||||||
|
// Add a new apn to the database
|
||||||
|
final Uri newUri = getContentResolver().insert(mCarrierUri, values);
|
||||||
|
if (newUri == null) {
|
||||||
|
Log.e(TAG, "Can't add a new apn to database " + mCarrierUri);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Update the existing apn
|
||||||
|
getContentResolver().update(
|
||||||
|
uri, values, null /* where */, null /* selection Args */);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates whether the apn data is valid.
|
||||||
|
*
|
||||||
|
* @return An error message if the apn data is invalid, otherwise return null.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
String validateApnData() {
|
||||||
String errorMsg = null;
|
String errorMsg = null;
|
||||||
|
|
||||||
String name = checkNotSet(mName.getText());
|
String name = checkNotSet(mName.getText());
|
||||||
@@ -1070,14 +1067,14 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
String mcc = checkNotSet(mMcc.getText());
|
String mcc = checkNotSet(mMcc.getText());
|
||||||
String mnc = checkNotSet(mMnc.getText());
|
String mnc = checkNotSet(mMnc.getText());
|
||||||
|
|
||||||
if (name.length() < 1) {
|
if (TextUtils.isEmpty(name)) {
|
||||||
errorMsg = mRes.getString(R.string.error_name_empty);
|
errorMsg = getResources().getString(R.string.error_name_empty);
|
||||||
} else if (apn.length() < 1) {
|
} else if (TextUtils.isEmpty(apn)) {
|
||||||
errorMsg = mRes.getString(R.string.error_apn_empty);
|
errorMsg = getResources().getString(R.string.error_apn_empty);
|
||||||
} else if (mcc.length() != 3) {
|
} else if (mcc == null || mcc.length() != 3) {
|
||||||
errorMsg = mRes.getString(R.string.error_mcc_not3);
|
errorMsg = getResources().getString(R.string.error_mcc_not3);
|
||||||
} else if ((mnc.length() & 0xFFFE) != 2) {
|
} else if ((mnc == null || (mnc.length() & 0xFFFE) != 2)) {
|
||||||
errorMsg = mRes.getString(R.string.error_mnc_not23);
|
errorMsg = getResources().getString(R.string.error_mnc_not23);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMsg == null) {
|
if (errorMsg == null) {
|
||||||
@@ -1088,13 +1085,13 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
for (String type : mReadOnlyApnTypes) {
|
for (String type : mReadOnlyApnTypes) {
|
||||||
stringBuilder.append(type).append(", ");
|
stringBuilder.append(type).append(", ");
|
||||||
Log.d(TAG, "getErrorMsg: appending type: " + type);
|
Log.d(TAG, "validateApnData: appending type: " + type);
|
||||||
}
|
}
|
||||||
// remove last ", "
|
// remove last ", "
|
||||||
if (stringBuilder.length() >= 2) {
|
if (stringBuilder.length() >= 2) {
|
||||||
stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length());
|
stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length());
|
||||||
}
|
}
|
||||||
errorMsg = String.format(mRes.getString(R.string.error_adding_apn_type),
|
errorMsg = String.format(getResources().getString(R.string.error_adding_apn_type),
|
||||||
stringBuilder);
|
stringBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1102,9 +1099,16 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
return errorMsg;
|
return errorMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void showError() {
|
||||||
|
ErrorDialog.showError(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void deleteApn() {
|
private void deleteApn() {
|
||||||
getContentResolver().delete(mUri, null, null);
|
if (mApnData.getUri() != null) {
|
||||||
finish();
|
getContentResolver().delete(mApnData.getUri(), null, null);
|
||||||
|
mApnData = new ApnData(sProjection.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String starify(String value) {
|
private String starify(String value) {
|
||||||
@@ -1119,20 +1123,21 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@link #sNotSet} if the given string {@code value} is null or empty. The string
|
||||||
|
* {@link #sNotSet} typically used as the default display when an entry in the preference is
|
||||||
|
* null or empty.
|
||||||
|
*/
|
||||||
private String checkNull(String value) {
|
private String checkNull(String value) {
|
||||||
if (value == null || value.length() == 0) {
|
return TextUtils.isEmpty(value) ? sNotSet : value;
|
||||||
return sNotSet;
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns null if the given string {@code value} equals to {@link #sNotSet}. This method
|
||||||
|
* should be used when convert a string value from preference to database.
|
||||||
|
*/
|
||||||
private String checkNotSet(String value) {
|
private String checkNotSet(String value) {
|
||||||
if (value == null || value.equals(sNotSet)) {
|
return sNotSet.equals(value) ? null : value;
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUserEnteredApnType() {
|
private String getUserEnteredApnType() {
|
||||||
@@ -1176,7 +1181,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
String msg = ((ApnEditor) getTargetFragment()).getErrorMsg();
|
String msg = ((ApnEditor) getTargetFragment()).validateApnData();
|
||||||
|
|
||||||
return new AlertDialog.Builder(getContext())
|
return new AlertDialog.Builder(getContext())
|
||||||
.setTitle(R.string.error_title)
|
.setTitle(R.string.error_title)
|
||||||
@@ -1191,10 +1196,19 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidTypeException extends RuntimeException {
|
private ApnData getApnDataFromUri(Uri uri) {
|
||||||
InvalidTypeException(String msg) {
|
ApnData apnData;
|
||||||
super(msg);
|
try (Cursor cursor = getActivity().managedQuery(
|
||||||
|
uri, sProjection, null /* selection */, null /* sortOrder */)) {
|
||||||
|
cursor.moveToFirst();
|
||||||
|
apnData = new ApnData(uri, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (apnData == null) {
|
||||||
|
Log.d(TAG, "Can't get apnData from Uri " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -1243,34 +1257,17 @@ public class ApnEditor extends SettingsPreferenceFragment
|
|||||||
mUri = uri;
|
mUri = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer getInteger(int index) throws InvalidTypeException {
|
Integer getInteger(int index) {
|
||||||
if (!isValidTypeOrNull(mData[index], Integer.class)) {
|
|
||||||
throwInvalidTypeException(Integer.class, mData[index].getClass());
|
|
||||||
}
|
|
||||||
return (Integer) mData[index];
|
return (Integer) mData[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer getInteger(int index, Integer defaultValue) throws InvalidTypeException {
|
Integer getInteger(int index, Integer defaultValue) {
|
||||||
Integer val = getInteger(index);
|
Integer val = getInteger(index);
|
||||||
return val == null ? defaultValue : val;
|
return val == null ? defaultValue : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getString(int index) throws InvalidTypeException {
|
String getString(int index) {
|
||||||
if (!isValidTypeOrNull(mData[index], String.class)) {
|
|
||||||
throwInvalidTypeException(String.class, mData[index].getClass());
|
|
||||||
}
|
|
||||||
return (String) mData[index];
|
return (String) mData[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidTypeOrNull(Object obj, Class expectedClass) {
|
|
||||||
return obj == null || expectedClass.isInstance(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwInvalidTypeException(Class<?> expectedClass, Class<?> actualClass) {
|
|
||||||
throw new InvalidTypeException(
|
|
||||||
String.format(
|
|
||||||
"Type mismatched, want %s, but is %s", expectedClass, actualClass));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -16,27 +16,73 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static junit.framework.Assert.assertNull;
|
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.support.v14.preference.MultiSelectListPreference;
|
||||||
|
import android.support.v14.preference.SwitchPreference;
|
||||||
|
import android.support.v7.preference.EditTextPreference;
|
||||||
|
import android.support.v7.preference.ListPreference;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.settings.ApnEditor.ApnData;
|
import com.android.settings.ApnEditor.ApnData;
|
||||||
import com.android.settings.ApnEditor.InvalidTypeException;
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
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;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class ApnEditorTest {
|
public class ApnEditorTest {
|
||||||
|
|
||||||
|
private static final Object[] APN_DATA = new Object[] {
|
||||||
|
0, /* ID */
|
||||||
|
"apn_name" /* apn name */,
|
||||||
|
"apn.com" /* apn */,
|
||||||
|
"" /* proxy */,
|
||||||
|
"" /* port */,
|
||||||
|
"" /* username */,
|
||||||
|
"" /* server */,
|
||||||
|
"" /* password */,
|
||||||
|
"" /* MMSC */,
|
||||||
|
"123" /* MCC */,
|
||||||
|
"456" /* MNC */,
|
||||||
|
"123456" /* operator numeric */,
|
||||||
|
"" /* MMS proxy */,
|
||||||
|
"" /* MMS port */,
|
||||||
|
0 /* Authentication type */,
|
||||||
|
"default,supl,ia" /* APN type */,
|
||||||
|
"IPv6" /* APN protocol */,
|
||||||
|
1 /* APN enable/disable */,
|
||||||
|
0 /* Bearer */,
|
||||||
|
0 /* Bearer BITMASK*/,
|
||||||
|
"IPv4" /* APN roaming protocol */,
|
||||||
|
"None" /* MVNO type */,
|
||||||
|
"", /* MVNO value */
|
||||||
|
};
|
||||||
|
|
||||||
private static final int CURSOR_INTEGER_INDEX = 0;
|
private static final int CURSOR_INTEGER_INDEX = 0;
|
||||||
private static final int CURSOR_STRING_INDEX = 1;
|
private static final int CURSOR_STRING_INDEX = 1;
|
||||||
|
|
||||||
@@ -45,10 +91,331 @@ public class ApnEditorTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Cursor mCursor;
|
private Cursor mCursor;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<Uri> mUriCaptor;
|
||||||
|
|
||||||
|
private ApnEditor mApnEditorUT;
|
||||||
|
private Activity mActivity;
|
||||||
|
private Resources mResources;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mActivity = spy(Robolectric.setupActivity(Activity.class));
|
||||||
|
mResources = mActivity.getResources();
|
||||||
|
mApnEditorUT = spy(new ApnEditor());
|
||||||
|
|
||||||
|
doReturn(mActivity).when(mApnEditorUT).getActivity();
|
||||||
|
doReturn(mResources).when(mApnEditorUT).getResources();
|
||||||
|
doNothing().when(mApnEditorUT).finish();
|
||||||
|
doNothing().when(mApnEditorUT).showError();
|
||||||
|
|
||||||
|
setMockPreference(mActivity);
|
||||||
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
||||||
|
mApnEditorUT.sNotSet = "Not Set";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetStringValue_valueChanged_shouldSetValue() {
|
||||||
|
// GIVEN an APN value which is different than the APN value in database
|
||||||
|
final String apnKey = "apn";
|
||||||
|
final String apnValue = "testing.com";
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
|
||||||
|
// WHEN try to check and set the apn value
|
||||||
|
final boolean isDiff = mApnEditorUT.setStringValueAndCheckIfDiff(
|
||||||
|
cv, apnKey, apnValue, false /* assumeDiff */, ApnEditor.APN_INDEX);
|
||||||
|
|
||||||
|
// THEN the APN value is different than the one in database, and it has been stored in the
|
||||||
|
// given ContentValues
|
||||||
|
assertThat(isDiff).isTrue();
|
||||||
|
assertThat(apnValue).isEqualTo(cv.getAsString(apnKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetStringValue_valueNotChanged_shouldNotSetValue() {
|
||||||
|
// GIVEN an APN value which is same as the APN value in database
|
||||||
|
final String apnKey = "apn";
|
||||||
|
final String apnValue = (String) APN_DATA[ApnEditor.APN_INDEX];
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
|
||||||
|
// WHEN try to check and set the apn value
|
||||||
|
final boolean isDiff = mApnEditorUT.setStringValueAndCheckIfDiff(
|
||||||
|
cv, apnKey, apnValue, false /* assumeDiff */, ApnEditor.APN_INDEX);
|
||||||
|
|
||||||
|
// THEN the APN value is same as the one in database, and the new APN value is not stored
|
||||||
|
// in the given ContentValues
|
||||||
|
assertThat(isDiff).isFalse();
|
||||||
|
assertThat(cv.get(apnKey)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetStringValue_nullValue_shouldNotSetValue_shouldNotSetValue() {
|
||||||
|
// GIVEN a null APN value
|
||||||
|
final String apnKey = "apn";
|
||||||
|
final String apnValue = null;
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
|
||||||
|
// WHEN try to check and set the apn value
|
||||||
|
final boolean isDiff = mApnEditorUT.setStringValueAndCheckIfDiff(
|
||||||
|
cv, apnKey, apnValue, false /* assumeDiff */, ApnEditor.APN_INDEX);
|
||||||
|
|
||||||
|
// THEN the APN value is different than the one in database, but the null value is not
|
||||||
|
// stored in the given ContentValues
|
||||||
|
assertThat(isDiff).isTrue();
|
||||||
|
assertThat(cv.get(apnKey)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIntValue_valueChanged_shouldSetValue() {
|
||||||
|
// GIVEN a value indicated whether the apn is enabled, and it's different than the value in
|
||||||
|
// the database
|
||||||
|
final String apnEnabledKey = "apn_enabled";
|
||||||
|
final int apnEnabledValue = 0;
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
|
||||||
|
// WHEN try to check and set the apn enabled
|
||||||
|
final boolean isDiff = mApnEditorUT.setIntValueAndCheckIfDiff(
|
||||||
|
cv,
|
||||||
|
apnEnabledKey,
|
||||||
|
apnEnabledValue,
|
||||||
|
false /* assumeDiff */,
|
||||||
|
ApnEditor.CARRIER_ENABLED_INDEX);
|
||||||
|
|
||||||
|
// THEN the apn enabled field is different than the one in database, and it has been stored
|
||||||
|
// in the given ContentValues
|
||||||
|
assertThat(isDiff).isTrue();
|
||||||
|
assertThat(cv.getAsInteger(apnEnabledKey)).isEqualTo(apnEnabledValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIntValue_valueNotChanged_shouldNotSetValue() {
|
||||||
|
// GIVEN a value indicated whether the apn is enabled, and it's same as the one in the
|
||||||
|
// database
|
||||||
|
final String apnEnabledKey = "apn_enabled";
|
||||||
|
final int apnEnabledValue = (int) APN_DATA[ApnEditor.CARRIER_ENABLED_INDEX];
|
||||||
|
final ContentValues cv = new ContentValues();
|
||||||
|
|
||||||
|
// WHEN try to check and set the apn enabled
|
||||||
|
final boolean isDiff = mApnEditorUT.setIntValueAndCheckIfDiff(
|
||||||
|
cv,
|
||||||
|
apnEnabledKey,
|
||||||
|
apnEnabledValue,
|
||||||
|
false /* assumeDiff */,
|
||||||
|
ApnEditor.CARRIER_ENABLED_INDEX);
|
||||||
|
|
||||||
|
// THEN the apn enabled field is same as the one in the database, and the filed is not
|
||||||
|
// stored in the given ContentValues
|
||||||
|
assertThat(isDiff).isFalse();
|
||||||
|
assertThat(cv.get(apnEnabledKey)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateApnData_validData_shouldReturnNull() {
|
||||||
|
// GIVEN a valid apn data
|
||||||
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN validate the apn data
|
||||||
|
final String errMsg = mApnEditorUT.validateApnData();
|
||||||
|
|
||||||
|
// THEN the error message should be null
|
||||||
|
assertThat(errMsg).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateApn_apnNameNotSet_shouldReturnErrorMessage() {
|
||||||
|
// GIVEN a apn data without the apn name
|
||||||
|
final FakeApnData apnData = new FakeApnData(APN_DATA);
|
||||||
|
apnData.mData[ApnEditor.NAME_INDEX] = "";
|
||||||
|
mApnEditorUT.mApnData = apnData;
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// THEN validate the apn data
|
||||||
|
final String errMsg = mApnEditorUT.validateApnData();
|
||||||
|
|
||||||
|
// THEN the error message indicated the apn name not set is returned
|
||||||
|
assertThat(errMsg).isEqualTo(mResources.getString(R.string.error_name_empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateApnData_apnNotSet_shouldReturnErrorMessage() {
|
||||||
|
// GIVEN a apn data without the apn
|
||||||
|
final FakeApnData apnData = new FakeApnData(APN_DATA);
|
||||||
|
apnData.mData[ApnEditor.APN_INDEX] = "";
|
||||||
|
mApnEditorUT.mApnData = apnData;
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// THEN validate the apn data
|
||||||
|
final String errMsg = mApnEditorUT.validateApnData();
|
||||||
|
|
||||||
|
// THEN the error message indicated the apn not set is returned
|
||||||
|
assertThat(errMsg).isEqualTo(mResources.getString(R.string.error_apn_empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateApnData_mccInvalid_shouldReturnErrorMessage() {
|
||||||
|
// GIVEN a apn data with invalid mcc
|
||||||
|
final FakeApnData apnData = new FakeApnData(APN_DATA);
|
||||||
|
// The length of the mcc should be 3
|
||||||
|
apnData.mData[ApnEditor.MCC_INDEX] = "1324";
|
||||||
|
mApnEditorUT.mApnData = apnData;
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN validate the apn data
|
||||||
|
final String errMsg = mApnEditorUT.validateApnData();
|
||||||
|
|
||||||
|
// THEN the error message indicated the mcc invalid is returned
|
||||||
|
assertThat(errMsg).isEqualTo(mResources.getString(R.string.error_mcc_not3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateApnData_mncInvalid_shouldReturnErrorMessage() {
|
||||||
|
// GIVEN an apn data with invalid mnc
|
||||||
|
final FakeApnData apnData = new FakeApnData(APN_DATA);
|
||||||
|
// The length of the mnc should be 2 or 3
|
||||||
|
apnData.mData[ApnEditor.MNC_INDEX] = "1324";
|
||||||
|
mApnEditorUT.mApnData = apnData;
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN validate the apn data
|
||||||
|
final String errMsg = mApnEditorUT.validateApnData();
|
||||||
|
|
||||||
|
// THEN the error message indicated the mnc invalid is returned
|
||||||
|
assertThat(errMsg).isEqualTo(mResources.getString(R.string.error_mnc_not23));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveApnData_pressBackButtonWithValidApnData_shouldSaveApnData() {
|
||||||
|
// GIVEN a valid apn data
|
||||||
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN press the back button
|
||||||
|
final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
|
||||||
|
mApnEditorUT.onKey(new View(mActivity), KeyEvent.KEYCODE_BACK, event);
|
||||||
|
|
||||||
|
// THEN the apn data is saved and the apn editor is closed
|
||||||
|
verify(mApnEditorUT).validateAndSaveApnData();
|
||||||
|
verify(mApnEditorUT).finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveApnData_pressSaveButtonWithValidApnData_shouldSaveApnData() {
|
||||||
|
// GIVEN a valid apn data
|
||||||
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN press the save button
|
||||||
|
MenuItem item = Mockito.mock(MenuItem.class);
|
||||||
|
// Menu.FIRST + 1 indicated the SAVE option in ApnEditor
|
||||||
|
doReturn(Menu.FIRST + 1).when(item).getItemId();
|
||||||
|
mApnEditorUT.onOptionsItemSelected(item);
|
||||||
|
|
||||||
|
// THEN the apn data is saved and the apn editor is closed
|
||||||
|
verify(mApnEditorUT).validateAndSaveApnData();
|
||||||
|
verify(mApnEditorUT).finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveApnData_apnDataInvalid_shouldNotSaveApnData() {
|
||||||
|
// GIVEN an invalid apn data
|
||||||
|
final FakeApnData apnData = new FakeApnData(APN_DATA);
|
||||||
|
// The valid apn data should contains a non-empty apn name
|
||||||
|
apnData.mData[ApnEditor.NAME_INDEX] = "";
|
||||||
|
mApnEditorUT.mApnData = apnData;
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
|
||||||
|
// WHEN press the save button
|
||||||
|
final MenuItem item = Mockito.mock(MenuItem.class);
|
||||||
|
// Menu.FIRST + 1 indicated the SAVE option in ApnEditor
|
||||||
|
doReturn(Menu.FIRST + 1).when(item).getItemId();
|
||||||
|
mApnEditorUT.onOptionsItemSelected(item);
|
||||||
|
|
||||||
|
// THEN the error dialog is shown
|
||||||
|
verify(mApnEditorUT).validateAndSaveApnData();
|
||||||
|
verify(mApnEditorUT).showError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteApnData_shouldDeleteData() {
|
||||||
|
// GIVEN a valid apn data correspond a row in database
|
||||||
|
final Uri apnUri = Uri.parse("content://telephony/carriers/1");
|
||||||
|
mApnEditorUT.mApnData = new FakeApnData(APN_DATA, apnUri);
|
||||||
|
mApnEditorUT.fillUI(true /* firstTime */);
|
||||||
|
ContentResolver mockContentResolver = Mockito.mock(ContentResolver.class);
|
||||||
|
doReturn(mockContentResolver).when(mActivity).getContentResolver();
|
||||||
|
|
||||||
|
// WHEN press the save button
|
||||||
|
final MenuItem item = Mockito.mock(MenuItem.class);
|
||||||
|
// Menu.FIRST indicated the DELETE option in ApnEditor
|
||||||
|
doReturn(Menu.FIRST).when(item).getItemId();
|
||||||
|
mApnEditorUT.onOptionsItemSelected(item);
|
||||||
|
|
||||||
|
// THEN the apn data is deleted and the apn editor is closed
|
||||||
|
verify(mockContentResolver).delete(mUriCaptor.capture(), any(), any());
|
||||||
|
assertThat(apnUri).isEqualTo(mUriCaptor.getValue());
|
||||||
|
verify(mApnEditorUT).finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void testApnData_invalidIntegerType_throwsInvalidTypeException() {
|
||||||
|
// GIVEN a ApnData constructed from cursor
|
||||||
initCursor();
|
initCursor();
|
||||||
|
final ApnData data = new ApnData(mApnUri, mCursor);
|
||||||
|
|
||||||
|
// WHEN get a string from an integer column
|
||||||
|
// THEN the InvalidTypeException is threw
|
||||||
|
data.getString(CURSOR_INTEGER_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void testApnData_invalidStringType_throwsInvalidTypeException() {
|
||||||
|
// GIVEN a ApnData constructed from cursor
|
||||||
|
initCursor();
|
||||||
|
final ApnData data = new ApnData(mApnUri, mCursor);
|
||||||
|
|
||||||
|
// WHEN get a integer from a string column
|
||||||
|
// THEN the InvalidTypeException is threw
|
||||||
|
data.getInteger(CURSOR_STRING_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApnData_validIntegerType_returnCorrectValue() {
|
||||||
|
// GIVEN a ApnData constructed from cursor
|
||||||
|
initCursor();
|
||||||
|
final ApnData data = new ApnData(mApnUri, mCursor);
|
||||||
|
|
||||||
|
// WHEN get integer from an integer column
|
||||||
|
final int val = data.getInteger(CURSOR_INTEGER_INDEX);
|
||||||
|
|
||||||
|
// THEN the integer is returned correctly
|
||||||
|
assertThat(val).isEqualTo(mCursor.getInt(CURSOR_INTEGER_INDEX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApnData_validStringType_returnCorrectValue() {
|
||||||
|
// GIVEN a ApnData constructed from cursor
|
||||||
|
initCursor();
|
||||||
|
final ApnData data = new ApnData(mApnUri, mCursor);
|
||||||
|
|
||||||
|
// WHEN get string from a string column
|
||||||
|
final String str = data.getString(CURSOR_STRING_INDEX);
|
||||||
|
|
||||||
|
// THEN the integer is returned correctly
|
||||||
|
assertThat(str).isEqualTo(mCursor.getString(CURSOR_STRING_INDEX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApnData_nullValueColumn_returnNull() {
|
||||||
|
// GIVEN a empty ApnData
|
||||||
|
final ApnData data = new ApnData(3);
|
||||||
|
|
||||||
|
// WHEN get string value from a null column
|
||||||
|
final String str = data.getString(0);
|
||||||
|
|
||||||
|
// THEN the null value is returned
|
||||||
|
assertThat(str).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initCursor() {
|
private void initCursor() {
|
||||||
@@ -59,59 +426,38 @@ public class ApnEditorTest {
|
|||||||
doReturn(Cursor.FIELD_TYPE_STRING).when(mCursor).getType(CURSOR_STRING_INDEX);
|
doReturn(Cursor.FIELD_TYPE_STRING).when(mCursor).getType(CURSOR_STRING_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidTypeException.class)
|
private void setMockPreference(Context context) {
|
||||||
public void testApnData_invalidIntegerType_throwsInvalidTypeException() {
|
mApnEditorUT.mName = new EditTextPreference(context);
|
||||||
// GIVEN a ApnData constructed from cursor
|
mApnEditorUT.mApn = new EditTextPreference(context);
|
||||||
ApnData data = new ApnData(mApnUri, mCursor);
|
mApnEditorUT.mProxy = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mPort = new EditTextPreference(context);
|
||||||
// WHEN get a string from an integer column
|
mApnEditorUT.mUser = new EditTextPreference(context);
|
||||||
// THEN the InvalidTypeException is threw
|
mApnEditorUT.mServer = new EditTextPreference(context);
|
||||||
data.getString(CURSOR_INTEGER_INDEX);
|
mApnEditorUT.mPassword = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mMmsc = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mMcc = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mMnc = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mMmsProxy = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mMmsPort = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mAuthType = new ListPreference(context);
|
||||||
|
mApnEditorUT.mApnType = new EditTextPreference(context);
|
||||||
|
mApnEditorUT.mProtocol = new ListPreference(context);
|
||||||
|
mApnEditorUT.mRoamingProtocol = new ListPreference(context);
|
||||||
|
mApnEditorUT.mCarrierEnabled = new SwitchPreference(context);
|
||||||
|
mApnEditorUT.mBearerMulti = new MultiSelectListPreference(context);
|
||||||
|
mApnEditorUT.mMvnoType = new ListPreference(context);
|
||||||
|
mApnEditorUT.mMvnoMatchData = new EditTextPreference(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidTypeException.class)
|
private final class FakeApnData extends ApnData {
|
||||||
public void testApnData_invalidStringType_throwsInvalidTypeException() {
|
FakeApnData(Object[] data) {
|
||||||
// GIVEN a ApnData constructed from cursor
|
super(data.length);
|
||||||
ApnData data = new ApnData(mApnUri, mCursor);
|
System.arraycopy(data, 0, mData, 0, data.length);
|
||||||
|
|
||||||
// WHEN get a integer from a string column
|
|
||||||
// THEN the InvalidTypeException is threw
|
|
||||||
data.getInteger(CURSOR_STRING_INDEX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
FakeApnData(Object[] data, Uri uri) {
|
||||||
public void testApnData_validIntegerType_returnCorrectValue() {
|
this(data);
|
||||||
// GIVEN a ApnData constructed from cursor
|
mUri = uri;
|
||||||
ApnData data = new ApnData(mApnUri, mCursor);
|
|
||||||
|
|
||||||
// WHEN get integer from an integer column
|
|
||||||
int val = data.getInteger(CURSOR_INTEGER_INDEX);
|
|
||||||
|
|
||||||
// THEN the integer is returned correctly
|
|
||||||
assertEquals(mCursor.getInt(CURSOR_INTEGER_INDEX), val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testApnData_validStringType_returnCorrectValue() {
|
|
||||||
// GIVEN a ApnData constructed from cursor
|
|
||||||
ApnData data = new ApnData(mApnUri, mCursor);
|
|
||||||
|
|
||||||
// WHEN get string from a string column
|
|
||||||
String str = data.getString(CURSOR_STRING_INDEX);
|
|
||||||
|
|
||||||
// THEN the integer is returned correctly
|
|
||||||
assertEquals(mCursor.getString(CURSOR_STRING_INDEX), str);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testApnData_nullValueColumn_returnNull() {
|
|
||||||
// GIVEN a empty ApnData
|
|
||||||
ApnData data = new ApnData(3);
|
|
||||||
|
|
||||||
// WHEN get string value from a null column
|
|
||||||
String str = data.getString(0);
|
|
||||||
|
|
||||||
// THEN the null value is returned
|
|
||||||
assertNull(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user