org.alfresco.mobile.android.application.security.PassCodeDialogFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.mobile.android.application.security.PassCodeDialogFragment.java

Source

/*
 *  Copyright (C) 2005-2015 Alfresco Software Limited.
 *
 *  This file is part of Alfresco Mobile for Android.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.alfresco.mobile.android.application.security;

import static org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences.KEY_PASSCODE_ACTIVATED_AT;
import static org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences.KEY_PASSCODE_ATTEMPT;
import static org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences.KEY_PASSCODE_ENABLE;
import static org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences.KEY_PASSCODE_MAX_ATTEMPT;
import static org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences.KEY_PASSCODE_VALUE;

import org.alfresco.mobile.android.application.R;
import org.alfresco.mobile.android.application.activity.MainActivity;
import org.alfresco.mobile.android.application.fragments.preferences.PasscodePreferences;
import org.alfresco.mobile.android.ui.fragments.WaitingDialogFragment;
import org.alfresco.mobile.android.ui.utils.UIUtils;

import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * This Fragment is responsible to prompt pin code form. It allows user to use
 * the app.<br/>
 * 
 * @author Jean Marie Pascal
 */
public class PassCodeDialogFragment extends DialogFragment {
    public static final String ARGUMENT_MODE = "Mode";

    public static final String ARGUMENT_INFO = "info";

    public static final int MODE_INFO = 1;

    public static final int MODE_CREATE = 1;

    public static final int MODE_UPDATE = 2;

    public static final int MODE_DELETE = 3;

    public static final int MODE_USER_REQUEST = 4;

    private static final int PASSCODE_LENGTH = 4;

    /** Public Fragment TAG. */
    public static final String TAG = PassCodeDialogFragment.class.getName();

    private EditText passwordEditText;

    private EditText focusValue;

    private int[] passcode = new int[PASSCODE_LENGTH];

    private int[] confirmPasscode = new int[PASSCODE_LENGTH];

    private boolean needConfirmation = false;

    private TextView title;

    private TextView errorMessage;

    private SharedPreferences sharedPref;

    private boolean editionEnable;

    // ///////////////////////////////////////////////////////////////////////////
    // CONSTRUCTORS & HELPERS
    // ///////////////////////////////////////////////////////////////////////////
    public static PassCodeDialogFragment disable() {
        PassCodeDialogFragment fragment = new PassCodeDialogFragment();
        Bundle b = new Bundle();
        b.putInt(ARGUMENT_MODE, MODE_DELETE);
        fragment.setArguments(b);
        return fragment;
    }

    public static PassCodeDialogFragment enable() {
        PassCodeDialogFragment fragment = new PassCodeDialogFragment();
        Bundle b = new Bundle();
        b.putInt(ARGUMENT_MODE, MODE_CREATE);
        fragment.setArguments(b);
        return fragment;
    }

    public static PassCodeDialogFragment define() {
        PassCodeDialogFragment fragment = new PassCodeDialogFragment();
        Bundle b = new Bundle();
        b.putInt(ARGUMENT_MODE, MODE_CREATE);
        b.putInt(ARGUMENT_INFO, MODE_INFO);
        fragment.setArguments(b);
        return fragment;
    }

    public static PassCodeDialogFragment modify() {
        PassCodeDialogFragment fragment = new PassCodeDialogFragment();
        Bundle b = new Bundle();
        b.putInt(ARGUMENT_MODE, MODE_UPDATE);
        fragment.setArguments(b);
        return fragment;
    }

    public static PassCodeDialogFragment requestPasscode() {
        PassCodeDialogFragment fragment = new PassCodeDialogFragment();
        Bundle b = new Bundle();
        b.putInt(ARGUMENT_MODE, MODE_USER_REQUEST);
        fragment.setArguments(b);
        return fragment;
    }

