From 5892792b172a1a492a58bf1629a73e2cdc4ed676 Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Wed, 14 Sep 2016 18:13:13 -0700 Subject: [PATCH] Changes to support read-only apn types. User will not be allowed to add/modify APNs for the read-only types. Bug: 31074581 Change-Id: I954bd68249a93ce9deb0146725c1432ea6cb0f38 --- src/com/android/settings/ApnEditor.java | 118 +++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index 8a963d8801c..333a19538c7 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -24,11 +24,13 @@ import android.app.Dialog; import android.app.DialogFragment; import android.content.ContentUris; import android.content.ContentValues; +import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.os.PersistableBundle; import android.provider.Telephony; import android.support.v14.preference.MultiSelectListPreference; import android.support.v14.preference.SwitchPreference; @@ -36,6 +38,7 @@ import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; +import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -49,8 +52,12 @@ import android.view.View; import android.view.View.OnKeyListener; import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.util.ArrayUtils; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; public class ApnEditor extends SettingsPreferenceFragment @@ -105,6 +112,8 @@ public class ApnEditor extends SettingsPreferenceFragment private int mBearerInitialVal = 0; private String mMvnoTypeStr; private String mMvnoMatchDataStr; + private String[] mReadOnlyApnTypes; + private boolean mReadOnlyApn; /** * Standard projection for the interesting columns of a normal note. @@ -132,7 +141,8 @@ public class ApnEditor extends SettingsPreferenceFragment Telephony.Carriers.BEARER_BITMASK, // 19 Telephony.Carriers.ROAMING_PROTOCOL, // 20 Telephony.Carriers.MVNO_TYPE, // 21 - Telephony.Carriers.MVNO_MATCH_DATA // 22 + Telephony.Carriers.MVNO_MATCH_DATA, // 22 + Telephony.Carriers.EDITED // 23 }; private static final int ID_INDEX = 0; @@ -157,6 +167,7 @@ public class ApnEditor extends SettingsPreferenceFragment private static final int ROAMING_PROTOCOL_INDEX = 20; private static final int MVNO_TYPE_INDEX = 21; private static final int MVNO_MATCH_DATA_INDEX = 22; + private static final int EDITED_INDEX = 23; @Override @@ -206,6 +217,8 @@ public class ApnEditor extends SettingsPreferenceFragment SubscriptionManager.INVALID_SUBSCRIPTION_ID); mFirstTime = icicle == null; + mReadOnlyApn = false; + mReadOnlyApnTypes = null; if (action.equals(Intent.ACTION_EDIT)) { Uri uri = intent.getData(); @@ -214,6 +227,15 @@ public class ApnEditor extends SettingsPreferenceFragment finish(); return; } + CarrierConfigManager configManager = (CarrierConfigManager) + getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager != null) { + PersistableBundle b = configManager.getConfig(); + if (b != null) { + mReadOnlyApnTypes = b.getStringArray( + CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY); + } + } mUri = uri; } else if (action.equals(Intent.ACTION_INSERT)) { if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { @@ -255,6 +277,17 @@ public class ApnEditor extends SettingsPreferenceFragment mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + Log.d(TAG, "onCreate: EDITED " + mCursor.getInt(EDITED_INDEX)); + // if it's not a USER_EDITED apn, check if it's read-only + if (mCursor.getInt(EDITED_INDEX) != Telephony.Carriers.USER_EDITED && + apnTypesMatch(mReadOnlyApnTypes, mCursor.getString(TYPE_INDEX))) { + Log.d(TAG, "onCreate: apnTypesMatch; read-only APN"); + mReadOnlyApn = true; + disableAllFields(); + } /* else (if specific fields are read-only) { + disable specific fields + } */ + for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) { getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); } @@ -262,6 +295,87 @@ public class ApnEditor extends SettingsPreferenceFragment fillUi(); } + /** + * Check if passed in array of APN types indicates all APN types + * @param apnTypes array of APN types. "*" indicates all types. + * @return true if all apn types are included in the array, false otherwise + */ + private boolean hasAllApns(String[] apnTypes) { + if (ArrayUtils.isEmpty(apnTypes)) { + return false; + } + + List apnList = Arrays.asList(apnTypes); + if (apnList.contains(PhoneConstants.APN_TYPE_ALL)) { + Log.d(TAG, "hasAllApns: true because apnList.contains(PhoneConstants.APN_TYPE_ALL)"); + return true; + } + for (String apn : PhoneConstants.APN_TYPES) { + if (!apnList.contains(apn)) { + return false; + } + } + + Log.d(TAG, "hasAllApns: true"); + return true; + } + + /** + * Check if APN types overlap. + * @param apnTypesArray1 array of APNs. Empty array indicates no APN type; "*" indicates all + * types + * @param apnTypes2 comma separated string of APN types. Empty string represents all types. + * @return if any apn type matches return true, otherwise return false + */ + private boolean apnTypesMatch(String[] apnTypesArray1, String apnTypes2) { + if (ArrayUtils.isEmpty(apnTypesArray1)) { + return false; + } + + if (hasAllApns(apnTypesArray1) || TextUtils.isEmpty(apnTypes2)) { + return true; + } + + List apnTypesList1 = Arrays.asList(apnTypesArray1); + String[] apnTypesArray2 = apnTypes2.split(","); + + for (String apn : apnTypesArray2) { + if (apnTypesList1.contains(apn.trim())) { + Log.d(TAG, "apnTypesMatch: true because match found for " + apn.trim()); + return true; + } + } + + Log.d(TAG, "apnTypesMatch: false"); + return false; + } + + /** + * Disables all fields so that user cannot modify the APN + */ + private void disableAllFields() { + mName.setEnabled(false); + mApn.setEnabled(false); + mProxy.setEnabled(false); + mPort.setEnabled(false); + mUser.setEnabled(false); + mServer.setEnabled(false); + mPassword.setEnabled(false); + mMmsProxy.setEnabled(false); + mMmsPort.setEnabled(false); + mMmsc.setEnabled(false); + mMcc.setEnabled(false); + mMnc.setEnabled(false); + mApnType.setEnabled(false); + mAuthType.setEnabled(false); + mProtocol.setEnabled(false); + mRoamingProtocol.setEnabled(false); + mCarrierEnabled.setEnabled(false); + mBearerMulti.setEnabled(false); + mMvnoType.setEnabled(false); + mMvnoMatchData.setEnabled(false); + } + @Override protected int getMetricsCategory() { return MetricsEvent.APN_EDITOR; @@ -537,7 +651,7 @@ public class ApnEditor extends SettingsPreferenceFragment public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); // If it's a new APN, then cancel will delete the new entry in onPause - if (!mNewApn) { + if (!mNewApn && !mReadOnlyApn) { menu.add(0, MENU_DELETE, 0, R.string.menu_delete) .setIcon(R.drawable.ic_menu_delete); }