mirror of https://github.com/m2049r/xmrwallet.git
lots of minor fixes & tweaks. do not copy cache.
the cache file is corrupt after recovery (except watch only).
This commit is contained in:
parent
032aa24ab5
commit
9f38b957e1
|
@ -302,7 +302,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobje
|
|||
return reinterpret_cast<jlong>(wallet);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
||||
jstring path, jstring language,
|
||||
jboolean isTestNet,
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.content.Context;
|
|||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -38,8 +37,6 @@ import com.m2049r.xmrwallet.util.Helper;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
// TODO: somehow show which net we are generating for
|
||||
|
||||
public class GenerateFragment extends Fragment {
|
||||
static final String TAG = "GenerateFragment";
|
||||
|
||||
|
@ -119,7 +116,11 @@ public class GenerateFragment extends Fragment {
|
|||
etWalletPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||
etWalletMnemonic.requestFocus();
|
||||
if (etWalletAddress.length() > 0) {
|
||||
etWalletAddress.requestFocus();
|
||||
} else {
|
||||
etWalletMnemonic.requestFocus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -141,39 +142,45 @@ public class GenerateFragment extends Fragment {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
etWalletMnemonic.setOnClickListener(new View.OnClickListener() {
|
||||
etWalletMnemonic.setOnClickListener(new View.OnClickListener()
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.showKeyboard(getActivity());
|
||||
}
|
||||
});
|
||||
etWalletMnemonic.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (etWalletMnemonic.length() > 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
etWalletAddress.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletAddress.setVisibility(View.VISIBLE);
|
||||
if (etWalletAddress.length() == 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
}
|
||||
etWalletMnemonic.addTextChangedListener(new
|
||||
|
||||
}
|
||||
}
|
||||
TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (etWalletMnemonic.length() > 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
etWalletAddress.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletAddress.setVisibility(View.VISIBLE);
|
||||
if (etWalletAddress.length() == 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
etWalletAddress.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
etWalletAddress.setOnEditorActionListener(new TextView.OnEditorActionListener()
|
||||
|
||||
{
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||
if (etWalletAddress.length() == 0) {
|
||||
|
@ -191,40 +198,46 @@ public class GenerateFragment extends Fragment {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
etWalletAddress.setOnClickListener(new View.OnClickListener() {
|
||||
etWalletAddress.setOnClickListener(new View.OnClickListener()
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.showKeyboard(getActivity());
|
||||
}
|
||||
});
|
||||
etWalletAddress.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (etWalletAddress.length() > 0) {
|
||||
llRestoreKeys.setVisibility(View.VISIBLE);
|
||||
etWalletMnemonic.setVisibility(View.INVISIBLE);
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
llRestoreKeys.setVisibility(View.INVISIBLE);
|
||||
etWalletMnemonic.setVisibility(View.VISIBLE);
|
||||
if (etWalletMnemonic.length() == 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
etWalletAddress.addTextChangedListener(new
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
if (etWalletAddress.length() > 0) {
|
||||
llRestoreKeys.setVisibility(View.VISIBLE);
|
||||
etWalletMnemonic.setVisibility(View.INVISIBLE);
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
llRestoreKeys.setVisibility(View.INVISIBLE);
|
||||
etWalletMnemonic.setVisibility(View.VISIBLE);
|
||||
if (etWalletMnemonic.length() == 0) {
|
||||
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
etWalletRestoreHeight.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
etWalletViewKey.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
etWalletViewKey.setOnEditorActionListener(new TextView.OnEditorActionListener()
|
||||
|
||||
{
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||
if (viewKeyOk()) {
|
||||
|
@ -237,21 +250,22 @@ public class GenerateFragment extends Fragment {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
etWalletViewKey.setOnClickListener(new View.OnClickListener() {
|
||||
etWalletViewKey.setOnClickListener(new View.OnClickListener()
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.showKeyboard(getActivity());
|
||||
}
|
||||
});
|
||||
|
||||
etWalletSpendKey.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
etWalletSpendKey.setOnEditorActionListener(new TextView.OnEditorActionListener()
|
||||
|
||||
{
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||
if (spendKeyOk()) {
|
||||
if (bGenerate.getVisibility() == View.VISIBLE) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
generateWallet();
|
||||
}
|
||||
etWalletRestoreHeight.requestFocus();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getString(R.string.generate_check_key), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
@ -260,14 +274,18 @@ public class GenerateFragment extends Fragment {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
etWalletSpendKey.setOnClickListener(new View.OnClickListener() {
|
||||
etWalletSpendKey.setOnClickListener(new View.OnClickListener()
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.showKeyboard(getActivity());
|
||||
}
|
||||
});
|
||||
|
||||
etWalletRestoreHeight.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
etWalletRestoreHeight.setOnEditorActionListener(new TextView.OnEditorActionListener()
|
||||
|
||||
{
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||
if (bGenerate.getVisibility() == View.VISIBLE) {
|
||||
|
@ -280,7 +298,9 @@ public class GenerateFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
bGenerate.setOnClickListener(new View.OnClickListener() {
|
||||
bGenerate.setOnClickListener(new View.OnClickListener()
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
|
|
@ -27,8 +27,6 @@ import android.widget.TextView;
|
|||
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
|
||||
// TODO: somehow show which net we are generating for
|
||||
|
||||
public class GenerateReviewFragment extends Fragment {
|
||||
static final String TAG = "GenerateReviewFragment";
|
||||
|
||||
|
@ -84,13 +82,17 @@ public class GenerateReviewFragment extends Fragment {
|
|||
String seed = b.getString("seed");
|
||||
String view = b.getString("viewkey");
|
||||
String spend = b.getString("spendkey");
|
||||
long height = b.getLong("restoreHeight");
|
||||
|
||||
tvWalletName.setText(name);
|
||||
tvWalletPassword.setText(password);
|
||||
tvWalletAddress.setText(address);
|
||||
tvWalletMnemonic.setText(seed);
|
||||
tvWalletViewKey.setText(view);
|
||||
tvWalletSpendKey.setText(spend);
|
||||
if (spend.length() > 0) { // should be == 64, but spendkey is not in the API yet
|
||||
tvWalletSpendKey.setText(spend);
|
||||
} else {
|
||||
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
||||
}
|
||||
bAccept.setEnabled(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
|
@ -44,6 +45,10 @@ import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
|||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class LoginActivity extends AppCompatActivity
|
||||
implements LoginFragment.Listener, GenerateFragment.Listener, GenerateReviewFragment.Listener {
|
||||
|
@ -288,8 +293,7 @@ public class LoginActivity extends AppCompatActivity
|
|||
final String seed = newWallet.getSeed();
|
||||
final String address = newWallet.getAddress();
|
||||
final String view = newWallet.getSecretViewKey();
|
||||
final long height = newWallet.getBlockChainHeight();
|
||||
final String spend = "not available - use seed for recovery"; //TODO
|
||||
final String spend = newWallet.isWatchOnly() ? "" : "not available - use seed for recovery";
|
||||
newWallet.close();
|
||||
Log.d(TAG, "Created " + address);
|
||||
runOnUiThread(new Runnable() {
|
||||
|
@ -301,7 +305,6 @@ public class LoginActivity extends AppCompatActivity
|
|||
b.putString("address", address);
|
||||
b.putString("viewkey", view);
|
||||
b.putString("spendkey", spend);
|
||||
b.putLong("restoreHeight", height);
|
||||
startReviewFragment(b);
|
||||
}
|
||||
});
|
||||
|
@ -321,7 +324,6 @@ public class LoginActivity extends AppCompatActivity
|
|||
public Wallet createWallet(String path, String password) {
|
||||
return WalletManager.getInstance()
|
||||
.createWallet(path, password, MNEMONIC_LANGUAGE);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -358,37 +360,16 @@ public class LoginActivity extends AppCompatActivity
|
|||
|
||||
@Override
|
||||
public void onAccept(final String name, final String password) {
|
||||
File newWalletFolder = new File(getStorageRoot(), ".new");
|
||||
if (!newWalletFolder.isDirectory()) {
|
||||
Log.e(TAG, "New wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
|
||||
return;
|
||||
}
|
||||
final String newWalletPath = new File(newWalletFolder, name).getAbsolutePath();
|
||||
final File newWalletFolder = new File(getStorageRoot(), ".new");
|
||||
final File walletFolder = getStorageRoot();
|
||||
new Thread(null,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "opening wallet " + newWalletPath);
|
||||
Wallet newWallet = WalletManager.getInstance()
|
||||
.openWallet(newWalletPath, password);
|
||||
Wallet.Status status = newWallet.getStatus();
|
||||
Log.d(TAG, "wallet opened " + newWallet.getStatus());
|
||||
if (status != Wallet.Status.Status_Ok) {
|
||||
Log.e(TAG, "New wallet is " + status.toString());
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
Toast.makeText(LoginActivity.this,
|
||||
getString(R.string.generate_wallet_create_failed_1), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
newWallet.close();
|
||||
return;
|
||||
}
|
||||
final String walletPath = new File(getStorageRoot(), name).getAbsolutePath();
|
||||
final boolean rc = newWallet.store(walletPath);
|
||||
Log.d(TAG, "wallet stored with rc=" + rc);
|
||||
newWallet.close();
|
||||
Log.d(TAG, "wallet closed");
|
||||
final String walletPath = new File(walletFolder, name).getAbsolutePath();
|
||||
final boolean rc = copyWallet(walletFolder, newWalletFolder, name)
|
||||
&&
|
||||
(testWallet(walletPath, password) == Wallet.Status.Status_Ok);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (rc) {
|
||||
|
@ -408,4 +389,45 @@ public class LoginActivity extends AppCompatActivity
|
|||
, "AcceptWallet", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
||||
}
|
||||
|
||||
Wallet.Status testWallet(String path, String password) {
|
||||
Log.d(TAG, "testing wallet " + path);
|
||||
Wallet aWallet = WalletManager.getInstance().openWallet(path, password);
|
||||
if (aWallet == null) return Wallet.Status.Status_Error; // does this ever happen?
|
||||
Wallet.Status status = aWallet.getStatus();
|
||||
Log.d(TAG, "wallet tested " + aWallet.getStatus());
|
||||
aWallet.close();
|
||||
return status;
|
||||
}
|
||||
|
||||
boolean copyWallet(File dstDir, File srcDir, String name) {
|
||||
boolean success = false;
|
||||
try {
|
||||
// TODO: the cache is corrupt if we recover (!!)
|
||||
// TODO recoveryheight is ignored but not on watchonly wallet ?! - find out why
|
||||
//copyFile(dstDir, srcDir, name);
|
||||
copyFile(dstDir, srcDir, name + ".keys");
|
||||
copyFile(dstDir, srcDir, name + ".address.txt");
|
||||
success = true;
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, "wallet copy failed: " + ex.getMessage());
|
||||
// try to rollback
|
||||
new File(dstDir, name).delete();
|
||||
new File(dstDir, name + ".keys").delete();
|
||||
new File(dstDir, name + ".address.txt").delete();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void copyFile(File dstDir, File srcDir, String name) throws IOException {
|
||||
FileChannel inChannel = new FileInputStream(new File(srcDir, name)).getChannel();
|
||||
FileChannel outChannel = new FileOutputStream(new File(dstDir, name)).getChannel();
|
||||
try {
|
||||
inChannel.transferTo(0, inChannel.size(), outChannel);
|
||||
} finally {
|
||||
if (inChannel != null)
|
||||
inChannel.close();
|
||||
if (outChannel != null)
|
||||
outChannel.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,8 @@ public class WalletService extends Service {
|
|||
fullRefresh = true;
|
||||
}
|
||||
}
|
||||
observer.onRefreshed(wallet, fullRefresh);
|
||||
if (observer != null)
|
||||
observer.onRefreshed(wallet, fullRefresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -354,6 +355,7 @@ public class WalletService extends Service {
|
|||
if (listener == null) {
|
||||
Log.d(TAG, "start() loadWallet");
|
||||
Wallet aWallet = loadWallet(walletName, walletPassword);
|
||||
// TODO check aWallet and die gracefully if neccessary
|
||||
listener = new MyWalletListener(aWallet);
|
||||
listener.start();
|
||||
showProgress(100);
|
||||
|
@ -420,6 +422,7 @@ public class WalletService extends Service {
|
|||
wallet = null;
|
||||
// TODO what do we do with the progress??
|
||||
// TODO tell the activity this failed
|
||||
// this crashes in MyWalletListener(Wallet aWallet) as wallet == null
|
||||
}
|
||||
}
|
||||
return wallet;
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
<string name="generate_button_accept">I have noted the mnemonic seed\nNow, I want to loose all my money!</string>
|
||||
<string name="generate_button_reset">I\'m confused - Let me start again!</string>
|
||||
|
||||
<string name="generate_wallet_watchonly"><Watch Only Wallet></string>
|
||||
|
||||
<string name="generate_wallet_exists">Wallet exists! Choose another name</string>
|
||||
<string name="generate_wallet_created">Wallet created</string>
|
||||
<string name="generate_wallet_create_failed_1">Wallet create failed (1/2)</string>
|
||||
|
|
Loading…
Reference in New Issue