package info.blockchain.wallet.ui; import java.security.SecureRandom; import org.apache.commons.lang.RandomStringUtils; import org.json.simple.JSONObject; import org.spongycastle.util.encoders.Hex; import com.google.android.gcm.GCMRegistrar; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.preference.PreferenceManager; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences.Editor; import android.content.pm.ActivityInfo; import android.text.Editable; import android.text.TextWatcher; import android.text.util.Linkify; //import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.Window; import android.view.View.OnKeyListener; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.CheckBox; import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; import android.widget.TextView.OnEditorActionListener; import piuk.blockchain.android.Constants; import piuk.blockchain.android.EventListeners; import piuk.blockchain.android.MyWallet; import piuk.blockchain.android.R; import piuk.blockchain.android.SuccessCallback; import piuk.blockchain.android.WalletApplication; public class PinCreateActivity extends Activity { private TextView tvHeader = null; private TextView tvWarning1 = null; private TextView tvWarning2 = null; private TextView tvTOS = null; private LinearLayout tosLayout = null; private LinearLayout tosPinConfirm = null; private CheckBox cbAccept = null; private String strPIN = null; private EditText pin1 = null; private EditText pin2 = null; private EditText pin3 = null; private EditText pin4 = null; private EditText pin1_2 = null; private EditText pin2_2 = null; private EditText pin3_2 = null; private EditText pin4_2 = null; private TextWatcher twPin1 = null; private TextWatcher twPin2 = null; private TextWatcher twPin3 = null; private TextWatcher twPin4 = null; private TextWatcher twPin1_2 = null; private TextWatcher twPin2_2 = null; private TextWatcher twPin3_2 = null; private TextWatcher twPin4_2 = null; public static final int PBKDF2Iterations = 2000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); // this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); if(!DeviceUtil.getInstance(this).isSmallScreen()) { setContentView(R.layout.activity_pin_create2); } else { setContentView(R.layout.activity_pin_create_small); } setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); cbAccept = (CheckBox)findViewById(R.id.tos_accept); tvTOS = (TextView)findViewById(R.id.tos_text); tvTOS.setText(R.string.accept_tos); Linkify.addLinks(tvTOS, Linkify.WEB_URLS); tosLayout = (LinearLayout) findViewById(R.id.tos); tosLayout.setVisibility(View.INVISIBLE); tosPinConfirm = (LinearLayout) findViewById(R.id.confirm_pin); tosPinConfirm.setVisibility(View.INVISIBLE); tvHeader = (TextView)findViewById(R.id.header); tvHeader.setTypeface(TypefaceUtil.getInstance(this).getGravityLightTypeface()); tvHeader.setText(R.string.create_new_wallet); tvWarning1 = (TextView)findViewById(R.id.warning1); tvWarning1.setText(R.string.set_your_pin); tvWarning2 = (TextView)findViewById(R.id.warning2); tvWarning2.setTextColor(0xFF039BD3); tvWarning2.setText(R.string.set_your_pin2); pin1 = ((EditText)findViewById(R.id.pin1)); pin2 = ((EditText)findViewById(R.id.pin2)); pin3 = ((EditText)findViewById(R.id.pin3)); pin4 = ((EditText)findViewById(R.id.pin4)); pin1_2 = ((EditText)findViewById(R.id.pin1_2)); pin2_2 = ((EditText)findViewById(R.id.pin2_2)); pin3_2 = ((EditText)findViewById(R.id.pin3_2)); pin4_2 = ((EditText)findViewById(R.id.pin4_2)); pin2.setVisibility(View.INVISIBLE); pin3.setVisibility(View.INVISIBLE); pin4.setVisibility(View.INVISIBLE); pin1_2.setVisibility(View.INVISIBLE); pin2_2.setVisibility(View.INVISIBLE); pin3_2.setVisibility(View.INVISIBLE); pin4_2.setVisibility(View.INVISIBLE); pin1.postDelayed(new Runnable() { @Override public void run() { InputMethodManager keyboard = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); keyboard.showSoftInput(pin1, 0); } }, 50); final long DELAY = 500; pin1.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { return false; } }); twPin1 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin1.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin1.getText().toString().length() == 1) { pin2.setVisibility(View.VISIBLE); pin1.postDelayed(new Runnable() { @Override public void run() { pin2.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin1.addTextChangedListener(twPin1); twPin2 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin2.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin2.getText().toString().length() == 1) { pin3.setVisibility(View.VISIBLE); pin2.postDelayed(new Runnable() { @Override public void run() { pin3.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin2.addTextChangedListener(twPin2); twPin3 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin3.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin3.getText().toString().length() == 1) { pin4.setVisibility(View.VISIBLE); pin3.postDelayed(new Runnable() { @Override public void run() { pin4.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin3.addTextChangedListener(twPin3); twPin4 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin4.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin4.getText().toString().length() == 1) { pin1_2.setVisibility(View.VISIBLE); tosLayout.setVisibility(View.VISIBLE); tosPinConfirm.setVisibility(View.VISIBLE); tvWarning2.setText(R.string.confirm_your_pin); pin4.postDelayed(new Runnable() { @Override public void run() { pin1_2.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin4.addTextChangedListener(twPin4); twPin1_2 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin1_2.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin2.getText().toString().length() == 1) { pin2_2.setVisibility(View.VISIBLE); pin1_2.postDelayed(new Runnable() { @Override public void run() { pin2_2.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin1_2.addTextChangedListener(twPin1_2); twPin2_2 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin2_2.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin2_2.getText().toString().length() == 1) { pin3_2.setVisibility(View.VISIBLE); pin2_2.postDelayed(new Runnable() { @Override public void run() { pin3_2.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin2_2.addTextChangedListener(twPin2_2); twPin3_2 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin3_2.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin3_2.getText().toString().length() == 1) { pin4_2.setVisibility(View.VISIBLE); pin3_2.postDelayed(new Runnable() { @Override public void run() { pin4_2.requestFocus(); } }, DELAY); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin3_2.addTextChangedListener(twPin3_2); twPin4_2 = new TextWatcher() { public void afterTextChanged(Editable s) { if(pin4_2.getText().toString().length() == 0) { resetPinDisplay(); } else if(pin4_2.getText().toString().length() == 1) { tosLayout.setVisibility(View.VISIBLE); } } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; pin4_2.addTextChangedListener(twPin4_2); pin4_2.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if(actionId == EditorInfo.IME_ACTION_DONE) { InputMethodManager imm = (InputMethodManager)PinCreateActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(pin4_2.getWindowToken(), 0); } return false; } }); cbAccept.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(cbAccept.isChecked()) { final String p1 = pin1.getText().toString() + pin2.getText().toString() + pin3.getText().toString() + pin4.getText().toString(); final String p2 = pin1_2.getText().toString() + pin2_2.getText().toString() + pin3_2.getText().toString() + pin4_2.getText().toString(); if(p1.equals("0000") || p2.equals("0000")) { resetPinDisplay(); Toast.makeText(PinCreateActivity.this.getApplication(), R.string.zero_pin, Toast.LENGTH_SHORT).show(); return; } if(p1 != null && p2 != null && p1.length() == 4 && p2.length() == 4 && p1.equals(p2)) { final ProgressDialog progressDialog = ProgressDialog.show(PinCreateActivity.this, "", getString(R.string.creating_account), true); progressDialog.show(); final Handler handler = new Handler(); new Thread() { @Override public void run() { Looper.prepare(); final WalletApplication application = WalletUtil.getInstance(PinCreateActivity.this).getWalletApplication(); try { try { application.generateNewWallet(); } catch (Exception e1) { throw new Exception("Error Generating Wallet"); } final String guid = application.getRemoteWallet().getGUID(); final String sharedKey = application.getRemoteWallet().getSharedKey(); final String pinCode = p1; final String password = pinCode + pinCode + pinCode; application.getRemoteWallet().setTemporyPassword(password); if (!application.getRemoteWallet().remoteSave("")) { throw new Exception("Unknown Error Inserting wallet"); } EventListeners.invokeWalletDidChange(); handler.post(new Runnable() { public void run() { try { progressDialog.dismiss(); // dismiss(); // final AbstractWalletActivity activity = (AbstractWalletActivity) getActivity(); Toast.makeText(PinCreateActivity.this.getApplication(), R.string.new_account_success, Toast.LENGTH_SHORT).show(); // PinEntryActivity.clearPrefValues(application); final Editor edit = PreferenceManager.getDefaultSharedPreferences(application.getApplicationContext()).edit(); edit.putString("guid", guid); edit.putString("sharedKey", sharedKey); if (edit.commit()) { handler.post(new Runnable() { @Override public void run() { new Thread(new Runnable(){ @Override public void run() { Looper.prepare(); // // Save PIN // try { byte[] bytes = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(bytes); final String key = new String(Hex.encode(bytes), "UTF-8"); random.nextBytes(bytes); final String value = new String(Hex.encode(bytes), "UTF-8"); final JSONObject response = piuk.blockchain.android.ui.PinEntryActivity.apiStoreKey(key, value, pinCode); if (response.get("success") != null) { edit.putString("pin_kookup_key", key); edit.putString("encrypted_password", MyWallet.encrypt(application.getRemoteWallet().getTemporyPassword(), value, PBKDF2Iterations)); if (!edit.commit()) { throw new Exception("Error Saving Preferences"); } else { TimeOutUtil.getInstance().updatePin(); application.setTemporyPIN(pinCode); Intent intent = new Intent(PinCreateActivity.this, SecureWallet.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } } else { Toast.makeText(application, response.toString(), Toast.LENGTH_SHORT).show(); } } catch (Exception e) { Toast.makeText(application, e.getStackTrace().toString(), Toast.LENGTH_SHORT).show(); e.printStackTrace(); } // // // Looper.loop(); } }).start(); // // // application.checkIfWalletHasUpdated(password, guid, sharedKey, true, new SuccessCallback(){ @Override public void onSuccess() { // activity.registerNotifications(); try { final String regId = GCMRegistrar.getRegistrationId(PinCreateActivity.this); if (regId == null || regId.equals("")) { GCMRegistrar.register(PinCreateActivity.this, Constants.SENDER_ID); } else { application.registerForNotificationsIfNeeded(regId); } } catch (Exception e) { e.printStackTrace(); } } @Override public void onFail() { Toast.makeText(application, R.string.toast_error_syncing_wallet, Toast.LENGTH_SHORT).show(); } }); } }); } else { throw new Exception("Error saving preferences"); } } catch (Exception e) { e.printStackTrace(); application.clearWallet(); Toast.makeText(PinCreateActivity.this.getApplication(), e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } } }); } catch (final Exception e) { e.printStackTrace(); application.clearWallet(); handler.post(new Runnable() { public void run() { progressDialog.dismiss(); Toast.makeText(PinCreateActivity.this.getApplication(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } }); } Looper.loop(); } }.start(); } else { resetPinDisplay(); Toast.makeText(PinCreateActivity.this, R.string.enter_matching_pins, Toast.LENGTH_LONG).show(); } } } }); } void resetPinDisplay() { pin1.removeTextChangedListener(twPin1); pin2.removeTextChangedListener(twPin2); pin3.removeTextChangedListener(twPin3); pin4.removeTextChangedListener(twPin4); pin1_2.removeTextChangedListener(twPin1_2); pin2_2.removeTextChangedListener(twPin2_2); pin3_2.removeTextChangedListener(twPin3_2); pin4_2.removeTextChangedListener(twPin4_2); pin1.setText(""); pin2.setText(""); pin3.setText(""); pin4.setText(""); pin1_2.setText(""); pin2_2.setText(""); pin3_2.setText(""); pin4_2.setText(""); pin1.addTextChangedListener(twPin1); pin2.addTextChangedListener(twPin2); pin3.addTextChangedListener(twPin3); pin4.addTextChangedListener(twPin4); pin1_2.addTextChangedListener(twPin1_2); pin2_2.addTextChangedListener(twPin2_2); pin3_2.addTextChangedListener(twPin3_2); pin4_2.addTextChangedListener(twPin4_2); pin2.setVisibility(View.INVISIBLE); pin3.setVisibility(View.INVISIBLE); pin4.setVisibility(View.INVISIBLE); pin1_2.setVisibility(View.INVISIBLE); pin2_2.setVisibility(View.INVISIBLE); pin3_2.setVisibility(View.INVISIBLE); pin4_2.setVisibility(View.INVISIBLE); cbAccept.setChecked(false); tosLayout.setVisibility(View.INVISIBLE); tosPinConfirm.setVisibility(View.INVISIBLE); tvWarning2.setText(R.string.set_your_pin2); pin1.requestFocus(); } }