<commit_before>package co.touchlab.researchstack.common.storage.aes;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.support.v7.app.AlertDialog;
import android.text.InputFilter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import co.touchlab.researchstack.R;
import co.touchlab.researchstack.common.storage.BaseFileAccess;
import co.touchlab.researchstack.common.storage.FileAccessException;
import co.touchlab.researchstack.utils.UiThreadContext;

/**
 * Created by kgalligan on 11/24/15.
 */
public class AesFileAccess extends BaseFileAccess
{
    public static final String CHARSET_NAME = "UTF8";
    public static final String A_LITTLE_TEST = "ALittleTest";
    DataDecoder dataDecoder;
    DataEncoder dataEncoder;
    private final int bitDepth;
    private final boolean alphaNumeric;
    private final int length;

    public AesFileAccess(int bitDepth, boolean alphaNumeric, int length)
    {
        this.bitDepth = bitDepth;
        this.alphaNumeric = alphaNumeric;
        this.length = length;
    }

    @Override @MainThread
    public void initFileAccess(Context context)
    {
        UiThreadContext.assertUiThread();
        if(dataDecoder != null && dataEncoder != null)
        {
            notifyReady();
        }
        else
        {
            if(passphraseExists(context))
            {
                runPinDialog(context, "Enter your passphrase.", new PinOnClickListener(context)
                             {
                                 @Override
                                 void onPin(Context context, String pin)
                                 {
                                     try
                                     {
                                         startWithPassphrase(context, pin);
                                         notifyReady();
                                     }
                                     catch(Exception e)
                                     {
                                         initFileAccess(context);
                                         Toast.makeText(context, "Wrong passphrase", Toast.LENGTH_LONG).show();
                                     }
                                 }
                             });
            }
            else
            {
                runPinDialog(context, "Create a passphrase.", new PinOnClickListener(context)
                {
                    @Override
                    void onPin(Context context, String pin)
                    {
                        try
                        {
                            confirmPin(context, pin);
                        }
                        catch(Exception e)
                        {
                            initFileAccess(context);
                            Toast.makeText(context, "Bad format", Toast.LENGTH_LONG).show();
                        }
                    }
                });
            }
        }
    }