    // ///////////////////////////////////////////////////////////////////////////
    // LIFECYCLE
    // ///////////////////////////////////////////////////////////////////////////
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (getDialog() != null) {
            setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Dialog_MinWidth);
            getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
            // getDialog().setTitle(R.string.passcode_preference);
        }

        final View v = inflater.inflate(R.layout.app_passcode, (ViewGroup) this.getView());

        title = (TextView) v.findViewById(R.id.passcode_hint);

        if (getArguments().containsKey(ARGUMENT_INFO)) {
            ((TextView) v.findViewById(R.id.passcode_admin)).setText(R.string.passcode_admin_title);
            v.findViewById(R.id.passcode_admin).setVisibility(View.VISIBLE);
        } else {

        }

        errorMessage = (TextView) v.findViewById(R.id.passcode_error);

        passwordEditText = (EditText) v.findViewById(R.id.passcode);
        passwordEditText.setInputType(InputType.TYPE_NULL);

        focusValue = passwordEditText;

        ImageView backButton = (ImageView) v.findViewById(R.id.delete_passcode);
        backButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                clearAll();
            }
        });

        int[] ids = new int[] { R.id.keyboard_0, R.id.keyboard_1, R.id.keyboard_2, R.id.keyboard_3, R.id.keyboard_4,
                R.id.keyboard_5, R.id.keyboard_6, R.id.keyboard_7, R.id.keyboard_8, R.id.keyboard_9,
                R.id.keyboard_back };

        Button key = null;
        for (int i = 0; i < ids.length; i++) {
            key = (Button) v.findViewById(ids[i]);
            key.setOnClickListener(keyboardClickListener);
        }

        return v;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getActivity() instanceof MainActivity) {
            UIUtils.displayTitle(getActivity(), R.string.menu_settings);
        } else {
            UIUtils.displayTitle(getActivity(), R.string.passcode_preference);
        }
        if (getDialog() != null) {
            getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                    | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
            UIUtils.hideKeyboard(getActivity());
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Avoid background stretching
        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
            getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (getActivity().getSupportFragmentManager().findFragmentByTag(PasscodePreferences.TAG) != null) {
            ((PasscodePreferences) getActivity().getSupportFragmentManager()
                    .findFragmentByTag(PasscodePreferences.TAG)).refresh();
        }
    }

    // ///////////////////////////////////////////////////////////////////////////
    // INTERNALS
    // ///////////////////////////////////////////////////////////////////////////
    private OnClickListener keyboardClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            int i = 0;
            switch (v.getId()) {
            case R.id.keyboard_0:
                i = 0;
                break;
            case R.id.keyboard_1:
                i = 1;
                break;
            case R.id.keyboard_2:
                i = 2;
                break;
            case R.id.keyboard_3:
                i = 3;
                break;
            case R.id.keyboard_4:
                i = 4;
                break;
            case R.id.keyboard_5:
                i = 5;
                break;
            case R.id.keyboard_6:
                i = 6;
                break;
            case R.id.keyboard_7:
                i = 7;
                break;
            case R.id.keyboard_8:
                i = 8;
                break;
            case R.id.keyboard_9:
                i = 9;
                break;
            default:
                break;
            }

            initCode(focusValue.length(), i);

            focusValue.setText(focusValue.getText().append("X"));

            if (focusValue.getText().length() == 4) {
                validate();
            }
        }
    };

    private void initCode(int index, int value) {
        if (needConfirmation) {
            confirmPasscode[index] = value;
        } else {
            passcode[index] = value;
        }
    }

    private void validate() {
        int mode = getArguments().getInt(ARGUMENT_MODE);
        sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
        switch (mode) {
        case MODE_USER_REQUEST:
            if (checkValue()) {
                Editor editor = sharedPref.edit();
                editor.putLong(KEY_PASSCODE_ACTIVATED_AT, -1);
                editor.remove(KEY_PASSCODE_ATTEMPT);
                editor.apply();
                getActivity().setResult(FragmentActivity.RESULT_OK);
                getActivity().finish();
            }
            break;
        case MODE_CREATE:
            create();
            break;
        case MODE_DELETE:
            delete();
            break;
        case MODE_UPDATE:
            if (!editionEnable) {
                update();
            } else {
                create();
            }
            break;
        default:
            break;
        }
    }

    private void create() {
        if (!needConfirmation) {
            clearAll();
            title.setText(R.string.passcode_confirmation);
            errorMessage.setVisibility(View.INVISIBLE);
            needConfirmation = true;
        } else if (needConfirmation && getUserPassCode(true) != null) {
            Editor editor = sharedPref.edit();
            editor.putBoolean(KEY_PASSCODE_ENABLE, true);
            editor.remove(KEY_PASSCODE_ATTEMPT);
            editor.putString(KEY_PASSCODE_VALUE, getUserPassCode(true));
            editor.apply();
            dismiss();
            errorMessage.setVisibility(View.INVISIBLE);
            if (getActivity().getSupportFragmentManager().findFragmentByTag(PasscodePreferences.TAG) != null) {
                ((PasscodePreferences) getActivity().getSupportFragmentManager()
                        .findFragmentByTag(PasscodePreferences.TAG)).refresh();
            } else {
                editor.putLong(KEY_PASSCODE_ACTIVATED_AT, -1);
                editor.remove(KEY_PASSCODE_ATTEMPT);
                editor.apply();
                getActivity().setResult(FragmentActivity.RESULT_OK);
                getActivity().finish();
            }
        } else {
            clearAll();
            needConfirmation = false;
            errorMessage.setVisibility(View.VISIBLE);
            errorMessage.setText(R.string.passcode_error_confirmation);
            title.setText(R.string.passcode_title);
        }
    }

    private void delete() {
        String passCodeValue = sharedPref.getString(KEY_PASSCODE_VALUE, "0000");
        if (passCodeValue.equals(getUserPassCode(false))) {
            Editor editor = sharedPref.edit();
            editor.putBoolean(KEY_PASSCODE_ENABLE, false);
            editor.remove(KEY_PASSCODE_ATTEMPT);
            editor.remove(KEY_PASSCODE_VALUE);
            editor.apply();
            dismiss();
            errorMessage.setVisibility(View.INVISIBLE);
            if (getActivity().getSupportFragmentManager().findFragmentByTag(PasscodePreferences.TAG) != null) {
                ((PasscodePreferences) getActivity().getSupportFragmentManager()
                        .findFragmentByTag(PasscodePreferences.TAG)).refresh();
            }
        } else {
            clearAll();
            errorMessage.setVisibility(View.VISIBLE);
            errorMessage.setText(R.string.passcode_unknown);
            checkAttempts();
        }
    }

    private void update() {
        if (checkValue()) {
            editionEnable = true;
            clearAll();
            title.setText(R.string.passcode_edit);
            errorMessage.setVisibility(View.INVISIBLE);
        } else {
            clearAll();
            errorMessage.setVisibility(View.VISIBLE);
            errorMessage.setText(R.string.passcode_unknown);
            // checkAttempts();
        }
    }

    private boolean checkValue() {
        String passCodeValue = sharedPref.getString(KEY_PASSCODE_VALUE, "0000");
        if (passCodeValue.equals(getUserPassCode(false))) {
            return true;
        } else {
            clearAll();
            errorMessage.setVisibility(View.VISIBLE);
            errorMessage.setText(R.string.passcode_unknown);
            checkAttempts();
        }
        return false;
    }

    private void checkAttempts() {
        int attempts = sharedPref.getInt(KEY_PASSCODE_ATTEMPT, 1);
        int maxAttempts = sharedPref.getInt(KEY_PASSCODE_MAX_ATTEMPT, -1);

        if (maxAttempts > 0 && attempts >= maxAttempts) {
            WaitingDialogFragment fr = new WaitingDialogFragment();
            fr.setCancelable(false);
            fr.show(getActivity().getSupportFragmentManager(), WaitingDialogFragment.TAG);

            DataCleaner cleaner = new DataCleaner(getActivity());
            cleaner.execute();
            dismiss();
            return;
        }

        Editor editor = sharedPref.edit();
        editor.putInt(KEY_PASSCODE_ATTEMPT, attempts + 1);
        editor.apply();
    }

    private String getUserPassCode(boolean needConfirmation) {
        String passcodeValue = "";
        for (int i = 0; i < passcode.length; i++) {
            if (needConfirmation && passcode[i] != confirmPasscode[i]) {
                break;
            } else {
                passcodeValue += passcode[i];
            }
        }

        if (passcodeValue.length() != PASSCODE_LENGTH) {
            passcodeValue = null;
        }
        return passcodeValue;
    }

    private void clearAll() {
        passwordEditText.setText("");
        focusValue = passwordEditText;
        passwordEditText.requestFocus();
    }
}