Loading src/com/android/settings/ApnEditor.java +116 −2 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.app.Dialog; import android.app.DialogFragment; import android.app.DialogFragment; import android.content.ContentUris; import android.content.ContentUris; import android.content.ContentValues; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.res.Resources; import android.content.res.Resources; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.provider.Telephony; import android.provider.Telephony; import android.support.v14.preference.MultiSelectListPreference; import android.support.v14.preference.MultiSelectListPreference; import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference; Loading @@ -36,6 +38,7 @@ import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; Loading @@ -49,8 +52,12 @@ import android.view.View; import android.view.View.OnKeyListener; import android.view.View.OnKeyListener; import com.android.internal.logging.MetricsProto.MetricsEvent; 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.HashSet; import java.util.List; import java.util.Set; import java.util.Set; public class ApnEditor extends SettingsPreferenceFragment public class ApnEditor extends SettingsPreferenceFragment Loading Loading @@ -105,6 +112,8 @@ public class ApnEditor extends SettingsPreferenceFragment private int mBearerInitialVal = 0; private int mBearerInitialVal = 0; private String mMvnoTypeStr; private String mMvnoTypeStr; private String mMvnoMatchDataStr; private String mMvnoMatchDataStr; private String[] mReadOnlyApnTypes; private boolean mReadOnlyApn; /** /** * Standard projection for the interesting columns of a normal note. * Standard projection for the interesting columns of a normal note. Loading Loading @@ -132,7 +141,8 @@ public class ApnEditor extends SettingsPreferenceFragment Telephony.Carriers.BEARER_BITMASK, // 19 Telephony.Carriers.BEARER_BITMASK, // 19 Telephony.Carriers.ROAMING_PROTOCOL, // 20 Telephony.Carriers.ROAMING_PROTOCOL, // 20 Telephony.Carriers.MVNO_TYPE, // 21 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; private static final int ID_INDEX = 0; Loading @@ -157,6 +167,7 @@ public class ApnEditor extends SettingsPreferenceFragment private static final int ROAMING_PROTOCOL_INDEX = 20; private static final int ROAMING_PROTOCOL_INDEX = 20; private static final int MVNO_TYPE_INDEX = 21; private static final int MVNO_TYPE_INDEX = 21; private static final int MVNO_MATCH_DATA_INDEX = 22; private static final int MVNO_MATCH_DATA_INDEX = 22; private static final int EDITED_INDEX = 23; @Override @Override Loading Loading @@ -206,6 +217,8 @@ public class ApnEditor extends SettingsPreferenceFragment SubscriptionManager.INVALID_SUBSCRIPTION_ID); SubscriptionManager.INVALID_SUBSCRIPTION_ID); mFirstTime = icicle == null; mFirstTime = icicle == null; mReadOnlyApn = false; mReadOnlyApnTypes = null; if (action.equals(Intent.ACTION_EDIT)) { if (action.equals(Intent.ACTION_EDIT)) { Uri uri = intent.getData(); Uri uri = intent.getData(); Loading @@ -214,6 +227,15 @@ public class ApnEditor extends SettingsPreferenceFragment finish(); finish(); return; 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; mUri = uri; } else if (action.equals(Intent.ACTION_INSERT)) { } else if (action.equals(Intent.ACTION_INSERT)) { if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { Loading Loading @@ -255,6 +277,17 @@ public class ApnEditor extends SettingsPreferenceFragment mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 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++) { for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) { getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); } } Loading @@ -262,6 +295,87 @@ public class ApnEditor extends SettingsPreferenceFragment fillUi(); 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 @Override protected int getMetricsCategory() { protected int getMetricsCategory() { return MetricsEvent.APN_EDITOR; return MetricsEvent.APN_EDITOR; Loading Loading @@ -552,7 +666,7 @@ public class ApnEditor extends SettingsPreferenceFragment public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater); // If it's a new APN, then cancel will delete the new entry in onPause // If it's a new APN, then cancel will delete the new entry in onPause if (!mNewApn) { if (!mNewApn && !mReadOnlyApn) { menu.add(0, MENU_DELETE, 0, R.string.menu_delete) menu.add(0, MENU_DELETE, 0, R.string.menu_delete) .setIcon(R.drawable.ic_menu_delete); .setIcon(R.drawable.ic_menu_delete); } } Loading Loading
src/com/android/settings/ApnEditor.java +116 −2 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.app.Dialog; import android.app.DialogFragment; import android.app.DialogFragment; import android.content.ContentUris; import android.content.ContentUris; import android.content.ContentValues; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.res.Resources; import android.content.res.Resources; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.os.PersistableBundle; import android.provider.Telephony; import android.provider.Telephony; import android.support.v14.preference.MultiSelectListPreference; import android.support.v14.preference.MultiSelectListPreference; import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference; Loading @@ -36,6 +38,7 @@ import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.telephony.CarrierConfigManager; import android.telephony.ServiceState; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; Loading @@ -49,8 +52,12 @@ import android.view.View; import android.view.View.OnKeyListener; import android.view.View.OnKeyListener; import com.android.internal.logging.MetricsProto.MetricsEvent; 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.HashSet; import java.util.List; import java.util.Set; import java.util.Set; public class ApnEditor extends SettingsPreferenceFragment public class ApnEditor extends SettingsPreferenceFragment Loading Loading @@ -105,6 +112,8 @@ public class ApnEditor extends SettingsPreferenceFragment private int mBearerInitialVal = 0; private int mBearerInitialVal = 0; private String mMvnoTypeStr; private String mMvnoTypeStr; private String mMvnoMatchDataStr; private String mMvnoMatchDataStr; private String[] mReadOnlyApnTypes; private boolean mReadOnlyApn; /** /** * Standard projection for the interesting columns of a normal note. * Standard projection for the interesting columns of a normal note. Loading Loading @@ -132,7 +141,8 @@ public class ApnEditor extends SettingsPreferenceFragment Telephony.Carriers.BEARER_BITMASK, // 19 Telephony.Carriers.BEARER_BITMASK, // 19 Telephony.Carriers.ROAMING_PROTOCOL, // 20 Telephony.Carriers.ROAMING_PROTOCOL, // 20 Telephony.Carriers.MVNO_TYPE, // 21 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; private static final int ID_INDEX = 0; Loading @@ -157,6 +167,7 @@ public class ApnEditor extends SettingsPreferenceFragment private static final int ROAMING_PROTOCOL_INDEX = 20; private static final int ROAMING_PROTOCOL_INDEX = 20; private static final int MVNO_TYPE_INDEX = 21; private static final int MVNO_TYPE_INDEX = 21; private static final int MVNO_MATCH_DATA_INDEX = 22; private static final int MVNO_MATCH_DATA_INDEX = 22; private static final int EDITED_INDEX = 23; @Override @Override Loading Loading @@ -206,6 +217,8 @@ public class ApnEditor extends SettingsPreferenceFragment SubscriptionManager.INVALID_SUBSCRIPTION_ID); SubscriptionManager.INVALID_SUBSCRIPTION_ID); mFirstTime = icicle == null; mFirstTime = icicle == null; mReadOnlyApn = false; mReadOnlyApnTypes = null; if (action.equals(Intent.ACTION_EDIT)) { if (action.equals(Intent.ACTION_EDIT)) { Uri uri = intent.getData(); Uri uri = intent.getData(); Loading @@ -214,6 +227,15 @@ public class ApnEditor extends SettingsPreferenceFragment finish(); finish(); return; 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; mUri = uri; } else if (action.equals(Intent.ACTION_INSERT)) { } else if (action.equals(Intent.ACTION_INSERT)) { if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { Loading Loading @@ -255,6 +277,17 @@ public class ApnEditor extends SettingsPreferenceFragment mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 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++) { for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) { getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); } } Loading @@ -262,6 +295,87 @@ public class ApnEditor extends SettingsPreferenceFragment fillUi(); 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 @Override protected int getMetricsCategory() { protected int getMetricsCategory() { return MetricsEvent.APN_EDITOR; return MetricsEvent.APN_EDITOR; Loading Loading @@ -552,7 +666,7 @@ public class ApnEditor extends SettingsPreferenceFragment public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater); // If it's a new APN, then cancel will delete the new entry in onPause // If it's a new APN, then cancel will delete the new entry in onPause if (!mNewApn) { if (!mNewApn && !mReadOnlyApn) { menu.add(0, MENU_DELETE, 0, R.string.menu_delete) menu.add(0, MENU_DELETE, 0, R.string.menu_delete) .setIcon(R.drawable.ic_menu_delete); .setIcon(R.drawable.ic_menu_delete); } } Loading