mirror of https://github.com/m2049r/xmrwallet.git
Merge pull request #39 from m2049r/bugfix_issue_36
Use AsyncTask with 5MB stack in lots of places
This commit is contained in:
commit
5b3e92e91a
|
@ -17,8 +17,10 @@
|
|||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -28,15 +30,13 @@ import android.widget.TextView;
|
|||
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
||||
|
||||
import java.io.File;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
|
||||
public class GenerateReviewFragment extends Fragment {
|
||||
static final String TAG = "GenerateReviewFragment";
|
||||
static final public String VIEW_DETAILS = "details";
|
||||
static final public String VIEW_ACCEPT = "accept";
|
||||
static final public String VIEW_WALLET = "wallet";
|
||||
static final public String VIEW_TYPE_DETAILS = "details";
|
||||
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||
|
||||
ProgressBar pbProgress;
|
||||
TextView tvWalletName;
|
||||
|
@ -76,16 +76,12 @@ public class GenerateReviewFragment extends Fragment {
|
|||
|
||||
showProgress();
|
||||
|
||||
Bundle b = getArguments();
|
||||
String type = b.getString("type");
|
||||
if (!type.equals(VIEW_WALLET)) {
|
||||
String path = b.getString("path");
|
||||
String password = b.getString("password");
|
||||
tvWalletName.setText(new File(path).getName());
|
||||
show(path, password, type);
|
||||
} else {
|
||||
show(walletCallback.getWallet(), null, type);
|
||||
}
|
||||
Bundle args = getArguments();
|
||||
String path = args.getString("path");
|
||||
String password = args.getString("password");
|
||||
String type = args.getString("type");
|
||||
new AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
|
||||
path, password, type);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -96,40 +92,64 @@ public class GenerateReviewFragment extends Fragment {
|
|||
acceptCallback.onAccept(name, password);
|
||||
}
|
||||
|
||||
private void show(final String walletPath, final String password, final String type) {
|
||||
new Thread(null,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
show(wallet, password, type);
|
||||
wallet.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
, "DetailsReview", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
||||
}
|
||||
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||
String type;
|
||||
String password;
|
||||
|
||||
private void show(final Wallet wallet, final String password, final String type) {
|
||||
if (type.equals(GenerateReviewFragment.VIEW_ACCEPT)) {
|
||||
tvWalletPassword.setText(password);
|
||||
bAccept.setVisibility(View.VISIBLE);
|
||||
bAccept.setEnabled(true);
|
||||
String name;
|
||||
String address;
|
||||
String seed;
|
||||
String viewKey;
|
||||
boolean isWatchOnly;
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(String... params) {
|
||||
if (params.length != 3) return false;
|
||||
String walletPath = params[0];
|
||||
password = params[1];
|
||||
type = params[2];
|
||||
|
||||
Wallet wallet;
|
||||
boolean closeWallet;
|
||||
if (type.equals(GenerateReviewFragment.VIEW_TYPE_WALLET)) {
|
||||
wallet = GenerateReviewFragment.this.walletCallback.getWallet();
|
||||
closeWallet = false;
|
||||
} else {
|
||||
wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
closeWallet = true;
|
||||
}
|
||||
if (wallet.getStatus() != Wallet.Status.Status_Ok) return false;
|
||||
name = wallet.getName();
|
||||
address = wallet.getAddress();
|
||||
seed = wallet.getSeed();
|
||||
viewKey = wallet.getSecretViewKey();
|
||||
isWatchOnly = wallet.isWatchOnly();
|
||||
if (closeWallet) wallet.close();
|
||||
return true;
|
||||
}
|
||||
tvWalletName.setText(wallet.getName());
|
||||
tvWalletAddress.setText(wallet.getAddress());
|
||||
tvWalletMnemonic.setText(wallet.getSeed());
|
||||
tvWalletViewKey.setText(wallet.getSecretViewKey());
|
||||
String spend = wallet.isWatchOnly() ? "" : "not available - use seed for recovery";
|
||||
if (spend.length() > 0) { //TODO should be == 64, but spendkey is not in the API yet
|
||||
tvWalletSpendKey.setText(spend);
|
||||
} else {
|
||||
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
if (result) {
|
||||
if (type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT)) {
|
||||
tvWalletPassword.setText(password);
|
||||
bAccept.setVisibility(View.VISIBLE);
|
||||
bAccept.setEnabled(true);
|
||||
}
|
||||
tvWalletName.setText(name);
|
||||
tvWalletAddress.setText(address);
|
||||
tvWalletMnemonic.setText(seed);
|
||||
tvWalletViewKey.setText(viewKey);
|
||||
String spend = isWatchOnly ? "" : "not available - use seed for recovery";
|
||||
if (spend.length() > 0) { //TODO should be == 64, but spendkey is not in the API yet
|
||||
tvWalletSpendKey.setText(spend);
|
||||
} else {
|
||||
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
||||
}
|
||||
}
|
||||
hideProgress();
|
||||
}
|
||||
hideProgress();
|
||||
}
|
||||
|
||||
GenerateReviewFragment.Listener acceptCallback = null;
|
||||
|
@ -141,6 +161,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||
|
||||
public interface ListenerWithWallet {
|
||||
Wallet getWallet();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -121,7 +121,7 @@ public class LoginActivity extends AppCompatActivity
|
|||
promptPassword(walletName, new PasswordAction() {
|
||||
@Override
|
||||
public void action(String walletName, String password) {
|
||||
startDetails(walletFile, password, GenerateReviewFragment.VIEW_DETAILS);
|
||||
startDetails(walletFile, password, GenerateReviewFragment.VIEW_TYPE_DETAILS);
|
||||
}
|
||||
});
|
||||
} else { // this cannot really happen as we prefilter choices
|
||||
|
@ -646,6 +646,7 @@ 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);
|
||||
|
@ -666,7 +667,7 @@ public class LoginActivity extends AppCompatActivity
|
|||
cacheFile.delete();
|
||||
File keysFile = new File(newWalletFolder, name + ".keys");
|
||||
keysFile.delete();
|
||||
final File addressFile = new File(newWalletFolder, name + ".address.txt");
|
||||
File addressFile = new File(newWalletFolder, name + ".address.txt");
|
||||
addressFile.delete();
|
||||
|
||||
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
|
||||
|
@ -678,7 +679,7 @@ public class LoginActivity extends AppCompatActivity
|
|||
File newWalletFile = new File(newWalletFolder, name);
|
||||
boolean success = walletCreator.createWallet(newWalletFile, password);
|
||||
if (success) {
|
||||
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_ACCEPT);
|
||||
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_TYPE_ACCEPT);
|
||||
} else {
|
||||
Toast.makeText(LoginActivity.this,
|
||||
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.m2049r.xmrwallet;
|
|||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
|
@ -34,6 +35,7 @@ import android.widget.EditText;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
|
@ -43,8 +45,8 @@ import com.google.zxing.qrcode.QRCodeWriter;
|
|||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -187,38 +189,50 @@ public class ReceiveFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void show(final String address) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
tvAddress.setText(address);
|
||||
etPaymentId.setEnabled(true);
|
||||
etAmount.setEnabled(true);
|
||||
bPaymentId.setEnabled(true);
|
||||
bGenerate.setEnabled(true);
|
||||
hideProgress();
|
||||
generateQr();
|
||||
}
|
||||
});
|
||||
private void show(String address) {
|
||||
tvAddress.setText(address);
|
||||
etPaymentId.setEnabled(true);
|
||||
etAmount.setEnabled(true);
|
||||
bPaymentId.setEnabled(true);
|
||||
bGenerate.setEnabled(true);
|
||||
hideProgress();
|
||||
generateQr();
|
||||
}
|
||||
|
||||
private void show(final String walletPath, final String password) {
|
||||
new Thread(null,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
String address = wallet.getAddress();
|
||||
wallet.close();
|
||||
show(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
, "Receive", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
||||
private void show(String walletPath, String password) {
|
||||
new ReceiveFragment.AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
|
||||
walletPath, password);
|
||||
}
|
||||
|
||||
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||
String password;
|
||||
|
||||
String address;
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(String... params) {
|
||||
if (params.length != 2) return false;
|
||||
String walletPath = params[0];
|
||||
password = params[1];
|
||||
Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
address = wallet.getAddress();
|
||||
wallet.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
if (result) {
|
||||
show(address);
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getString(R.string.receive_cannot_open), Toast.LENGTH_LONG).show();
|
||||
hideProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean amountOk() {
|
||||
String amountEntry = etAmount.getText().toString();
|
||||
if (amountEntry.isEmpty()) return true;
|
||||
|
|
|
@ -24,7 +24,6 @@ import android.content.Intent;
|
|||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.net.UrlQuerySanitizer;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
|
@ -35,8 +34,6 @@ import android.support.v4.app.FragmentTransaction;
|
|||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -49,7 +46,6 @@ import com.m2049r.xmrwallet.util.BarcodeData;
|
|||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -594,7 +590,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
|||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
Bundle extras = new Bundle();
|
||||
extras.putString("type", GenerateReviewFragment.VIEW_WALLET);
|
||||
extras.putString("type", GenerateReviewFragment.VIEW_TYPE_WALLET);
|
||||
replaceFragment(new GenerateReviewFragment(), null, extras);
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2017 m2049r
|
||||
*
|
||||
* 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 com.m2049r.xmrwallet.util;
|
||||
|
||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
public class MoneroThreadPoolExecutor {
|
||||
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
|
||||
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
|
||||
private static final int KEEP_ALIVE_SECONDS = 30;
|
||||
|
||||
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
|
||||
private final AtomicInteger mCount = new AtomicInteger(1);
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
return new Thread(null, r, "MoneroTask #" + mCount.getAndIncrement(), MoneroHandlerThread.THREAD_STACK_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
private static final BlockingQueue<Runnable> sPoolWorkQueue =
|
||||
new LinkedBlockingQueue<>(128);
|
||||
|
||||
public static final Executor MONERO_THREAD_POOL_EXECUTOR;
|
||||
|
||||
static {
|
||||
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
|
||||
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
|
||||
sPoolWorkQueue, sThreadFactory);
|
||||
threadPoolExecutor.allowCoreThreadTimeOut(true);
|
||||
MONERO_THREAD_POOL_EXECUTOR = threadPoolExecutor;
|
||||
}
|
||||
}
|
|
@ -177,6 +177,7 @@
|
|||
<string name="receive_paymentid_hint">(optional)</string>
|
||||
<string name="receive_amount_label">Amount</string>
|
||||
<string name="receive_amount_hint">(optional)</string>
|
||||
<string name="receive_cannot_open">Could not open wallet!</string>
|
||||
|
||||
<string name="details_alert_message">Sensitive data will now be shown.\nLook over your shoulder!</string>
|
||||
<string name="details_alert_yes">I\'m safe</string>
|
||||
|
|
Loading…
Reference in New Issue