    private void confirmPin(Context context, String firstPin)
    {
        runPinDialog(context, "Confirm passphrase.", new PinOnClickListener(context)
        {
            @Override
            void onPin(Context context, String pin)
            {
                try
                {
                    if(!firstPin.equals(pin))
                    {
                        Toast.makeText(context, "Pins do not match", Toast.LENGTH_LONG).show();
                        initFileAccess(context);
                    }
                    else
                    {
                        startWithPassphrase(context, pin);
                        notifyReady();
                    }
                }
                catch(Exception e)
                {
                    initFileAccess(context);
                    Toast.makeText(context, "Bad format", Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    private void runPinDialog(Context context, String title, PinOnClickListener listener)
    {
        View customView = LayoutInflater.from(context).inflate(
                alphaNumeric ? R.layout.dialog_pin_entry_alphanumeric : R.layout.dialog_pin_entry
                , null);
        EditText editText = (EditText) customView.findViewById(R.id.pinValue);
        editText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(length) });
        listener.setCustomView(customView);
        AlertDialog alertDialog = new AlertDialog
                .Builder(context)
                .setView(customView)
                .setTitle(title)
                .setOnCancelListener(dialog -> {

                    new Handler().post(AesFileAccess.this :: notifyListenersFailed);
                })
                .setPositiveButton("OK", listener)
                .create();

        //If not an Activity, need system alert. Not sure how it wouldn't be, but...
        if(!(context instanceof Activity))
        {
            alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        }

        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        alertDialog.show();
    }

    private abstract class PinOnClickListener implements DialogInterface.OnClickListener
    {
        private final Context context;
        private View customView;

        public PinOnClickListener(Context context)
        {
            this.context = context;
        }
<commit_msg>Auto-submit<commit_after>package co.touchlab.researchstack.common.storage.aes;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.support.v7.app.AlertDialog;
import android.text.InputFilter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.Toast;

import com.jakewharton.rxbinding.widget.RxTextView;

import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import co.touchlab.researchstack.R;
import co.touchlab.researchstack.common.storage.BaseFileAccess;
import co.touchlab.researchstack.common.storage.FileAccessException;
import co.touchlab.researchstack.utils.UiThreadContext;
import rx.functions.Action1;

/**
 * Created by kgalligan on 11/24/15.
 */
public class AesFileAccess extends BaseFileAccess
{
    public static final String CHARSET_NAME = "UTF8";
    public static final String A_LITTLE_TEST = "ALittleTest";
    DataDecoder dataDecoder;
    DataEncoder dataEncoder;
    private final int bitDepth;
    private final boolean alphaNumeric;
    private final int length;

    public AesFileAccess(int bitDepth, boolean alphaNumeric, int length)
    {
        this.bitDepth = bitDepth;
        this.alphaNumeric = alphaNumeric;
        this.length = length;
    }

    @Override @MainThread
    public void initFileAccess(Context context)
    {
        UiThreadContext.assertUiThread();
        if(dataDecoder != null && dataEncoder != null)
        {
            notifyReady();
        }
        else
        {
            if(passphraseExists(context))
            {
                runPinDialog(context, "Enter your passphrase.", new PinOnClickListener(context)
                             {
                                 @Override
                                 void onPin(Context context, String pin)
                                 {
                                     try
                                     {
                                         startWithPassphrase(context, pin);
                                         notifyReady();
                                     }
                                     catch(Exception e)
                                     {
                                         initFileAccess(context);
                                         Toast.makeText(context, "Wrong passphrase", Toast.LENGTH_LONG).show();
                                     }
                                 }
                             });
            }
            else
            {
                runPinDialog(context, "Create a passphrase.", new PinOnClickListener(context)
                {
                    @Override
                    void onPin(Context context, String pin)
                    {
                        try
                        {
                            confirmPin(context, pin);
                        }
                        catch(Exception e)
                        {
                            initFileAccess(context);
                            Toast.makeText(context, "Bad format", Toast.LENGTH_LONG).show();
                        }
                    }
                });
            }
        }
    }

    private void confirmPin(Context context, String firstPin)
    {
        runPinDialog(context, "Confirm passphrase.", new PinOnClickListener(context)
        {
            @Override
            void onPin(Context context, String pin)
            {
                try
                {
                    if(!firstPin.equals(pin))
                    {
                        Toast.makeText(context, "Pins do not match", Toast.LENGTH_LONG).show();
                        initFileAccess(context);
                    }
                    else
                    {
                        startWithPassphrase(context, pin);
                        notifyReady();
                    }
                }
                catch(Exception e)
                {
                    initFileAccess(context);
                    Toast.makeText(context, "Bad format", Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    private void runPinDialog(Context context, String title, PinOnClickListener listener)
    {
        View customView = LayoutInflater.from(context).inflate(
                alphaNumeric ? R.layout.dialog_pin_entry_alphanumeric : R.layout.dialog_pin_entry
                , null);
        EditText editText = (EditText) customView.findViewById(R.id.pinValue);
        editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(length)});


        listener.setCustomView(customView);
        AlertDialog alertDialog = new AlertDialog
                .Builder(context)
                .setView(customView)
                .setTitle(title)
                .setOnCancelListener(dialog -> {

                    new Handler().post(AesFileAccess.this :: notifyListenersFailed);
                })
//                .setPositiveButton("OK", listener)
                .create();

        RxTextView.textChanges(editText)
                  .filter(charSequence -> charSequence.length() == length)
                  .subscribe(charSequence -> {
                      new Handler().postDelayed(() -> {
                          listener.onPin(context, charSequence.toString());
                          alertDialog.dismiss();
                      }, 300);
                  });

        //If not an Activity, need system alert. Not sure how it wouldn't be, but...
        if(!(context instanceof Activity))
        {
            alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        }

        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        alertDialog.show();
    }

    private abstract class PinOnClickListener implements DialogInterface.OnClickListener
    {
        private final Context context;
        private View customView;

        public PinOnClickListener(Context context)
        {
            this.context = context;
        }

{'fraction_non_alphanumeric': 0.07837753020555469, 'fraction_numerical': 0.0015691197238349285, 'mean_word_length': 1.5013736263736264, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6965795', 'n_tokens_mistral': 3038, 'n_tokens_neox': 2844, 'n_words': 575}