package org.awesomeapp.messenger.ui;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import android.widget.ViewFlipper;
import info.guardianproject.cacheword.CacheWordHandler;
import info.guardianproject.cacheword.ICacheWordSubscriber;
import info.guardianproject.cacheword.PassphraseSecrets;
import im.zom.messenger.R;
import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.Preferences;
import org.awesomeapp.messenger.ui.legacy.ThemeableActivity;
import org.ironrabbit.type.CustomTypefaceManager;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.UUID;
public class LockScreenActivity extends BaseActivity implements ICacheWordSubscriber {
private static final String TAG = "LockScreenActivity";
private final static int MIN_PASS_LENGTH = 4;
// private final static int MAX_PASS_ATTEMPTS = 3;
// private final static int PASS_RETRY_WAIT_TIMEOUT = 30000;
private EditText mEnterPassphrase;
private EditText mNewPassphrase;
private EditText mConfirmNewPassphrase;
private View mViewCreatePassphrase;
private View mViewEnterPassphrase;
private CacheWordHandler mCacheWord;
private String mPasswordError;
private TwoViewSlider mSlider;
private ImApp mApp;
private TextView mBtnCreate;
private TextView mBtnSkip;
public static final String ACTION_CHANGE_PASSPHRASE = "cp";
public static final String ACTION_RESET_PASSPHRASE = "reset";
private Handler mHandler = new Handler();
private String mAction = "unlock";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mApp = (ImApp)getApplication();
checkCustomFont ();
setContentView(R.layout.activity_lock_screen);
if (getIntent() != null && getIntent().getAction() != null)
mAction = getIntent().getAction();
mCacheWord = new CacheWordHandler(mApp, (ICacheWordSubscriber)this);
mCacheWord.connectToService();
mViewCreatePassphrase = findViewById(R.id.llCreatePassphrase);
mViewEnterPassphrase = findViewById(R.id.llEnterPassphrase);
mEnterPassphrase = (EditText) findViewById(R.id.editEnterPassphrase);
mNewPassphrase = (EditText) findViewById(R.id.editNewPassphrase);
mConfirmNewPassphrase = (EditText) findViewById(R.id.editConfirmNewPassphrase);
ViewFlipper vf = (ViewFlipper) findViewById(R.id.viewFlipper1);
LinearLayout flipView1 = (LinearLayout) findViewById(R.id.flipView1);
LinearLayout flipView2 = (LinearLayout) findViewById(R.id.flipView2);
mSlider = new TwoViewSlider(vf, flipView1, flipView2, mNewPassphrase, mConfirmNewPassphrase);
mBtnSkip = (TextView)findViewById(R.id.btnSkip);
mBtnSkip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(new Runnable ()
{
public void run ()
{
LockScreenActivity.this.finish();
}
});
}
});
if (mAction.equals(ACTION_CHANGE_PASSPHRASE))
{
changePassphrase();
}
//not set color
final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
int themeColorBg = settings.getInt("themeColorBg",-1);
if (themeColorBg != -1)
findViewById(R.id.llRoot).setBackgroundColor(themeColorBg);
}
@Override
protected void onPause() {
super.onPause();
mCacheWord.detach();
}
@Override
protected void onResume() {
super.onResume();
mCacheWord.reattach();
getSupportActionBar().hide();
}
@Override
protected void onDestroy() {
super.onDestroy();
mCacheWord.disconnectFromService();
}
private boolean newEqualsConfirmation() {
return mNewPassphrase.getText().toString()
.equals(mConfirmNewPassphrase.getText().toString());
}
private void showValidationError() {
Toast.makeText(LockScreenActivity.this, mPasswordError, Toast.LENGTH_LONG).show();
mNewPassphrase.requestFocus();
}
private void showInequalityError() {
Toast.makeText(LockScreenActivity.this,
getString(R.string.lock_screen_passphrases_not_matching),
Toast.LENGTH_SHORT).show();
clearNewFields();
}
private void clearNewFields() {
mNewPassphrase.getEditableText().clear();
mConfirmNewPassphrase.getEditableText().clear();
}
private boolean isPasswordValid() {
return validatePassword(mNewPassphrase.getText().toString().toCharArray());
}
private boolean isPasswordFieldEmpty() {
return mNewPassphrase.getText().toString().length() == 0;
}
private boolean isConfirmationFieldEmpty() {
return mConfirmNewPassphrase.getText().toString().length() == 0;
}
private void initializeWithPassphrase() {
try {
String passphrase = mNewPassphrase.getText().toString();
if (!passphrase.isEmpty()) {
PassphraseSecrets p = (PassphraseSecrets)mCacheWord.getCachedSecrets();
mCacheWord.changePassphrase(p,passphrase.toCharArray());
//now remove the temp passphrase if it exists
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
if (settings.contains(ImApp.PREFERENCE_KEY_TEMP_PASS))
settings.edit().remove(ImApp.PREFERENCE_KEY_TEMP_PASS).commit();
finish();
}
} catch (Exception e) {
// TODO initialization failed
Log.e(TAG, "Cacheword pass initialization failed: " + e.getMessage());
}
}
private void changePassphrase() {
// Passphrase is not set, so allow the user to create one
View viewCreatePassphrase = findViewById(R.id.llCreatePassphrase);
viewCreatePassphrase.setVisibility(View.VISIBLE);
mViewEnterPassphrase.setVisibility(View.GONE);
mNewPassphrase.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE)
{
if (isPasswordFieldEmpty())
{
resetPassphrase();
finish();
}
else if (!isPasswordValid())
showValidationError();
else
mSlider.showConfirmationField();
}
return false;
}
});
mConfirmNewPassphrase.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE) {
if (!newEqualsConfirmation()) {
showInequalityError();
mSlider.showNewPasswordField();
}
}
return false;
}
});
mBtnCreate = (TextView)findViewById(R.id.btnCreate);
mBtnCreate.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// validate
if (isPasswordFieldEmpty())
{
resetPassphrase();
finish();
}
else if (!isPasswordValid()) {
showValidationError();
mSlider.showNewPasswordField();
} else if (isConfirmationFieldEmpty() && !isPasswordFieldEmpty()) {
mBtnSkip.setVisibility(View.GONE);
mSlider.showConfirmationField();
mBtnCreate.setText(R.string.lock_screen_confirm_passphrase);
} else if (!newEqualsConfirmation()) {
showInequalityError();
} else if (!isConfirmationFieldEmpty() && !isPasswordFieldEmpty()) {
initializeWithPassphrase();
}
}
});
}
private void promptPassphrase() {
mViewCreatePassphrase.setVisibility(View.GONE);
mViewEnterPassphrase.setVisibility(View.VISIBLE);
mEnterPassphrase.setOnEditorActionListener(new OnEditorActionListener()
{
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_GO)
{
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
Handler threadHandler = new Handler();
imm.hideSoftInputFromWindow(v.getWindowToken(), 0, new ResultReceiver(
threadHandler)
{
@Override
protected void onReceiveResult(int resultCode, Bundle resultData)
{
super.onReceiveResult(resultCode, resultData);
if (mEnterPassphrase.getText().toString().length() == 0)
return;
// Check passphrase
try {
char[] passphrase = mEnterPassphrase.getText().toString().toCharArray();
mCacheWord.setPassphrase(passphrase);
} catch (Exception e) {
mEnterPassphrase.setText("");
// TODO implement try again and wipe if fail
Log.e(TAG, "Cacheword pass verification failed: " + e.getMessage());
return;
}
}
});
return true;
}
return false;
}
});
}
private boolean validatePassword(char[] pass)
{
if (pass.length < MIN_PASS_LENGTH && pass.length != 0)
{
// should we support some user string message here?
mPasswordError = getString(R.string.pass_err_length);
return false;
}
return true;
}
public class TwoViewSlider {
private boolean firstIsShown = true;
private ViewFlipper flipper;
private LinearLayout container1;
private LinearLayout container2;
private View firstView;
private View secondView;
private Animation pushRightIn;
private Animation pushRightOut;
private Animation pushLeftIn;
private Animation pushLeftOut;
public TwoViewSlider(ViewFlipper flipper, LinearLayout container1, LinearLayout container2,
View view1, View view2) {
this.flipper = flipper;
this.container1 = container1;
this.container2 = container2;
this.firstView = view1;
this.secondView = view2;
pushRightIn = AnimationUtils.loadAnimation(LockScreenActivity.this, R.anim.push_right_in);
pushRightOut = AnimationUtils.loadAnimation(LockScreenActivity.this, R.anim.push_right_out);
pushLeftIn = AnimationUtils.loadAnimation(LockScreenActivity.this, R.anim.push_left_in);
pushLeftOut = AnimationUtils.loadAnimation(LockScreenActivity.this, R.anim.push_left_out);
}
public void showNewPasswordField() {
if (firstIsShown)
return;
flipper.setInAnimation(pushRightIn);
flipper.setOutAnimation(pushRightOut);
flip();
}
public void showConfirmationField() {
if (!firstIsShown)
return;
flipper.setInAnimation(pushLeftIn);
flipper.setOutAnimation(pushLeftOut);
flip();
}
private void flip() {
if (firstIsShown) {
firstIsShown = false;
container2.removeAllViews();
container2.addView(secondView);
} else {
firstIsShown = true;
container1.removeAllViews();
container1.addView(firstView);
}
flipper.showNext();
}
}
@Override
public void onCacheWordUninitialized() {
//this should never happen
}
@Override
public void onCacheWordLocked() {
promptPassphrase();
}
@Override
public void onCacheWordOpened() {
if (mAction.equals("unlock")) {
// mCacheWord.setTimeout(0);
setResult(RESULT_OK);
finish();
}
}
private void checkCustomFont ()
{
if (Preferences.getLanguage() != null
&& Preferences.getLanguage().equalsIgnoreCase("bo"))
{
CustomTypefaceManager.loadFromAssets(this,true);
}
else
{
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> mInputMethodProperties = imm.getEnabledInputMethodList();
final int N = mInputMethodProperties.size();
boolean loadTibetan = false;
for (int i = 0; i < N; i++) {
InputMethodInfo imi = mInputMethodProperties.get(i);
//imi contains the information about the keyboard you are using
if (imi.getPackageName().equals("org.ironrabbit.bhoboard")) {
// CustomTypefaceManager.loadFromKeyboard(this);
loadTibetan = true;
break;
}
}
CustomTypefaceManager.loadFromAssets(this,loadTibetan);
}
}
void resetPassphrase () {
//set temporary passphrase
try {
PassphraseSecrets p = (PassphraseSecrets)mCacheWord.getCachedSecrets();
if (p != null) {
String tempPassphrase = UUID.randomUUID().toString();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
settings.edit().putString(ImApp.PREFERENCE_KEY_TEMP_PASS, tempPassphrase).apply();
mCacheWord.changePassphrase(p, tempPassphrase.toCharArray());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}