use MoneroThreadPoolExecutor for wallet creation (#53)

merge-requests/3/head
m2049r 7 years ago committed by GitHub
parent 7a9bb22da7
commit eb2b3b5675

@ -47,6 +47,7 @@ import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import java.io.File;
import java.io.FileInputStream;
@ -196,7 +197,7 @@ public class LoginActivity extends AppCompatActivity
// copy + delete seems safer than rename because we call rollback easily
boolean renameWallet(File walletFile, String newName) {
if (copyWallet(walletFile, new File(walletFile.getParentFile(), newName), false, true)) {
if (copyWallet(walletFile, new File(walletFile.getParentFile(), newName), false)) {
deleteWallet(walletFile);
return true;
} else {
@ -300,7 +301,7 @@ public class LoginActivity extends AppCompatActivity
// TODO probably better to copy to a new file and then rename
// then if something fails we have the old backup at least
// or just create a new backup every time and keep n old backups
return copyWallet(walletFile, backupFile, true, true);
return copyWallet(walletFile, backupFile, true);
}
@Override
@ -501,14 +502,15 @@ public class LoginActivity extends AppCompatActivity
super.onPause();
}
AsyncTask asyncWaitTask = null;
AsyncTask asyncWaitTask = null; // TODO should this really be set from all AsyncTasks here?
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
// wait for WalletService to finish
if (WalletService.Running && (asyncWaitTask == null)) {
Log.d(TAG, "new process dialog");
// and show a progress dialog, but only if there isn't one already
new AsyncWaitForService().execute();
}
}
@ -658,45 +660,87 @@ public class LoginActivity extends AppCompatActivity
//////////////////////////////////////////
static final String MNEMONIC_LANGUAGE = "English"; // see mnemonics/electrum-words.cpp for more
// TODO make this an AsyncTask?
public void createWallet(final String name, final String password, final WalletCreator walletCreator) {
final GenerateFragment genFragment = (GenerateFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
File newWalletFolder = new File(getStorageRoot(), ".new");
if (!newWalletFolder.exists()) {
if (!newWalletFolder.mkdir()) {
Log.e(TAG, "Cannot create new wallet dir " + newWalletFolder.getAbsolutePath());
genFragment.walletGenerateError();
return;
}
private class AsyncCreateWallet extends AsyncTask<Void, Void, Boolean> {
String walletName;
String walletPassword;
WalletCreator walletCreator;
File newWalletFile;
public AsyncCreateWallet(String name, String password, WalletCreator walletCreator) {
super();
this.walletName = name;
this.walletPassword = password;
this.walletCreator = walletCreator;
}
if (!newWalletFolder.isDirectory()) {
Log.e(TAG, "New wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
genFragment.walletGenerateError();
return;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
File cacheFile = new File(newWalletFolder, name);
cacheFile.delete();
File keysFile = new File(newWalletFolder, name + ".keys");
keysFile.delete();
File addressFile = new File(newWalletFolder, name + ".address.txt");
addressFile.delete();
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
Log.e(TAG, "Cannot remove all old wallet files: " + cacheFile.getAbsolutePath());
genFragment.walletGenerateError();
return;
@Override
protected Boolean doInBackground(Void... params) {
File newWalletFolder = new File(getStorageRoot(), ".new");
if (!newWalletFolder.exists()) {
if (!newWalletFolder.mkdir()) {
Log.e(TAG, "Cannot create new wallet dir " + newWalletFolder.getAbsolutePath());
return false;
}
}
if (!newWalletFolder.isDirectory()) {
Log.e(TAG, "New wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
return false;
}
File cacheFile = new File(newWalletFolder, walletName);
cacheFile.delete();
File keysFile = new File(newWalletFolder, walletName + ".keys");
keysFile.delete();
File addressFile = new File(newWalletFolder, walletName + ".address.txt");
addressFile.delete();
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
Log.e(TAG, "Cannot remove all old wallet files: " + cacheFile.getAbsolutePath());
return false;
}
newWalletFile = new File(newWalletFolder, walletName);
boolean success = walletCreator.createWallet(newWalletFile, walletPassword);
if (success) {
return true;
} else {
Toast.makeText(LoginActivity.this,
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
Log.e(TAG, "Could not create new wallet in " + newWalletFile.getAbsolutePath());
return false;
}
}
File newWalletFile = new File(newWalletFolder, name);
boolean success = walletCreator.createWallet(newWalletFile, password);
if (success) {
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_TYPE_ACCEPT);
} else {
Toast.makeText(LoginActivity.this,
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
Log.e(TAG, "Could not create new wallet in " + newWalletFile.getAbsolutePath());
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
startDetails(newWalletFile, walletPassword, GenerateReviewFragment.VIEW_TYPE_ACCEPT);
} else {
walletGenerateError();
}
LoginActivity.this.asyncWaitTask = null;
}
}
public void createWallet(String name, String password, WalletCreator walletCreator) {
new AsyncCreateWallet(name, password, walletCreator)
.executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
}
void walletGenerateError() {
try {
GenerateFragment genFragment = (GenerateFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
genFragment.walletGenerateError();
} catch (ClassCastException ex) {
Log.e(TAG, "walletGenerateError() but not in GenerateFragment");
}
}
@ -761,15 +805,18 @@ public class LoginActivity extends AppCompatActivity
});
}
@Override
public void onAccept(final String name, final String password) {
final File newWalletFile = new File(new File(getStorageRoot(), ".new"), name);
final File walletFolder = getStorageRoot();
final File walletFile = new File(walletFolder, name);
final boolean rc = copyWallet(newWalletFile, walletFile, false, false)
&&
(testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok);
File newWalletFile = new File(new File(getStorageRoot(), ".new"), name);
File walletFolder = getStorageRoot();
File walletFile = new File(walletFolder, name);
boolean rc = copyWallet(newWalletFile, walletFile, false);
if (rc) {
walletFile.delete(); // when recovering wallets, the cache seems corrupt
// TODO: figure out why this is so? Only for a private testnet?
rc = testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok;
}
if (rc) {
popFragmentStack(GENERATE_STACK);
Toast.makeText(LoginActivity.this,
@ -811,7 +858,7 @@ public class LoginActivity extends AppCompatActivity
}
}
boolean copyWallet(File srcWallet, File dstWallet, boolean overwrite, boolean full) {
boolean copyWallet(File srcWallet, File dstWallet, boolean overwrite) {
//Log.d(TAG, "src=" + srcWallet.exists() + " dst=" + dstWallet.exists());
if (walletExists(dstWallet, true) && !overwrite) return false;
if (!walletExists(srcWallet, false)) return false;
@ -822,13 +869,7 @@ public class LoginActivity extends AppCompatActivity
File dstDir = dstWallet.getParentFile();
String dstName = dstWallet.getName();
try {
if (full) {
// the cache is corrupt if we recover (!!) from seed
// the cache is ok if we immediately do a full refresh()
// recoveryheight is ignored but not on watchonly wallet ?! - find out why
// so we just ignore the cache file and rebuild it on first sync
copyFile(new File(srcDir, srcName), new File(dstDir, dstName));
}
copyFile(new File(srcDir, srcName), new File(dstDir, dstName));
copyFile(new File(srcDir, srcName + ".keys"), new File(dstDir, dstName + ".keys"));
copyFile(new File(srcDir, srcName + ".address.txt"), new File(dstDir, dstName + ".address.txt"));
success = true;

@ -239,7 +239,6 @@ public class LoginFragment extends Fragment {
displayedList.clear();
String x = isMainNet() ? "4" : "9A";
for (String s : walletList) {
// Log.d(TAG, "filtering " + s);
if (x.indexOf(s.charAt(1)) >= 0) displayedList.add(s);
}
}
@ -252,12 +251,14 @@ public class LoginFragment extends Fragment {
walletList.clear();
for (WalletManager.WalletInfo walletInfo : walletInfos) {
// Log.d(TAG, walletInfo.address);
// ONCE the walletInfo.address was null - because the address.txt was empty
// this was before the wallet generation was in its own therad with huge stack
// TODO: keep an eye on Wallet.getAddress() returning empty
String displayAddress = walletInfo.address;
if (displayAddress.length() == 95) {
if ((displayAddress != null) && displayAddress.length() == 95) {
displayAddress = walletInfo.address.substring(0, 6);
walletList.add("[" + displayAddress + "] " + walletInfo.name);
}
walletList.add("[" + displayAddress + "] " + walletInfo.name);
}
filterList();
((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();

@ -305,7 +305,7 @@ public class ReceiveFragment extends Fragment implements AsyncExchangeRate.Liste
}
private void show(String walletPath, String password) {
new ReceiveFragment.AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
new AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
walletPath, password);
}

Loading…
Cancel
Save