blob: 50a7a77309a1906f801a27d84be3a80e7ce9e784 [file] [log] [blame]
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings;
18
19import android.app.AlertDialog;
Jiehua.Dai20108e22010-05-12 08:37:52 +020020import android.app.Dialog;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080021import android.content.ContentUris;
22import android.content.ContentValues;
Amit Mahajan58927922016-09-14 18:13:13 -070023import android.content.Context;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080024import android.content.Intent;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080025import android.content.res.Resources;
26import android.database.Cursor;
27import android.net.Uri;
28import android.os.Bundle;
Amit Mahajan58927922016-09-14 18:13:13 -070029import android.os.PersistableBundle;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080030import android.provider.Telephony;
Jason Monk39b46742015-09-10 15:52:51 -040031import android.support.v14.preference.MultiSelectListPreference;
32import android.support.v14.preference.SwitchPreference;
33import android.support.v7.preference.EditTextPreference;
34import android.support.v7.preference.ListPreference;
35import android.support.v7.preference.Preference;
Jason Monkb7e43802016-06-06 16:01:58 -040036import android.support.v7.preference.Preference.OnPreferenceChangeListener;
Amit Mahajan58927922016-09-14 18:13:13 -070037import android.telephony.CarrierConfigManager;
Amit Mahajan7e282212015-04-16 10:01:25 -070038import android.telephony.ServiceState;
Mick Lin09c9e5e2015-01-22 17:28:43 +080039import android.telephony.SubscriptionManager;
John Huangd0de4272011-10-15 22:41:11 -070040import android.telephony.TelephonyManager;
Amit Mahajan7e282212015-04-16 10:01:25 -070041import android.text.TextUtils;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080042import android.util.Log;
43import android.view.KeyEvent;
44import android.view.Menu;
Jason Monkb7e43802016-06-06 16:01:58 -040045import android.view.MenuInflater;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080046import android.view.MenuItem;
Jason Monkb7e43802016-06-06 16:01:58 -040047import android.view.View;
48import android.view.View.OnKeyListener;
49
Tamas Berghammer265d3c22016-06-22 15:34:45 +010050import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Fan Zhangac5e5932016-08-24 18:13:33 -070051import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
Amit Mahajan58927922016-09-14 18:13:13 -070052import com.android.internal.telephony.PhoneConstants;
53import com.android.internal.util.ArrayUtils;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080054
TreeHugger Robot94714cf2017-06-19 23:21:12 +000055import java.util.ArrayList;
Amit Mahajan58927922016-09-14 18:13:13 -070056import java.util.Arrays;
Amit Mahajan7e282212015-04-16 10:01:25 -070057import java.util.HashSet;
Amit Mahajan58927922016-09-14 18:13:13 -070058import java.util.List;
Amit Mahajan7e282212015-04-16 10:01:25 -070059import java.util.Set;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070060
Fan Zhangac5e5932016-08-24 18:13:33 -070061import static android.app.Activity.RESULT_OK;
62import static android.content.Context.TELEPHONY_SERVICE;
63
Jason Monkb7e43802016-06-06 16:01:58 -040064public class ApnEditor extends SettingsPreferenceFragment
65 implements OnPreferenceChangeListener, OnKeyListener {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080066
67 private final static String TAG = ApnEditor.class.getSimpleName();
Amit Mahajan657c2372017-04-27 14:50:39 -070068 private final static boolean VDBG = false; // STOPSHIP if true
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070069
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080070 private final static String SAVED_POS = "pos";
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070071 private final static String KEY_AUTH_TYPE = "auth_type";
Lorenzo Colittia7e587f2010-12-29 15:52:41 -080072 private final static String KEY_PROTOCOL = "apn_protocol";
John Huangd0de4272011-10-15 22:41:11 -070073 private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol";
sinikangcd8b7c32011-09-08 15:44:09 -070074 private final static String KEY_CARRIER_ENABLED = "carrier_enabled";
Amit Mahajan7e282212015-04-16 10:01:25 -070075 private final static String KEY_BEARER_MULTI = "bearer_multi";
Sungmin Choiaa4d4c62013-01-30 13:53:03 +090076 private final static String KEY_MVNO_TYPE = "mvno_type";
Amit Mahajan91fb4802016-05-25 13:22:18 -070077 private final static String KEY_PASSWORD = "apn_password";
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070078
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080079 private static final int MENU_DELETE = Menu.FIRST;
80 private static final int MENU_SAVE = Menu.FIRST + 1;
81 private static final int MENU_CANCEL = Menu.FIRST + 2;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070082
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080083 private static String sNotSet;
84 private EditTextPreference mName;
85 private EditTextPreference mApn;
86 private EditTextPreference mProxy;
87 private EditTextPreference mPort;
88 private EditTextPreference mUser;
89 private EditTextPreference mServer;
90 private EditTextPreference mPassword;
91 private EditTextPreference mMmsc;
92 private EditTextPreference mMcc;
93 private EditTextPreference mMnc;
94 private EditTextPreference mMmsProxy;
95 private EditTextPreference mMmsPort;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -070096 private ListPreference mAuthType;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080097 private EditTextPreference mApnType;
Lorenzo Colittia7e587f2010-12-29 15:52:41 -080098 private ListPreference mProtocol;
John Huangd0de4272011-10-15 22:41:11 -070099 private ListPreference mRoamingProtocol;
Fabrice Di Megliodaef2e22014-10-15 19:00:35 -0700100 private SwitchPreference mCarrierEnabled;
Amit Mahajan7e282212015-04-16 10:01:25 -0700101 private MultiSelectListPreference mBearerMulti;
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900102 private ListPreference mMvnoType;
103 private EditTextPreference mMvnoMatchData;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700104
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800105 private String mCurMnc;
106 private String mCurMcc;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700107
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800108 private Uri mUri;
109 private Cursor mCursor;
110 private boolean mNewApn;
111 private boolean mFirstTime;
Mick Lin09c9e5e2015-01-22 17:28:43 +0800112 private int mSubId;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800113 private Resources mRes;
Sungmin Choicd1cb162013-03-21 15:42:27 +0900114 private TelephonyManager mTelephonyManager;
Amit Mahajan7e282212015-04-16 10:01:25 -0700115 private int mBearerInitialVal = 0;
Amit Mahajan17b0c482015-05-12 16:02:22 -0700116 private String mMvnoTypeStr;
117 private String mMvnoMatchDataStr;
Amit Mahajan58927922016-09-14 18:13:13 -0700118 private String[] mReadOnlyApnTypes;
Amit Mahajan7c013442016-09-20 10:59:16 -0700119 private String[] mReadOnlyApnFields;
Amit Mahajan58927922016-09-14 18:13:13 -0700120 private boolean mReadOnlyApn;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700121
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800122 /**
123 * Standard projection for the interesting columns of a normal note.
124 */
125 private static final String[] sProjection = new String[] {
126 Telephony.Carriers._ID, // 0
127 Telephony.Carriers.NAME, // 1
128 Telephony.Carriers.APN, // 2
129 Telephony.Carriers.PROXY, // 3
130 Telephony.Carriers.PORT, // 4
131 Telephony.Carriers.USER, // 5
132 Telephony.Carriers.SERVER, // 6
133 Telephony.Carriers.PASSWORD, // 7
134 Telephony.Carriers.MMSC, // 8
135 Telephony.Carriers.MCC, // 9
136 Telephony.Carriers.MNC, // 10
137 Telephony.Carriers.NUMERIC, // 11
138 Telephony.Carriers.MMSPROXY,// 12
139 Telephony.Carriers.MMSPORT, // 13
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700140 Telephony.Carriers.AUTH_TYPE, // 14
141 Telephony.Carriers.TYPE, // 15
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800142 Telephony.Carriers.PROTOCOL, // 16
sinikangcd8b7c32011-09-08 15:44:09 -0700143 Telephony.Carriers.CARRIER_ENABLED, // 17
144 Telephony.Carriers.BEARER, // 18
Amit Mahajan7e282212015-04-16 10:01:25 -0700145 Telephony.Carriers.BEARER_BITMASK, // 19
146 Telephony.Carriers.ROAMING_PROTOCOL, // 20
147 Telephony.Carriers.MVNO_TYPE, // 21
Amit Mahajan58927922016-09-14 18:13:13 -0700148 Telephony.Carriers.MVNO_MATCH_DATA, // 22
Amit Mahajan313c9402017-07-17 18:23:53 -0700149 Telephony.Carriers.EDITED, // 23
150 Telephony.Carriers.USER_EDITABLE //24
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800151 };
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700152
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800153 private static final int ID_INDEX = 0;
154 private static final int NAME_INDEX = 1;
155 private static final int APN_INDEX = 2;
156 private static final int PROXY_INDEX = 3;
157 private static final int PORT_INDEX = 4;
158 private static final int USER_INDEX = 5;
159 private static final int SERVER_INDEX = 6;
160 private static final int PASSWORD_INDEX = 7;
161 private static final int MMSC_INDEX = 8;
162 private static final int MCC_INDEX = 9;
163 private static final int MNC_INDEX = 10;
164 private static final int MMSPROXY_INDEX = 12;
165 private static final int MMSPORT_INDEX = 13;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700166 private static final int AUTH_TYPE_INDEX = 14;
167 private static final int TYPE_INDEX = 15;
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800168 private static final int PROTOCOL_INDEX = 16;
sinikangcd8b7c32011-09-08 15:44:09 -0700169 private static final int CARRIER_ENABLED_INDEX = 17;
170 private static final int BEARER_INDEX = 18;
Amit Mahajan7e282212015-04-16 10:01:25 -0700171 private static final int BEARER_BITMASK_INDEX = 19;
172 private static final int ROAMING_PROTOCOL_INDEX = 20;
173 private static final int MVNO_TYPE_INDEX = 21;
174 private static final int MVNO_MATCH_DATA_INDEX = 22;
Amit Mahajan58927922016-09-14 18:13:13 -0700175 private static final int EDITED_INDEX = 23;
Amit Mahajan313c9402017-07-17 18:23:53 -0700176 private static final int USER_EDITABLE_INDEX = 24;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700177
178
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800179 @Override
Jason Monkb7e43802016-06-06 16:01:58 -0400180 public void onCreate(Bundle icicle) {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800181 super.onCreate(icicle);
182
183 addPreferencesFromResource(R.xml.apn_editor);
184
185 sNotSet = getResources().getString(R.string.apn_not_set);
186 mName = (EditTextPreference) findPreference("apn_name");
187 mApn = (EditTextPreference) findPreference("apn_apn");
188 mProxy = (EditTextPreference) findPreference("apn_http_proxy");
189 mPort = (EditTextPreference) findPreference("apn_http_port");
190 mUser = (EditTextPreference) findPreference("apn_user");
191 mServer = (EditTextPreference) findPreference("apn_server");
Amit Mahajan91fb4802016-05-25 13:22:18 -0700192 mPassword = (EditTextPreference) findPreference(KEY_PASSWORD);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800193 mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy");
194 mMmsPort = (EditTextPreference) findPreference("apn_mms_port");
195 mMmsc = (EditTextPreference) findPreference("apn_mmsc");
196 mMcc = (EditTextPreference) findPreference("apn_mcc");
197 mMnc = (EditTextPreference) findPreference("apn_mnc");
198 mApnType = (EditTextPreference) findPreference("apn_type");
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800199 mAuthType = (ListPreference) findPreference(KEY_AUTH_TYPE);
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800200 mProtocol = (ListPreference) findPreference(KEY_PROTOCOL);
John Huangd0de4272011-10-15 22:41:11 -0700201 mRoamingProtocol = (ListPreference) findPreference(KEY_ROAMING_PROTOCOL);
Fabrice Di Megliodaef2e22014-10-15 19:00:35 -0700202 mCarrierEnabled = (SwitchPreference) findPreference(KEY_CARRIER_ENABLED);
Amit Mahajan7e282212015-04-16 10:01:25 -0700203 mBearerMulti = (MultiSelectListPreference) findPreference(KEY_BEARER_MULTI);
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900204 mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE);
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900205 mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
206
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800207 mRes = getResources();
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700208
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800209 final Intent intent = getIntent();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800210 final String action = intent.getAction();
Amit Mahajan17b0c482015-05-12 16:02:22 -0700211 mSubId = intent.getIntExtra(ApnSettings.SUB_ID,
212 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800213
214 mFirstTime = icicle == null;
Amit Mahajan58927922016-09-14 18:13:13 -0700215 mReadOnlyApn = false;
216 mReadOnlyApnTypes = null;
Amit Mahajan7c013442016-09-20 10:59:16 -0700217 mReadOnlyApnFields = null;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700218
Amit Mahajan1eee1f82017-05-09 22:31:13 -0700219 CarrierConfigManager configManager = (CarrierConfigManager)
220 getSystemService(Context.CARRIER_CONFIG_SERVICE);
221 if (configManager != null) {
222 PersistableBundle b = configManager.getConfig();
223 if (b != null) {
224 mReadOnlyApnTypes = b.getStringArray(
225 CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY);
TreeHugger Robot94714cf2017-06-19 23:21:12 +0000226 if (!ArrayUtils.isEmpty(mReadOnlyApnTypes)) {
227 for (String apnType : mReadOnlyApnTypes) {
228 Log.d(TAG, "onCreate: read only APN type: " + apnType);
229 }
230 }
Amit Mahajan1eee1f82017-05-09 22:31:13 -0700231 mReadOnlyApnFields = b.getStringArray(
232 CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY);
233 }
234 }
235
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800236 if (action.equals(Intent.ACTION_EDIT)) {
Amit Mahajan21742872015-10-28 13:43:01 -0700237 Uri uri = intent.getData();
238 if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
239 Log.e(TAG, "Edit request not for carrier table. Uri: " + uri);
240 finish();
241 return;
242 }
243 mUri = uri;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800244 } else if (action.equals(Intent.ACTION_INSERT)) {
Amith Yamasani4d312882009-10-28 16:59:17 -0700245 if (mFirstTime || icicle.getInt(SAVED_POS) == 0) {
Amit Mahajan21742872015-10-28 13:43:01 -0700246 Uri uri = intent.getData();
247 if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
248 Log.e(TAG, "Insert request not for carrier table. Uri: " + uri);
249 finish();
250 return;
251 }
252 mUri = getContentResolver().insert(uri, new ContentValues());
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800253 } else {
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700254 mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI,
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800255 icicle.getInt(SAVED_POS));
256 }
257 mNewApn = true;
Amit Mahajan17b0c482015-05-12 16:02:22 -0700258 mMvnoTypeStr = intent.getStringExtra(ApnSettings.MVNO_TYPE);
259 mMvnoMatchDataStr = intent.getStringExtra(ApnSettings.MVNO_MATCH_DATA);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800260 // If we were unable to create a new note, then just finish
261 // this activity. A RESULT_CANCELED will be sent back to the
262 // original activity if they requested a result.
263 if (mUri == null) {
264 Log.w(TAG, "Failed to insert new telephony provider into "
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800265 + getIntent().getData());
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800266 finish();
267 return;
268 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700269
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800270 // The new entry was created, so assume all will end well and
271 // set the result to be returned.
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800272 setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800273
274 } else {
275 finish();
276 return;
277 }
278
Jason Monkb7e43802016-06-06 16:01:58 -0400279 mCursor = getActivity().managedQuery(mUri, sProjection, null, null);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800280 mCursor.moveToFirst();
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700281
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800282 mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
Sungmin Choicd1cb162013-03-21 15:42:27 +0900283
Amit Mahajan58927922016-09-14 18:13:13 -0700284 Log.d(TAG, "onCreate: EDITED " + mCursor.getInt(EDITED_INDEX));
285 // if it's not a USER_EDITED apn, check if it's read-only
286 if (mCursor.getInt(EDITED_INDEX) != Telephony.Carriers.USER_EDITED &&
Amit Mahajan313c9402017-07-17 18:23:53 -0700287 (mCursor.getInt(USER_EDITABLE_INDEX) == 0 ||
288 apnTypesMatch(mReadOnlyApnTypes, mCursor.getString(TYPE_INDEX)))) {
Amit Mahajan58927922016-09-14 18:13:13 -0700289 Log.d(TAG, "onCreate: apnTypesMatch; read-only APN");
290 mReadOnlyApn = true;
291 disableAllFields();
Amit Mahajan7c013442016-09-20 10:59:16 -0700292 } else if (!ArrayUtils.isEmpty(mReadOnlyApnFields)) {
293 disableFields(mReadOnlyApnFields);
294 }
Amit Mahajan58927922016-09-14 18:13:13 -0700295
Jason Monkd2e75e02016-02-17 17:27:23 -0500296 for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
297 getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this);
298 }
299
Malcolm Chen26938b32017-09-11 17:48:14 -0700300 }
301
302 @Override
303 public void onActivityCreated(Bundle savedInstanceState) {
304 super.onActivityCreated(savedInstanceState);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800305 fillUi();
306 }
307
Amit Mahajan58927922016-09-14 18:13:13 -0700308 /**
309 * Check if passed in array of APN types indicates all APN types
310 * @param apnTypes array of APN types. "*" indicates all types.
311 * @return true if all apn types are included in the array, false otherwise
312 */
Amit Mahajan1eee1f82017-05-09 22:31:13 -0700313 static boolean hasAllApns(String[] apnTypes) {
Amit Mahajan58927922016-09-14 18:13:13 -0700314 if (ArrayUtils.isEmpty(apnTypes)) {
315 return false;
316 }
317
318 List apnList = Arrays.asList(apnTypes);
319 if (apnList.contains(PhoneConstants.APN_TYPE_ALL)) {
320 Log.d(TAG, "hasAllApns: true because apnList.contains(PhoneConstants.APN_TYPE_ALL)");
321 return true;
322 }
323 for (String apn : PhoneConstants.APN_TYPES) {
324 if (!apnList.contains(apn)) {
325 return false;
326 }
327 }
328
329 Log.d(TAG, "hasAllApns: true");
330 return true;
331 }
332
333 /**
334 * Check if APN types overlap.
335 * @param apnTypesArray1 array of APNs. Empty array indicates no APN type; "*" indicates all
336 * types
337 * @param apnTypes2 comma separated string of APN types. Empty string represents all types.
338 * @return if any apn type matches return true, otherwise return false
339 */
340 private boolean apnTypesMatch(String[] apnTypesArray1, String apnTypes2) {
341 if (ArrayUtils.isEmpty(apnTypesArray1)) {
342 return false;
343 }
344
345 if (hasAllApns(apnTypesArray1) || TextUtils.isEmpty(apnTypes2)) {
346 return true;
347 }
348
349 List apnTypesList1 = Arrays.asList(apnTypesArray1);
350 String[] apnTypesArray2 = apnTypes2.split(",");
351
352 for (String apn : apnTypesArray2) {
353 if (apnTypesList1.contains(apn.trim())) {
354 Log.d(TAG, "apnTypesMatch: true because match found for " + apn.trim());
355 return true;
356 }
357 }
358
359 Log.d(TAG, "apnTypesMatch: false");
360 return false;
361 }
362
363 /**
Amit Mahajan7c013442016-09-20 10:59:16 -0700364 * Function to get Preference obj corresponding to an apnField
365 * @param apnField apn field name for which pref is needed
366 * @return Preference obj corresponding to passed in apnField
367 */
368 private Preference getPreferenceFromFieldName(String apnField) {
369 switch (apnField) {
370 case Telephony.Carriers.NAME:
371 return mName;
372 case Telephony.Carriers.APN:
373 return mApn;
374 case Telephony.Carriers.PROXY:
375 return mProxy;
376 case Telephony.Carriers.PORT:
377 return mPort;
378 case Telephony.Carriers.USER:
379 return mUser;
380 case Telephony.Carriers.SERVER:
381 return mServer;
382 case Telephony.Carriers.PASSWORD:
383 return mPassword;
384 case Telephony.Carriers.MMSPROXY:
385 return mMmsProxy;
386 case Telephony.Carriers.MMSPORT:
387 return mMmsPort;
388 case Telephony.Carriers.MMSC:
389 return mMmsc;
390 case Telephony.Carriers.MCC:
391 return mMcc;
392 case Telephony.Carriers.MNC:
393 return mMnc;
394 case Telephony.Carriers.TYPE:
395 return mApnType;
396 case Telephony.Carriers.AUTH_TYPE:
397 return mAuthType;
398 case Telephony.Carriers.PROTOCOL:
399 return mProtocol;
400 case Telephony.Carriers.ROAMING_PROTOCOL:
401 return mRoamingProtocol;
402 case Telephony.Carriers.CARRIER_ENABLED:
403 return mCarrierEnabled;
404 case Telephony.Carriers.BEARER:
405 case Telephony.Carriers.BEARER_BITMASK:
406 return mBearerMulti;
407 case Telephony.Carriers.MVNO_TYPE:
408 return mMvnoType;
409 case Telephony.Carriers.MVNO_MATCH_DATA:
410 return mMvnoMatchData;
411 }
412 return null;
413 }
414
415 /**
416 * Disables given fields so that user cannot modify them
417 *
418 * @param apnFields fields to be disabled
419 */
420 private void disableFields(String[] apnFields) {
421 for (String apnField : apnFields) {
422 Preference preference = getPreferenceFromFieldName(apnField);
423 if (preference != null) {
424 preference.setEnabled(false);
425 }
426 }
427 }
428
429 /**
Amit Mahajan58927922016-09-14 18:13:13 -0700430 * Disables all fields so that user cannot modify the APN
431 */
432 private void disableAllFields() {
433 mName.setEnabled(false);
434 mApn.setEnabled(false);
435 mProxy.setEnabled(false);
436 mPort.setEnabled(false);
437 mUser.setEnabled(false);
438 mServer.setEnabled(false);
439 mPassword.setEnabled(false);
440 mMmsProxy.setEnabled(false);
441 mMmsPort.setEnabled(false);
442 mMmsc.setEnabled(false);
443 mMcc.setEnabled(false);
444 mMnc.setEnabled(false);
445 mApnType.setEnabled(false);
446 mAuthType.setEnabled(false);
447 mProtocol.setEnabled(false);
448 mRoamingProtocol.setEnabled(false);
449 mCarrierEnabled.setEnabled(false);
450 mBearerMulti.setEnabled(false);
451 mMvnoType.setEnabled(false);
452 mMvnoMatchData.setEnabled(false);
453 }
454
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800455 @Override
Fan Zhang65076132016-08-08 10:25:13 -0700456 public int getMetricsCategory() {
Chris Wren9d1bfd12016-01-26 18:04:01 -0500457 return MetricsEvent.APN_EDITOR;
Chris Wren8a963ba2015-03-20 10:29:14 -0400458 }
459
460 @Override
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800461 public void onResume() {
462 super.onResume();
yifan.bai28fa4402016-04-11 10:43:41 +0800463
464 if (mUri == null && mNewApn) {
465 // The URI could have been deleted when activity is paused,
466 // therefore, it needs to be restored.
467 mUri = getContentResolver().insert(getIntent().getData(), new ContentValues());
468 if (mUri == null) {
469 Log.w(TAG, "Failed to insert new telephony provider into "
470 + getIntent().getData());
471 finish();
472 return;
473 }
Jason Monke3ce6712016-06-08 16:09:03 -0400474 mCursor = getActivity().managedQuery(mUri, sProjection, null, null);
yifan.bai28fa4402016-04-11 10:43:41 +0800475 mCursor.moveToFirst();
476 }
477
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800478 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700479
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800480 @Override
481 public void onPause() {
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700482 super.onPause();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800483 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700484
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800485 private void fillUi() {
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700486 if (mFirstTime) {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800487 mFirstTime = false;
488 // Fill in all the values from the db in both text editor and summary
489 mName.setText(mCursor.getString(NAME_INDEX));
490 mApn.setText(mCursor.getString(APN_INDEX));
491 mProxy.setText(mCursor.getString(PROXY_INDEX));
492 mPort.setText(mCursor.getString(PORT_INDEX));
493 mUser.setText(mCursor.getString(USER_INDEX));
494 mServer.setText(mCursor.getString(SERVER_INDEX));
495 mPassword.setText(mCursor.getString(PASSWORD_INDEX));
496 mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
497 mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
498 mMmsc.setText(mCursor.getString(MMSC_INDEX));
499 mMcc.setText(mCursor.getString(MCC_INDEX));
500 mMnc.setText(mCursor.getString(MNC_INDEX));
501 mApnType.setText(mCursor.getString(TYPE_INDEX));
502 if (mNewApn) {
Mick Lin09c9e5e2015-01-22 17:28:43 +0800503 String numeric = mTelephonyManager.getSimOperator(mSubId);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800504 // MCC is first 3 chars and then in 2 - 3 chars of MNC
505 if (numeric != null && numeric.length() > 4) {
506 // Country code
507 String mcc = numeric.substring(0, 3);
508 // Network code
509 String mnc = numeric.substring(3);
510 // Auto populate MNC and MCC for new entries, based on what SIM reports
511 mMcc.setText(mcc);
512 mMnc.setText(mnc);
513 mCurMnc = mnc;
514 mCurMcc = mcc;
515 }
516 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700517 int authVal = mCursor.getInt(AUTH_TYPE_INDEX);
518 if (authVal != -1) {
519 mAuthType.setValueIndex(authVal);
Marta Białka19290082010-10-25 15:39:04 +0200520 } else {
521 mAuthType.setValue(null);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700522 }
523
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800524 mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX));
John Huangd0de4272011-10-15 22:41:11 -0700525 mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX));
sinikangcd8b7c32011-09-08 15:44:09 -0700526 mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1);
Amit Mahajan7e282212015-04-16 10:01:25 -0700527 mBearerInitialVal = mCursor.getInt(BEARER_INDEX);
528
529 HashSet<String> bearers = new HashSet<String>();
530 int bearerBitmask = mCursor.getInt(BEARER_BITMASK_INDEX);
531 if (bearerBitmask == 0) {
532 if (mBearerInitialVal == 0) {
533 bearers.add("" + 0);
534 }
535 } else {
536 int i = 1;
537 while (bearerBitmask != 0) {
538 if ((bearerBitmask & 1) == 1) {
539 bearers.add("" + i);
540 }
541 bearerBitmask >>= 1;
542 i++;
543 }
544 }
545
546 if (mBearerInitialVal != 0 && bearers.contains("" + mBearerInitialVal) == false) {
547 // add mBearerInitialVal to bearers
548 bearers.add("" + mBearerInitialVal);
549 }
550 mBearerMulti.setValues(bearers);
551
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900552 mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX));
553 mMvnoMatchData.setEnabled(false);
554 mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX));
Amit Mahajan17b0c482015-05-12 16:02:22 -0700555 if (mNewApn && mMvnoTypeStr != null && mMvnoMatchDataStr != null) {
556 mMvnoType.setValue(mMvnoTypeStr);
557 mMvnoMatchData.setText(mMvnoMatchDataStr);
558 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800559 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700560
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800561 mName.setSummary(checkNull(mName.getText()));
562 mApn.setSummary(checkNull(mApn.getText()));
563 mProxy.setSummary(checkNull(mProxy.getText()));
564 mPort.setSummary(checkNull(mPort.getText()));
565 mUser.setSummary(checkNull(mUser.getText()));
566 mServer.setSummary(checkNull(mServer.getText()));
567 mPassword.setSummary(starify(mPassword.getText()));
568 mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
569 mMmsPort.setSummary(checkNull(mMmsPort.getText()));
570 mMmsc.setSummary(checkNull(mMmsc.getText()));
571 mMcc.setSummary(checkNull(mMcc.getText()));
572 mMnc.setSummary(checkNull(mMnc.getText()));
573 mApnType.setSummary(checkNull(mApnType.getText()));
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700574
575 String authVal = mAuthType.getValue();
576 if (authVal != null) {
577 int authValIndex = Integer.parseInt(authVal);
578 mAuthType.setValueIndex(authValIndex);
579
580 String []values = mRes.getStringArray(R.array.apn_auth_entries);
581 mAuthType.setSummary(values[authValIndex]);
582 } else {
583 mAuthType.setSummary(sNotSet);
584 }
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800585
Amit Mahajan91fb4802016-05-25 13:22:18 -0700586 mProtocol.setSummary(checkNull(protocolDescription(mProtocol.getValue(), mProtocol)));
John Huangd0de4272011-10-15 22:41:11 -0700587 mRoamingProtocol.setSummary(
588 checkNull(protocolDescription(mRoamingProtocol.getValue(), mRoamingProtocol)));
Amit Mahajan7e282212015-04-16 10:01:25 -0700589 mBearerMulti.setSummary(
590 checkNull(bearerMultiDescription(mBearerMulti.getValues())));
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900591 mMvnoType.setSummary(
592 checkNull(mvnoDescription(mMvnoType.getValue())));
593 mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText()));
Jing Zhaof04d69a2014-08-26 14:44:02 -0500594 // allow user to edit carrier_enabled for some APN
595 boolean ceEditable = getResources().getBoolean(R.bool.config_allow_edit_carrier_enabled);
596 if (ceEditable) {
597 mCarrierEnabled.setEnabled(true);
598 } else {
599 mCarrierEnabled.setEnabled(false);
600 }
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800601 }
602
603 /**
604 * Returns the UI choice (e.g., "IPv4/IPv6") corresponding to the given
605 * raw value of the protocol preference (e.g., "IPV4V6"). If unknown,
606 * return null.
607 */
John Huangd0de4272011-10-15 22:41:11 -0700608 private String protocolDescription(String raw, ListPreference protocol) {
609 int protocolIndex = protocol.findIndexOfValue(raw);
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800610 if (protocolIndex == -1) {
611 return null;
612 } else {
613 String[] values = mRes.getStringArray(R.array.apn_protocol_entries);
614 try {
615 return values[protocolIndex];
616 } catch (ArrayIndexOutOfBoundsException e) {
617 return null;
618 }
619 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700620 }
621
sinikangcd8b7c32011-09-08 15:44:09 -0700622 private String bearerDescription(String raw) {
Amit Mahajan7e282212015-04-16 10:01:25 -0700623 int mBearerIndex = mBearerMulti.findIndexOfValue(raw);
sinikangcd8b7c32011-09-08 15:44:09 -0700624 if (mBearerIndex == -1) {
625 return null;
626 } else {
627 String[] values = mRes.getStringArray(R.array.bearer_entries);
628 try {
629 return values[mBearerIndex];
630 } catch (ArrayIndexOutOfBoundsException e) {
631 return null;
632 }
633 }
634 }
635
Amit Mahajan7e282212015-04-16 10:01:25 -0700636 private String bearerMultiDescription(Set<String> raw) {
637 String[] values = mRes.getStringArray(R.array.bearer_entries);
638 StringBuilder retVal = new StringBuilder();
639 boolean first = true;
640 for (String bearer : raw) {
641 int bearerIndex = mBearerMulti.findIndexOfValue(bearer);
642 try {
643 if (first) {
644 retVal.append(values[bearerIndex]);
645 first = false;
646 } else {
647 retVal.append(", " + values[bearerIndex]);
648 }
649 } catch (ArrayIndexOutOfBoundsException e) {
650 // ignore
651 }
652 }
653 String val = retVal.toString();
654 if (!TextUtils.isEmpty(val)) {
655 return val;
656 }
657 return null;
658 }
659
Sungmin Choicd1cb162013-03-21 15:42:27 +0900660 private String mvnoDescription(String newValue) {
661 int mvnoIndex = mMvnoType.findIndexOfValue(newValue);
662 String oldValue = mMvnoType.getValue();
663
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900664 if (mvnoIndex == -1) {
665 return null;
666 } else {
667 String[] values = mRes.getStringArray(R.array.mvno_type_entries);
Amit Mahajana00af972017-08-31 13:59:20 -0700668 boolean mvnoMatchDataUneditable =
669 mReadOnlyApn || (mReadOnlyApnFields != null
670 && Arrays.asList(mReadOnlyApnFields)
671 .contains(Telephony.Carriers.MVNO_MATCH_DATA));
672 mMvnoMatchData.setEnabled(!mvnoMatchDataUneditable && mvnoIndex != 0);
Sungmin Choicd1cb162013-03-21 15:42:27 +0900673 if (newValue != null && newValue.equals(oldValue) == false) {
674 if (values[mvnoIndex].equals("SPN")) {
675 mMvnoMatchData.setText(mTelephonyManager.getSimOperatorName());
676 } else if (values[mvnoIndex].equals("IMSI")) {
Mick Lin09c9e5e2015-01-22 17:28:43 +0800677 String numeric = mTelephonyManager.getSimOperator(mSubId);
Sungmin Choicd1cb162013-03-21 15:42:27 +0900678 mMvnoMatchData.setText(numeric + "x");
679 } else if (values[mvnoIndex].equals("GID")) {
680 mMvnoMatchData.setText(mTelephonyManager.getGroupIdLevel1());
681 }
682 }
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900683
684 try {
685 return values[mvnoIndex];
686 } catch (ArrayIndexOutOfBoundsException e) {
687 return null;
688 }
689 }
690 }
691
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700692 public boolean onPreferenceChange(Preference preference, Object newValue) {
693 String key = preference.getKey();
694 if (KEY_AUTH_TYPE.equals(key)) {
695 try {
696 int index = Integer.parseInt((String) newValue);
697 mAuthType.setValueIndex(index);
698
Jason Monkd2e75e02016-02-17 17:27:23 -0500699 String[] values = mRes.getStringArray(R.array.apn_auth_entries);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700700 mAuthType.setSummary(values[index]);
701 } catch (NumberFormatException e) {
702 return false;
703 }
John Huangd0de4272011-10-15 22:41:11 -0700704 } else if (KEY_PROTOCOL.equals(key)) {
705 String protocol = protocolDescription((String) newValue, mProtocol);
Lorenzo Colittia7e587f2010-12-29 15:52:41 -0800706 if (protocol == null) {
707 return false;
708 }
709 mProtocol.setSummary(protocol);
710 mProtocol.setValue((String) newValue);
John Huangd0de4272011-10-15 22:41:11 -0700711 } else if (KEY_ROAMING_PROTOCOL.equals(key)) {
712 String protocol = protocolDescription((String) newValue, mRoamingProtocol);
713 if (protocol == null) {
714 return false;
715 }
716 mRoamingProtocol.setSummary(protocol);
717 mRoamingProtocol.setValue((String) newValue);
Amit Mahajan7e282212015-04-16 10:01:25 -0700718 } else if (KEY_BEARER_MULTI.equals(key)) {
719 String bearer = bearerMultiDescription((Set<String>) newValue);
sinikangcd8b7c32011-09-08 15:44:09 -0700720 if (bearer == null) {
721 return false;
722 }
Amit Mahajan7e282212015-04-16 10:01:25 -0700723 mBearerMulti.setValues((Set<String>) newValue);
724 mBearerMulti.setSummary(bearer);
Sungmin Choiaa4d4c62013-01-30 13:53:03 +0900725 } else if (KEY_MVNO_TYPE.equals(key)) {
726 String mvno = mvnoDescription((String) newValue);
727 if (mvno == null) {
728 return false;
729 }
730 mMvnoType.setValue((String) newValue);
731 mMvnoType.setSummary(mvno);
Amit Mahajan91fb4802016-05-25 13:22:18 -0700732 } else if (KEY_PASSWORD.equals(key)) {
733 mPassword.setSummary(starify(newValue != null ? String.valueOf(newValue) : ""));
734 } else if (KEY_CARRIER_ENABLED.equals(key)) {
Jason Monkd2e75e02016-02-17 17:27:23 -0500735 // do nothing
736 } else {
737 preference.setSummary(checkNull(newValue != null ? String.valueOf(newValue) : null));
738 }
sinikangcd8b7c32011-09-08 15:44:09 -0700739
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700740 return true;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800741 }
742
743 @Override
Jason Monkb7e43802016-06-06 16:01:58 -0400744 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
745 super.onCreateOptionsMenu(menu, inflater);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800746 // If it's a new APN, then cancel will delete the new entry in onPause
Amit Mahajan58927922016-09-14 18:13:13 -0700747 if (!mNewApn && !mReadOnlyApn) {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800748 menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
Amith Yamasani247520c2014-07-25 12:52:29 -0700749 .setIcon(R.drawable.ic_menu_delete);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800750 }
751 menu.add(0, MENU_SAVE, 0, R.string.menu_save)
752 .setIcon(android.R.drawable.ic_menu_save);
753 menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel)
754 .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800755 }
756
757 @Override
758 public boolean onOptionsItemSelected(MenuItem item) {
759 switch (item.getItemId()) {
760 case MENU_DELETE:
761 deleteApn();
762 return true;
763 case MENU_SAVE:
764 if (validateAndSave(false)) {
765 finish();
766 }
767 return true;
768 case MENU_CANCEL:
769 if (mNewApn) {
770 getContentResolver().delete(mUri, null, null);
771 }
772 finish();
773 return true;
774 }
775 return super.onOptionsItemSelected(item);
776 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700777
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800778 @Override
Jason Monkb7e43802016-06-06 16:01:58 -0400779 public void onViewCreated(View view, Bundle savedInstanceState) {
780 super.onViewCreated(view, savedInstanceState);
781 view.setOnKeyListener(this);
xiaocheng.x.wang7602e882016-08-23 13:53:47 +0800782 view.setFocusableInTouchMode(true);
783 view.requestFocus();
Jason Monkb7e43802016-06-06 16:01:58 -0400784 }
785
786 public boolean onKey(View v, int keyCode, KeyEvent event) {
787 if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800788 switch (keyCode) {
789 case KeyEvent.KEYCODE_BACK: {
790 if (validateAndSave(false)) {
791 finish();
792 }
793 return true;
794 }
795 }
Jason Monkb7e43802016-06-06 16:01:58 -0400796 return false;
Fabrice Di Meglio710e3092014-02-11 18:27:38 -0800797 }
798
799 @Override
Jason Monkb7e43802016-06-06 16:01:58 -0400800 public void onSaveInstanceState(Bundle icicle) {
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800801 super.onSaveInstanceState(icicle);
Amith Yamasani4d312882009-10-28 16:59:17 -0700802 if (validateAndSave(true)) {
803 icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
804 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800805 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700806
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800807 /**
Amit Mahajan657c2372017-04-27 14:50:39 -0700808 * Add key, value to cv and compare the value against the value at index in mCursor. Return true
809 * if values are different. assumeDiff indicates if values can be assumed different in which
810 * case no comparison is needed.
811 * @return true if value is different from the value at index in mCursor
812 */
813 boolean setStringValueAndCheckIfDiff(ContentValues cv, String key, String value,
814 boolean assumeDiff, int index) {
815 cv.put(key, value);
816 String valueFromCursor = mCursor.getString(index);
817 if (VDBG) {
818 Log.d(TAG, "setStringValueAndCheckIfDiff: assumeDiff: " + assumeDiff
819 + " key: " + key
820 + " value: '" + value
821 + "' valueFromCursor: '" + valueFromCursor + "'");
822 }
823 return assumeDiff
824 || !((TextUtils.isEmpty(value) && TextUtils.isEmpty(valueFromCursor))
825 || (value != null && value.equals(valueFromCursor)));
826 }
827
828 /**
829 * Add key, value to cv and compare the value against the value at index in mCursor. Return true
830 * if values are different. assumeDiff indicates if values can be assumed different in which
831 * case no comparison is needed.
832 * @return true if value is different from the value at index in mCursor
833 */
834 boolean setIntValueAndCheckIfDiff(ContentValues cv, String key, int value,
835 boolean assumeDiff, int index) {
836 cv.put(key, value);
837 int valueFromCursor = mCursor.getInt(index);
838 if (VDBG) {
839 Log.d(TAG, "setIntValueAndCheckIfDiff: assumeDiff: " + assumeDiff
840 + " key: " + key
841 + " value: '" + value
842 + "' valueFromCursor: '" + valueFromCursor + "'");
843 }
844 return assumeDiff || value != valueFromCursor;
845 }
846
847 /**
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800848 * Check the key fields' validity and save if valid.
849 * @param force save even if the fields are not valid, if the app is
850 * being suspended
Amit Mahajanb4ac40b2017-04-24 11:02:03 -0700851 * @return true if there's no error
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800852 */
853 private boolean validateAndSave(boolean force) {
Amit Mahajanb4ac40b2017-04-24 11:02:03 -0700854 // nothing to do if it's a read only APN
855 if (mReadOnlyApn) {
856 return true;
857 }
858
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800859 String name = checkNotSet(mName.getText());
860 String apn = checkNotSet(mApn.getText());
861 String mcc = checkNotSet(mMcc.getText());
862 String mnc = checkNotSet(mMnc.getText());
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700863
Jiehua.Dai20108e22010-05-12 08:37:52 +0200864 if (getErrorMsg() != null && !force) {
Jason Monkb7e43802016-06-06 16:01:58 -0400865 ErrorDialog.showError(this);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800866 return false;
867 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700868
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800869 if (!mCursor.moveToFirst()) {
870 Log.w(TAG,
871 "Could not go to the first row in the Cursor when saving data.");
872 return false;
873 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700874
Amith Yamasani4d312882009-10-28 16:59:17 -0700875 // If it's a new APN and a name or apn haven't been entered, then erase the entry
876 if (force && mNewApn && name.length() < 1 && apn.length() < 1) {
877 getContentResolver().delete(mUri, null, null);
yifan.bai28fa4402016-04-11 10:43:41 +0800878 mUri = null;
Amith Yamasani4d312882009-10-28 16:59:17 -0700879 return false;
880 }
881
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800882 ContentValues values = new ContentValues();
Amit Mahajan657c2372017-04-27 14:50:39 -0700883 // call update() if it's a new APN. If not, check if any field differs from the db value;
884 // if any diff is found update() should be called
885 boolean callUpdate = mNewApn;
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700886
Amit Mahajan7e282212015-04-16 10:01:25 -0700887 // Add a dummy name "Untitled", if the user exits the screen without adding a name but
Amith Yamasani4d312882009-10-28 16:59:17 -0700888 // entered other information worth keeping.
Amit Mahajan657c2372017-04-27 14:50:39 -0700889 callUpdate = setStringValueAndCheckIfDiff(values,
890 Telephony.Carriers.NAME,
891 name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name,
892 callUpdate,
893 NAME_INDEX);
894
895 callUpdate = setStringValueAndCheckIfDiff(values,
896 Telephony.Carriers.APN,
897 apn,
898 callUpdate,
899 APN_INDEX);
900
901 callUpdate = setStringValueAndCheckIfDiff(values,
902 Telephony.Carriers.PROXY,
903 checkNotSet(mProxy.getText()),
904 callUpdate,
905 PROXY_INDEX);
906
907 callUpdate = setStringValueAndCheckIfDiff(values,
908 Telephony.Carriers.PORT,
909 checkNotSet(mPort.getText()),
910 callUpdate,
911 PORT_INDEX);
912
913 callUpdate = setStringValueAndCheckIfDiff(values,
914 Telephony.Carriers.MMSPROXY,
915 checkNotSet(mMmsProxy.getText()),
916 callUpdate,
917 MMSPROXY_INDEX);
918
919 callUpdate = setStringValueAndCheckIfDiff(values,
920 Telephony.Carriers.MMSPORT,
921 checkNotSet(mMmsPort.getText()),
922 callUpdate,
923 MMSPORT_INDEX);
924
925 callUpdate = setStringValueAndCheckIfDiff(values,
926 Telephony.Carriers.USER,
927 checkNotSet(mUser.getText()),
928 callUpdate,
929 USER_INDEX);
930
931 callUpdate = setStringValueAndCheckIfDiff(values,
932 Telephony.Carriers.SERVER,
933 checkNotSet(mServer.getText()),
934 callUpdate,
935 SERVER_INDEX);
936
937 callUpdate = setStringValueAndCheckIfDiff(values,
938 Telephony.Carriers.PASSWORD,
939 checkNotSet(mPassword.getText()),
940 callUpdate,
941 PASSWORD_INDEX);
942
943 callUpdate = setStringValueAndCheckIfDiff(values,
944 Telephony.Carriers.MMSC,
945 checkNotSet(mMmsc.getText()),
946 callUpdate,
947 MMSC_INDEX);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700948
949 String authVal = mAuthType.getValue();
950 if (authVal != null) {
Amit Mahajan657c2372017-04-27 14:50:39 -0700951 callUpdate = setIntValueAndCheckIfDiff(values,
952 Telephony.Carriers.AUTH_TYPE,
953 Integer.parseInt(authVal),
954 callUpdate,
955 AUTH_TYPE_INDEX);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700956 }
957
Amit Mahajan657c2372017-04-27 14:50:39 -0700958 callUpdate = setStringValueAndCheckIfDiff(values,
959 Telephony.Carriers.PROTOCOL,
960 checkNotSet(mProtocol.getValue()),
961 callUpdate,
962 PROTOCOL_INDEX);
Lorenzo Colittia52c5692010-12-29 15:52:41 -0800963
Amit Mahajan657c2372017-04-27 14:50:39 -0700964 callUpdate = setStringValueAndCheckIfDiff(values,
965 Telephony.Carriers.ROAMING_PROTOCOL,
966 checkNotSet(mRoamingProtocol.getValue()),
967 callUpdate,
968 ROAMING_PROTOCOL_INDEX);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800969
Amit Mahajan657c2372017-04-27 14:50:39 -0700970 callUpdate = setStringValueAndCheckIfDiff(values,
971 Telephony.Carriers.TYPE,
TreeHugger Robot94714cf2017-06-19 23:21:12 +0000972 checkNotSet(getUserEnteredApnType()),
Amit Mahajan657c2372017-04-27 14:50:39 -0700973 callUpdate,
974 TYPE_INDEX);
975
976 callUpdate = setStringValueAndCheckIfDiff(values,
977 Telephony.Carriers.MCC,
978 mcc,
979 callUpdate,
980 MCC_INDEX);
981
982 callUpdate = setStringValueAndCheckIfDiff(values,
983 Telephony.Carriers.MNC,
984 mnc,
985 callUpdate,
986 MNC_INDEX);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700987
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800988 values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700989
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800990 if (mCurMnc != null && mCurMcc != null) {
991 if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) {
992 values.put(Telephony.Carriers.CURRENT, 1);
993 }
994 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -0700995
Amit Mahajan7e282212015-04-16 10:01:25 -0700996 Set<String> bearerSet = mBearerMulti.getValues();
997 int bearerBitmask = 0;
998 for (String bearer : bearerSet) {
999 if (Integer.parseInt(bearer) == 0) {
1000 bearerBitmask = 0;
1001 break;
1002 } else {
1003 bearerBitmask |= ServiceState.getBitmaskForTech(Integer.parseInt(bearer));
1004 }
sinikangcd8b7c32011-09-08 15:44:09 -07001005 }
Amit Mahajan657c2372017-04-27 14:50:39 -07001006 callUpdate = setIntValueAndCheckIfDiff(values,
1007 Telephony.Carriers.BEARER_BITMASK,
1008 bearerBitmask,
1009 callUpdate,
1010 BEARER_BITMASK_INDEX);
Amit Mahajan7e282212015-04-16 10:01:25 -07001011
1012 int bearerVal;
1013 if (bearerBitmask == 0 || mBearerInitialVal == 0) {
1014 bearerVal = 0;
1015 } else if (ServiceState.bitmaskHasTech(bearerBitmask, mBearerInitialVal)) {
1016 bearerVal = mBearerInitialVal;
1017 } else {
1018 // bearer field was being used but bitmask has changed now and does not include the
1019 // initial bearer value -- setting bearer to 0 but maybe better behavior is to choose a
1020 // random tech from the new bitmask??
1021 bearerVal = 0;
1022 }
Amit Mahajan657c2372017-04-27 14:50:39 -07001023 callUpdate = setIntValueAndCheckIfDiff(values,
1024 Telephony.Carriers.BEARER,
1025 bearerVal,
1026 callUpdate,
1027 BEARER_INDEX);
sinikangcd8b7c32011-09-08 15:44:09 -07001028
Amit Mahajan657c2372017-04-27 14:50:39 -07001029 callUpdate = setStringValueAndCheckIfDiff(values,
1030 Telephony.Carriers.MVNO_TYPE,
1031 checkNotSet(mMvnoType.getValue()),
1032 callUpdate,
1033 MVNO_TYPE_INDEX);
Sungmin Choiaa4d4c62013-01-30 13:53:03 +09001034
Amit Mahajan657c2372017-04-27 14:50:39 -07001035 callUpdate = setStringValueAndCheckIfDiff(values,
1036 Telephony.Carriers.MVNO_MATCH_DATA,
1037 checkNotSet(mMvnoMatchData.getText()),
1038 callUpdate,
1039 MVNO_MATCH_DATA_INDEX);
1040
1041 callUpdate = setIntValueAndCheckIfDiff(values,
1042 Telephony.Carriers.CARRIER_ENABLED,
1043 mCarrierEnabled.isChecked() ? 1 : 0,
1044 callUpdate,
1045 CARRIER_ENABLED_INDEX);
1046
1047 if (callUpdate) {
1048 getContentResolver().update(mUri, values, null, null);
1049 } else {
1050 if (VDBG) Log.d(TAG, "validateAndSave: not calling update()");
1051 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -07001052
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001053 return true;
1054 }
1055
Jiehua.Dai20108e22010-05-12 08:37:52 +02001056 private String getErrorMsg() {
1057 String errorMsg = null;
1058
1059 String name = checkNotSet(mName.getText());
1060 String apn = checkNotSet(mApn.getText());
1061 String mcc = checkNotSet(mMcc.getText());
1062 String mnc = checkNotSet(mMnc.getText());
1063
1064 if (name.length() < 1) {
1065 errorMsg = mRes.getString(R.string.error_name_empty);
1066 } else if (apn.length() < 1) {
1067 errorMsg = mRes.getString(R.string.error_apn_empty);
1068 } else if (mcc.length() != 3) {
1069 errorMsg = mRes.getString(R.string.error_mcc_not3);
1070 } else if ((mnc.length() & 0xFFFE) != 2) {
1071 errorMsg = mRes.getString(R.string.error_mnc_not23);
1072 }
1073
Amit Mahajan1eee1f82017-05-09 22:31:13 -07001074 if (errorMsg == null) {
1075 // if carrier does not allow editing certain apn types, make sure type does not include
1076 // those
Amit Mahajan7243db22017-06-01 16:39:40 -07001077 if (!ArrayUtils.isEmpty(mReadOnlyApnTypes)
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001078 && apnTypesMatch(mReadOnlyApnTypes, getUserEnteredApnType())) {
Amit Mahajan1eee1f82017-05-09 22:31:13 -07001079 StringBuilder stringBuilder = new StringBuilder();
1080 for (String type : mReadOnlyApnTypes) {
1081 stringBuilder.append(type).append(", ");
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001082 Log.d(TAG, "getErrorMsg: appending type: " + type);
Amit Mahajan1eee1f82017-05-09 22:31:13 -07001083 }
1084 // remove last ", "
1085 if (stringBuilder.length() >= 2) {
1086 stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length());
1087 }
1088 errorMsg = String.format(mRes.getString(R.string.error_adding_apn_type),
1089 stringBuilder);
1090 }
1091 }
1092
Jiehua.Dai20108e22010-05-12 08:37:52 +02001093 return errorMsg;
1094 }
1095
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001096 private void deleteApn() {
1097 getContentResolver().delete(mUri, null, null);
1098 finish();
1099 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -07001100
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001101 private String starify(String value) {
1102 if (value == null || value.length() == 0) {
1103 return sNotSet;
1104 } else {
1105 char[] password = new char[value.length()];
1106 for (int i = 0; i < password.length; i++) {
1107 password[i] = '*';
1108 }
1109 return new String(password);
1110 }
1111 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -07001112
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001113 private String checkNull(String value) {
1114 if (value == null || value.length() == 0) {
1115 return sNotSet;
1116 } else {
1117 return value;
1118 }
1119 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -07001120
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001121 private String checkNotSet(String value) {
1122 if (value == null || value.equals(sNotSet)) {
1123 return "";
1124 } else {
1125 return value;
1126 }
1127 }
Jaikumar Ganesh195bc432009-10-26 13:01:36 -07001128
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001129 private String getUserEnteredApnType() {
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001130 // if user has not specified a type, map it to "ALL APN TYPES THAT ARE NOT READ-ONLY"
Amit Mahajan9eac2f72017-08-02 09:59:03 -07001131 String userEnteredApnType = mApnType.getText();
1132 if (userEnteredApnType != null) userEnteredApnType = userEnteredApnType.trim();
1133 if ((TextUtils.isEmpty(userEnteredApnType)
1134 || PhoneConstants.APN_TYPE_ALL.equals(userEnteredApnType))
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001135 && !ArrayUtils.isEmpty(mReadOnlyApnTypes)) {
1136 StringBuilder editableApnTypes = new StringBuilder();
1137 List<String> readOnlyApnTypes = Arrays.asList(mReadOnlyApnTypes);
1138 boolean first = true;
1139 for (String apnType : PhoneConstants.APN_TYPES) {
1140 // add APN type if it is not read-only and is not wild-cardable
1141 if (!readOnlyApnTypes.contains(apnType)
1142 && !apnType.equals(PhoneConstants.APN_TYPE_IA)
1143 && !apnType.equals(PhoneConstants.APN_TYPE_EMERGENCY)) {
1144 if (first) {
1145 first = false;
1146 } else {
1147 editableApnTypes.append(",");
1148 }
1149 editableApnTypes.append(apnType);
1150 }
1151 }
Amit Mahajan9eac2f72017-08-02 09:59:03 -07001152 userEnteredApnType = editableApnTypes.toString();
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001153 Log.d(TAG, "getUserEnteredApnType: changed apn type to editable apn types: "
Amit Mahajan9eac2f72017-08-02 09:59:03 -07001154 + userEnteredApnType);
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001155 }
1156
Amit Mahajan9eac2f72017-08-02 09:59:03 -07001157 return userEnteredApnType;
TreeHugger Robot94714cf2017-06-19 23:21:12 +00001158 }
1159
Fan Zhangac5e5932016-08-24 18:13:33 -07001160 public static class ErrorDialog extends InstrumentedDialogFragment {
Jason Monkb7e43802016-06-06 16:01:58 -04001161
1162 public static void showError(ApnEditor editor) {
1163 ErrorDialog dialog = new ErrorDialog();
1164 dialog.setTargetFragment(editor, 0);
1165 dialog.show(editor.getFragmentManager(), "error");
1166 }
1167
1168 @Override
1169 public Dialog onCreateDialog(Bundle savedInstanceState) {
1170 String msg = ((ApnEditor) getTargetFragment()).getErrorMsg();
1171
1172 return new AlertDialog.Builder(getContext())
1173 .setTitle(R.string.error_title)
1174 .setPositiveButton(android.R.string.ok, null)
1175 .setMessage(msg)
1176 .create();
1177 }
Fan Zhangac5e5932016-08-24 18:13:33 -07001178
1179 @Override
1180 public int getMetricsCategory() {
1181 return MetricsEvent.DIALOG_APN_EDITOR_ERROR;
1182 }
Jason Monkb7e43802016-06-06 16:01:58 -04001183 }
1184
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001185}