package org.exobel.routerkeygen.ui; import android.annotation.TargetApi; import android.app.Activity; import android.app.Fragment; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.text.Editable; import android.text.InputFilter; import android.text.Spanned; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import org.exobel.routerkeygen.R; import org.exobel.routerkeygen.algorithms.Keygen; import org.exobel.routerkeygen.algorithms.WiFiNetwork; import org.exobel.routerkeygen.ui.NetworksListFragment.OnItemSelectionListener; import java.io.IOException; import java.util.Locale; import java.util.zip.ZipInputStream; public class ManualInputFragment extends Fragment { public final static String MAC_ADDRESS_ARG = "mac_address"; private static final OnItemSelectionListener sDummyCallbacks = new OnItemSelectionListener() { public void onItemSelected(WiFiNetwork id) { } public void onItemSelected(String mac) { } }; private View loading; private View mainView; private OnItemSelectionListener mCallbacks = sDummyCallbacks; public static ManualInputFragment newInstance() { ManualInputFragment frag = new ManualInputFragment(); frag.setArguments(Bundle.EMPTY); return frag; } public static ManualInputFragment newInstance(String mac) { Bundle args = new Bundle(); if (mac != null) args.putString(MAC_ADDRESS_ARG, mac.replace(":", "")); ManualInputFragment frag = new ManualInputFragment(); frag.setArguments(args); return frag; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final String macAddress; if (getArguments().containsKey(MAC_ADDRESS_ARG)) macAddress = getArguments().getString(MAC_ADDRESS_ARG); else macAddress = null; final View root = inflater .inflate(R.layout.fragment_manual_input, container, false); mainView = root.findViewById(R.id.manual_root); loading = root.findViewById(R.id.loading_spinner); final String[] routers = getResources().getStringArray( R.array.supported_routers); ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_dropdown_item_1line, routers); final AutoCompleteTextView edit = (AutoCompleteTextView) root .findViewById(R.id.manual_autotext); edit.setAdapter(adapter); edit.setThreshold(1); edit.requestFocus(); final InputFilter filterSSID = new InputFilter() { public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { for (int i = start; i < end; i++) { if (!Character.isLetterOrDigit(source.charAt(i)) && source.charAt(i) != '-' && source.charAt(i) != '_' && source.charAt(i) != ' ') { return ""; } } return null; } }; edit.setFilters(new InputFilter[]{filterSSID}); final EditText macs[] = new EditText[6]; root.findViewById(R.id.manual_mac_root).setVisibility(View.VISIBLE); edit.setImeOptions(EditorInfo.IME_ACTION_NEXT); macs[0] = (EditText) root.findViewById(R.id.input_mac_pair1); macs[1] = (EditText) root.findViewById(R.id.input_mac_pair2); macs[2] = (EditText) root.findViewById(R.id.input_mac_pair3); macs[3] = (EditText) root.findViewById(R.id.input_mac_pair4); macs[4] = (EditText) root.findViewById(R.id.input_mac_pair5); macs[5] = (EditText) root.findViewById(R.id.input_mac_pair6); if (macAddress != null) { macs[0].setText(macAddress.substring(0, 2)); macs[1].setText(macAddress.substring(2, 4)); macs[2].setText(macAddress.substring(4, 6)); macs[3].setText(macAddress.substring(6, 8)); macs[4].setText(macAddress.substring(8, 10)); macs[5].setText(macAddress.substring(10, 12)); } final InputFilter filterMac = new InputFilter() { public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (dstart >= 2) return ""; if (source.length() > 2) return "";// max 2 chars for (int i = start; i < end; i++) { if (Character.digit(source.charAt(i), 16) == -1) { return ""; } } if (source.length() + dstart > 2) return source.subSequence(0, 2 - dstart); return null; } }; for (final EditText mac : macs) { mac.setFilters(new InputFilter[]{filterMac}); mac.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void afterTextChanged(Editable e) { if (e.length() != 2) return; for (int i = 0; i < 6; ++i) { if (macs[i].getText().length() >= 2) continue; macs[i].requestFocus(); return; } } }); } Button calc = (Button) root.findViewById(R.id.bt_calc); calc.setOnClickListener(new View.OnClickListener() { @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void onClick(View v) { String ssid = edit.getText().toString().trim(); StringBuilder mac = new StringBuilder(); boolean warnUnused = false; for (EditText m : macs) { final String mText = m.getText().toString(); if (mText.length() > 0) warnUnused = true; mac.append(mText); if (!m.equals(macs[5])) mac.append(":"); // do not add this for the // last one } if (mac.length() < 17) { mac.setLength(0); if (warnUnused) Toast.makeText(getActivity(), R.string.msg_invalid_mac, Toast.LENGTH_SHORT).show(); } KeygenMatcherTask matcher = new KeygenMatcherTask(ssid, mac .toString().toUpperCase(Locale.getDefault())); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { matcher.execute(); } else { matcher.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } } }); Button cancel = (Button) root.findViewById(R.id.bt_cancel); cancel.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { getActivity().onBackPressed(); } }); return root; } @Override @SuppressWarnings("deprecation") public void onAttach(Activity activity) { super.onAttach(activity); if (!(activity instanceof OnItemSelectionListener)) { throw new IllegalStateException( "Activity must implement fragment's callbacks."); } mCallbacks = (OnItemSelectionListener) activity; } @Override public void onDetach() { super.onDetach(); mCallbacks = sDummyCallbacks; } private class KeygenMatcherTask extends AsyncTask<Void, Void, WiFiNetwork> { private final String ssid; private final String mac; public KeygenMatcherTask(String ssid, String mac) { this.ssid = ssid; this.mac = mac; } @Override protected void onPreExecute() { mainView.setVisibility(View.GONE); loading.setVisibility(View.VISIBLE); } @Override protected void onPostExecute(WiFiNetwork wifiNetwork) { loading.setVisibility(View.GONE); mainView.setVisibility(View.VISIBLE); if (wifiNetwork.getSupportState() == Keygen.UNSUPPORTED) { if (getActivity() != null) { Toast.makeText(getActivity(), R.string.msg_unspported_network, Toast.LENGTH_SHORT).show(); } return; } mCallbacks.onItemSelected(wifiNetwork); } @Override protected WiFiNetwork doInBackground(Void... params) { final ZipInputStream magicInfo = new ZipInputStream(getActivity() .getResources().openRawResource(R.raw.magic_info)); final WiFiNetwork wifi = new WiFiNetwork(ssid, mac, 0, 0, "", magicInfo); try { magicInfo.close(); } catch (IOException e) { e.printStackTrace(); } return wifi; } } }