package com.ofa.offline3fauth; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.List; import utils.LocalBinaryPattern; import utils.ObjCompressor; import utils.ObjCrypter; import utils.QRCodeEncoder; import utils.SkinFaceDetector; import com.google.zxing.BarcodeFormat; import com.google.zxing.WriterException; import com.google.zxing.integration.android.IntentIntegrator; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextWatcher; import android.util.Base64; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import android.widget.TextView.OnEditorActionListener; public abstract class TabFragment extends Fragment { protected Button faceRecButton, qrCodeButton; protected ImageView faceRecView, qrCodeView; protected EditText codeInput, codeInputValidate; protected final static int CAMREQ_CODE = 12221; protected LinearLayout codeLayout, faceRecLayout, qrCodeLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.worker_fragment, container, false); faceRecButton = (Button) rootView.findViewById(R.id.faceRecButton); qrCodeButton = (Button) rootView.findViewById(R.id.qrCodeButton); faceRecView = (ImageView) rootView.findViewById(R.id.faceRecView); qrCodeView = (ImageView) rootView.findViewById(R.id.qrCodeView); codeInput = (EditText) rootView.findViewById(R.id.codeInput); codeInputValidate = (EditText) rootView.findViewById(R.id.codeInputValidate); codeLayout = (LinearLayout)rootView.findViewById(R.id.codeLayout); faceRecLayout = (LinearLayout)rootView.findViewById(R.id.faceRecLayout); qrCodeLayout = (LinearLayout)rootView.findViewById(R.id.qrCodeLayout); faceRecButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { onFaceRecButtonClicked(); } }); qrCodeButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { onQRCodeButtonClicked(); } }); codeInput.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changes the Text processCode(); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) { } }); codeInputValidate.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changes the Text processCode(); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) { } }); codeInput.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { hideSoftKeyboard(codeInput); processCode(); return true; } return false; } }); codeInputValidate.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { hideSoftKeyboard(codeInputValidate); processCode(); return true; } return false; } }); displayAcceptedInputs(); return rootView; } protected abstract void displayAcceptedInputs(); public void hideSoftKeyboard(EditText input){ if(getActivity().getCurrentFocus()!=null && getActivity().getCurrentFocus() instanceof EditText){ InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(input.getWindowToken(), 0); } } protected void onQRCodeButtonClicked() { IntentIntegrator integrator = new IntentIntegrator(getActivity()); integrator.initiateScan(); } protected void onFaceRecButtonClicked() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); PackageManager packageManager = getActivity().getApplicationContext().getPackageManager(); List<ResolveInfo> list = packageManager.queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY); if(list.size() > 0) { getActivity().startActivityForResult(takePictureIntent, CAMREQ_CODE); } } protected void processCode() { String codeIn = codeInput.getText().toString().trim(); String codeInVal = codeInputValidate.getText().toString().trim(); if(codeIn==null || "".equals(codeIn) || codeInVal==null || "".equals(codeInVal)) { // notify user that one is empty } else if(!codeIn.equals(codeInVal)) { // notify user that they don't match } else { setPassword(codeIn); validateAllFactors(); } } protected abstract void setPassword(String codeIn); protected static void fillImageViewWithQRCode(ImageView imageView, String textToEncode) { try { Bitmap bm = QRCodeEncoder.encodeAsBitmap(textToEncode, BarcodeFormat.QR_CODE, 250, 250); if(bm != null) { imageView.setImageBitmap(bm); } } catch (WriterException e) { e.printStackTrace(); } } protected abstract boolean validateAllFactors(); protected ArrayList<ArrayList<Integer>> deProcessFactors(String processedString, String password) { try { return ObjCompressor.decompress( ObjCrypter.decrypt3DES( Base64.decode( processedString.getBytes("ISO-8859-1") , Base64.NO_WRAP) , password)); } catch (GeneralSecurityException e) { Toast.makeText(getActivity(), "Error in decrypting. Password may be incorrect.", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Toast.makeText(getActivity(), "Error in processing. Try to scan QRCode again.", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } return new ArrayList<ArrayList<Integer>>(); } protected String processFactors(ArrayList<ArrayList<Integer>> faceDescriptor, String password) { try { return new String(Base64.encode( ObjCrypter.encrypt3DES( ObjCompressor.compress(faceDescriptor) , password) , Base64.NO_WRAP) , "ISO-8859-1"); } catch (GeneralSecurityException e) { Toast.makeText(getActivity(), "Error in encrypting. Password may be incorrect.", Toast.LENGTH_SHORT).show(); } catch (IOException e) { Toast.makeText(getActivity(), "Error in processing. Try again.", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } return ""; } protected String generateQRCodeText(Bitmap faceBitmap, String password) { ArrayList<ArrayList<Integer>> faceDes = getFaceDescriptor(faceBitmap); String compressed = ""; if(faceDes!=null && faceDes.size()!=0) { compressed = processFactors(faceDes, password); System.out.println("Last Face Descriptor: " + faceDes); System.out.println("Encrypted QR Text: " + compressed); } return compressed; } protected ArrayList<ArrayList<Integer>> getFaceDescriptor(Bitmap faceBitmap) { LocalBinaryPattern lbp = new LocalBinaryPattern(new SkinFaceDetector(), 0.5, 0.5); return lbp.getDescriptor(faceBitmap); } protected boolean saveStringToStorage(String obj, String directory, String fileName) { if(!directory.startsWith(File.separator)) directory = File.separator + directory; File dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath() + directory); if(!dir.exists()) dir.mkdirs(); File file = new File(dir, fileName); BufferedOutputStream output = null; try { output = new BufferedOutputStream( new FileOutputStream(file) ); output.write(obj.getBytes()); output.flush(); return true; } catch (Exception e) { e.printStackTrace(); } finally { if(output!=null) try { output.close(); } catch (IOException e) { } } return false; } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setLayoutColors(); } protected abstract void setLayoutColors(); }