package com.lechucksoftware.proxy.proxysettings.ui.fragments; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentActivity; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.ScrollView; import com.lechucksoftware.proxy.proxysettings.App; import com.lechucksoftware.proxy.proxysettings.R; import com.lechucksoftware.proxy.proxysettings.constants.Requests; import com.lechucksoftware.proxy.proxysettings.db.ProxyEntity; import com.lechucksoftware.proxy.proxysettings.tasks.AsyncDeleteProxy; import com.lechucksoftware.proxy.proxysettings.tasks.AsyncSaveProxy; import com.lechucksoftware.proxy.proxysettings.tasks.AsyncUpdateLinkedWiFiAP; import com.lechucksoftware.proxy.proxysettings.ui.activities.MasterActivity; import com.lechucksoftware.proxy.proxysettings.ui.base.BaseDialogFragment; import com.lechucksoftware.proxy.proxysettings.ui.components.InputExclusionList; import com.lechucksoftware.proxy.proxysettings.ui.components.InputField; import com.lechucksoftware.proxy.proxysettings.ui.dialogs.UpdateLinkedWifiAPAlertDialog; import com.lechucksoftware.proxy.proxysettings.utils.UIUtils; import java.util.HashMap; import java.util.List; import java.util.Map; import be.shouldit.proxy.lib.ProxyStatusItem; import be.shouldit.proxy.lib.enums.ProxyStatusProperties; import be.shouldit.proxy.lib.utils.ProxyUtils; import timber.log.Timber; public class ProxyDetailFragment extends BaseDialogFragment { public static ProxyDetailFragment instance; public static final String TAG = ProxyDetailFragment.class.getSimpleName(); // Arguments private static final String SELECTED_PROXY_ARG = "SELECTED_PROXY_ARG"; private boolean saveEnabled; private boolean deleteEnabled; private InputField proxyHost; private InputField proxyPort; private InputExclusionList proxyBypass; // private InputTags proxyTags; private Long selectedProxyId; private ProxyEntity selectedProxy; private UIHandler uiHandler; private RelativeLayout proxyInUseBanner; private RelativeLayout proxyDuplicatedBanner; private ScrollView proxyScrollView; private Map<ProxyStatusProperties,CharSequence> validationErrors; public static ProxyDetailFragment newInstance(Long proxyId) { ProxyDetailFragment instance = new ProxyDetailFragment(); Bundle args = new Bundle(); args.putSerializable(SELECTED_PROXY_ARG, proxyId); instance.setArguments(args); return instance; } public static ProxyDetailFragment newInstance() { ProxyDetailFragment instance = new ProxyDetailFragment(); return instance; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.proxy_preferences, container, false); setHasOptionsMenu(true); getUIComponents(v); return v; } @Override public void onResume() { super.onResume(); Bundle args = getArguments(); uiHandler = new UIHandler(); validationErrors = new HashMap<ProxyStatusProperties, CharSequence>(); if (args != null && args.containsKey(SELECTED_PROXY_ARG)) { selectedProxyId = (Long) getArguments().getSerializable(SELECTED_PROXY_ARG); selectedProxy = (ProxyEntity) App.getDBManager().getProxy(selectedProxyId); deleteEnabled = true; } if (selectedProxy == null) { selectedProxy = new ProxyEntity(); deleteEnabled = false; } uiHandler.callRefreshUI(); } private void getUIComponents(View v) { proxyScrollView = (ScrollView) v.findViewById(R.id.proxy_scrollview); proxyInUseBanner = (RelativeLayout) v.findViewById(R.id.proxy_in_use_banner); proxyDuplicatedBanner = (RelativeLayout) v.findViewById(R.id.proxy_duplicated_banner); proxyHost = (InputField) v.findViewById(R.id.proxy_host); proxyHost.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void afterTextChanged(Editable editable) { checkValidation(); } }); proxyPort = (InputField) v.findViewById(R.id.proxy_port); proxyPort.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void afterTextChanged(Editable editable) { checkValidation(); } }); proxyBypass = (InputExclusionList) v.findViewById(R.id.proxy_bypass); proxyBypass.addValueChangedListener(new InputExclusionList.ValueChangedListener() { @Override public void onExclusionListChanged(String result) { // TODO: Improve scrolling to focused bypass item -> Temporary disabled // proxyScrollView.scrollTo(0,proxyScrollView.getBottom()); checkValidation(); } }); // proxyTags = (InputTags) v.findViewById(R.id.proxy_tags); // proxyTags.setTagsViewOnClickListener(new View.OnClickListener() // { // @Override // public void onClick(View view) // { // TagsListFragment tagsListSelectorFragment = TagsListFragment.newInstance(cachedObjId); // tagsListSelectorFragment.show(getFragmentManager(), TAG); // } // }); } private boolean validateBypass() { String value = proxyBypass.getExclusionString(); Timber.d("Exclusion list updated: " + value); ProxyStatusItem item = ProxyUtils.isProxyValidExclusionList(value); validationErrors.remove(item.statusCode); if (!item.result) { validationErrors.put(item.statusCode,item.message); return false; } else { selectedProxy.setExclusion(value); return true; } } private boolean validateHost() { String value = proxyHost.getValue(); proxyHost.setError(null); ProxyStatusItem item = ProxyUtils.isProxyValidHostname(value); validationErrors.remove(item.statusCode); if (!item.result) { proxyHost.setError(item.message); validationErrors.put(item.statusCode, item.message); return false; } else { selectedProxy.setHost(value); return true; } } private boolean validatePort() { Integer value = null; try { value = Integer.parseInt(proxyPort.getValue()); } catch (NumberFormatException e) { value = Integer.MAX_VALUE; } ProxyStatusItem item = ProxyUtils.isProxyValidPort(value); validationErrors.remove(item.statusCode); proxyPort.setError(null); if (!item.result) { proxyPort.setError(item.message); validationErrors.put(item.statusCode, item.message); return false; } else { selectedProxy.setPort(value); return true; } } private void checkValidation() { if ( validateHost() && validatePort() && validateBypass()) { enableSave(); } else { disableSave(); } // TODO: Add check for duplicated configuration to Async handler proxyDuplicatedBanner.setVisibility(View.GONE); String host = selectedProxy.getHost(); Integer port = selectedProxy.getPort(); if (host != null && port != null) { List<Long> duplicatedIDs = App.getDBManager().findDuplicatedProxy(host, port); if (selectedProxy.isPersisted()) { proxyDuplicatedBanner.setVisibility(UIUtils.booleanToVisibility(duplicatedIDs.size() > 1)); } else { proxyDuplicatedBanner.setVisibility(UIUtils.booleanToVisibility(duplicatedIDs.size() > 0)); } } } private void refreshUI() { if (selectedProxy != null) { proxyInUseBanner.setVisibility(UIUtils.booleanToVisibility(selectedProxy.getInUse())); proxyHost.setValue(selectedProxy.getHost()); if (selectedProxy.getPort() != null && selectedProxy.getPort() != 0) { proxyPort.setValue(selectedProxy.getPort()); } proxyBypass.setExclusionString(selectedProxy.getExclusion()); // proxyTags.setTags(selectedProxy.getTags()); checkValidation(); } else { // TODO: Add handling here Timber.e(new Exception(),"NO PROXY SELECTED"); } } private class UIHandler extends Handler { @Override public void handleMessage(Message message) { Bundle b = message.getData(); // Timber.w("handleMessage: " + b.toString()); refreshUI(); } public void callRefreshUI() { sendEmptyMessage(0); } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.proxy_details, menu); } @Override public void onPrepareOptionsMenu(Menu menu) { MenuItem saveMenuItem = menu.findItem(R.id.menu_save); if (saveMenuItem != null) { saveMenuItem.setVisible(saveEnabled); } MenuItem deleteMenuItem = menu.findItem(R.id.menu_delete); if (deleteMenuItem != null) { deleteMenuItem.setVisible(deleteEnabled); } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent mainIntent = new Intent(getActivity(), MasterActivity.class); mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(mainIntent); return true; case R.id.menu_save: saveProxy(); return true; case R.id.menu_delete: deleteProxy(); return true; } return super.onOptionsItemSelected(item); } private void saveProxy() { try { if (selectedProxy.getInUse()) { UpdateLinkedWifiAPAlertDialog updateDialog = UpdateLinkedWifiAPAlertDialog.newInstance(); updateDialog.setTargetFragment(this, Requests.UPDATE_LINKED_WIFI_AP); updateDialog.show(getFragmentManager(), "UpdateLinkedWifiAPAlertDialog"); } else { AsyncSaveProxy asyncSaveProxy = new AsyncSaveProxy(this,selectedProxy); asyncSaveProxy.execute(); getActivity().finish(); } } catch (Exception e) { Timber.e(e,"Exception saving proxy"); } } private void deleteProxy() { try { if (selectedProxy.getInUse()) { UIUtils.showError(getActivity(), R.string.proxy_in_use_cannot_delete); } else { AsyncDeleteProxy asyncDeleteProxy = new AsyncDeleteProxy(this,selectedProxy); asyncDeleteProxy.execute(); getActivity().finish(); } } catch (Exception e) { Timber.e(e, "Exception deleting proxy"); } } public void enableSave() { saveEnabled = true; FragmentActivity activity = getActivity(); if (activity != null) { activity.invalidateOptionsMenu(); } } public void disableSave() { saveEnabled = false; FragmentActivity activity = getActivity(); if (activity != null) { activity.invalidateOptionsMenu(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == Requests.UPDATE_LINKED_WIFI_AP) { ProxyEntity persistedProxy = App.getDBManager().getProxy(selectedProxy.getId()); AsyncSaveProxy asyncSaveProxy = new AsyncSaveProxy(this,selectedProxy); asyncSaveProxy.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); AsyncUpdateLinkedWiFiAP asyncUpdateLinkedWiFiAP = new AsyncUpdateLinkedWiFiAP(getActivity(), persistedProxy, selectedProxy); asyncUpdateLinkedWiFiAP.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); getActivity().finish(); } } }