cleanup + docs

This commit is contained in:
m2049r
2017-08-20 22:34:36 +02:00
parent 37414be4bf
commit 30e35a895d
18 changed files with 160 additions and 118 deletions
@@ -142,11 +142,11 @@ public class GenerateFragment extends Fragment {
public void afterTextChanged(Editable editable) {
if (etWalletMnemonic.length() > 0) {
etWalletRestoreHeight.setVisibility(View.VISIBLE);
etWalletAddress.setVisibility(View.INVISIBLE);
etWalletAddress.setVisibility(View.GONE);
} else {
etWalletAddress.setVisibility(View.VISIBLE);
if (etWalletAddress.length() == 0) {
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
etWalletRestoreHeight.setVisibility(View.GONE);
} else {
etWalletRestoreHeight.setVisibility(View.VISIBLE);
}
@@ -193,10 +193,10 @@ public class GenerateFragment extends Fragment {
etWalletMnemonic.setVisibility(View.INVISIBLE);
etWalletRestoreHeight.setVisibility(View.VISIBLE);
} else {
llRestoreKeys.setVisibility(View.INVISIBLE);
llRestoreKeys.setVisibility(View.GONE);
etWalletMnemonic.setVisibility(View.VISIBLE);
if (etWalletMnemonic.length() == 0) {
etWalletRestoreHeight.setVisibility(View.INVISIBLE);
etWalletRestoreHeight.setVisibility(View.GONE);
} else {
etWalletRestoreHeight.setVisibility(View.VISIBLE);
}
@@ -280,8 +280,8 @@ public class GenerateFragment extends Fragment {
private boolean addressOk() {
String address = etWalletAddress.getText().toString();
// TODO only accept address from the correct net
return ((address.length() == 95) && ("49A".indexOf(address.charAt(0)) >= 0));
boolean testnet = WalletManager.getInstance().isTestNet();
return ((address.length() == 95) && ((testnet ? "9A" : "4").indexOf(address.charAt(0)) >= 0));
}
private boolean viewKeyOk() {
@@ -318,19 +318,19 @@ public class GenerateFragment extends Fragment {
// figure out how we want to create this wallet
// A. from scratch
if ((seed.length() == 0) && (address.length() == 0)) {
bGenerate.setVisibility(View.INVISIBLE);
bGenerate.setVisibility(View.GONE);
activityCallback.onGenerate(name, password);
} else
// B. from seed
if (mnemonicOk()) {
bGenerate.setVisibility(View.INVISIBLE);
bGenerate.setVisibility(View.GONE);
activityCallback.onGenerate(name, password, seed, height);
} else
// C. from keys
if (addressOk() && viewKeyOk() && (spendKeyOk())) {
String viewKey = etWalletViewKey.getText().toString();
String spendKey = etWalletSpendKey.getText().toString();
bGenerate.setVisibility(View.INVISIBLE);
bGenerate.setVisibility(View.GONE);
activityCallback.onGenerate(name, password, address, viewKey, spendKey, height);
} else
// D. none of the above :)
@@ -36,6 +36,7 @@ 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";
ProgressBar pbProgress;
TextView tvWalletName;
@@ -75,12 +76,15 @@ public class GenerateReviewFragment extends Fragment {
showProgress();
Bundle b = getArguments();
String name = b.getString("name");
String password = b.getString("password");
String type = b.getString("type");
tvWalletName.setText(new File(name).getName());
show(name, password, type);
if (!type.equals(VIEW_WALLET)) {
String name = b.getString("name");
String password = b.getString("password");
tvWalletName.setText(new File(name).getName());
show(name, password, type);
} else {
show(walletCallback.getWallet(), null, type);
}
return view;
}
@@ -88,7 +92,7 @@ public class GenerateReviewFragment extends Fragment {
String name = tvWalletName.getText().toString();
String password = tvWalletPassword.getText().toString();
bAccept.setEnabled(false);
activityCallback.onAccept(name, password);
acceptCallback.onAccept(name, password);
}
private void show(final String walletPath, final String password, final String type) {
@@ -96,50 +100,55 @@ public class GenerateReviewFragment extends Fragment {
new Runnable() {
@Override
public void run() {
Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
final String name = wallet.getName();
final String seed = wallet.getSeed();
final String address = wallet.getAddress();
final String view = wallet.getSecretViewKey();
final String spend = wallet.isWatchOnly() ? "" : "not available - use seed for recovery";
wallet.close();
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (type.equals(GenerateReviewFragment.VIEW_ACCEPT)) {
tvWalletPassword.setText(password);
bAccept.setVisibility(View.VISIBLE);
bAccept.setEnabled(true);
}
tvWalletName.setText(name);
tvWalletAddress.setText(address);
tvWalletMnemonic.setText(seed);
tvWalletViewKey.setText(view);
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();
show(wallet, password, type);
}
});
wallet.close();
}
}
, "DetailsReview", MoneroHandlerThread.THREAD_STACK_SIZE).start();
}
GenerateReviewFragment.Listener activityCallback;
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);
}
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));
}
hideProgress();
}
GenerateReviewFragment.Listener acceptCallback = null;
GenerateReviewFragment.ListenerWithWallet walletCallback = null;
public interface Listener {
void onAccept(String name, String password);
}
public interface ListenerWithWallet {
Wallet getWallet();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof GenerateReviewFragment.Listener) {
this.activityCallback = (GenerateReviewFragment.Listener) context;
this.acceptCallback = (GenerateReviewFragment.Listener) context;
} else if (context instanceof GenerateReviewFragment.ListenerWithWallet) {
this.walletCallback = (GenerateReviewFragment.ListenerWithWallet) context;
} else {
throw new ClassCastException(context.toString()
+ " must implement Listener");
@@ -16,7 +16,6 @@
package com.m2049r.xmrwallet;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -29,6 +28,7 @@ import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -40,7 +40,6 @@ import android.widget.Toast;
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 java.io.File;
@@ -63,6 +62,11 @@ public class LoginActivity extends AppCompatActivity
if (savedInstanceState != null) {
return;
}
Toolbar toolbar = (Toolbar) findViewById(R.id.tbLogin);
toolbar.setTitle(R.string.login_activity_name);
setSupportActionBar(toolbar);
if (Helper.getWritePermission(this)) {
startLoginFragment();
} else {
@@ -235,7 +239,6 @@ public class LoginActivity extends AppCompatActivity
startReviewFragment(b);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()");
@@ -420,9 +423,10 @@ public class LoginActivity extends AppCompatActivity
boolean copyWallet(File dstDir, File srcDir, String name) {
boolean success = false;
try {
// TODO: the cache is corrupt if we recover (!!)
// TODO: the cache is ok if we immediately to a full refresh()
// TODO recoveryheight is ignored but not on watchonly wallet ?! - find out why
// the cache is corrupt if we recover (!!)
// 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(dstDir, srcDir, name);
copyFile(dstDir, srcDir, name + ".keys");
copyFile(dstDir, srcDir, name + ".address.txt");
@@ -28,17 +28,21 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.m2049r.xmrwallet.model.PendingTransaction;
import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.TxData;
public class WalletActivity extends AppCompatActivity implements WalletFragment.Listener,
WalletService.Observer, SendFragment.Listener, TxFragment.Listener {
WalletService.Observer, SendFragment.Listener, TxFragment.Listener, GenerateReviewFragment.ListenerWithWallet {
private static final String TAG = "WalletActivity";
static final int MIN_DAEMON_VERSION = 65544;
@@ -46,6 +50,8 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
public static final String REQUEST_ID = "id";
public static final String REQUEST_PW = "pw";
Toolbar tbWallet;
private boolean synced = false;
@Override
@@ -109,21 +115,29 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.wallet_activity);
if (savedInstanceState != null) {
return;
}
tbWallet = (Toolbar) findViewById(R.id.tbWallet);
tbWallet.setTitle(R.string.app_name);
setSupportActionBar(tbWallet);
tbWallet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onWalletDetails();
}
});
Fragment walletFragment = new WalletFragment();
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, walletFragment).commit();
Log.d(TAG, "fragment added");
if (savedInstanceState != null) {
return;
}
startWalletService();
Log.d(TAG, "onCreate() done.");
}
public Wallet getWallet() {
if (mBoundService == null) throw new IllegalStateException("WalletService not bound.");
return mBoundService.getWallet();
@@ -256,7 +270,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
@Override
public void setTitle(String title) {
super.setTitle(title);
tbWallet.setTitle(title);
}
@Override
@@ -522,4 +536,13 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
transaction.addToBackStack(stackName);
transaction.commit();
}
}
private void onWalletDetails() {
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof WalletFragment) {
Bundle extras = new Bundle();
extras.putString("type", GenerateReviewFragment.VIEW_WALLET);
replaceFragment(new GenerateReviewFragment(), null, extras);
}
}
}
@@ -116,7 +116,7 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
updateStatus(wallet);
}
public void onSynced() { // TODO watchonly
public void onSynced() {
if (!activityCallback.isWatchOnly()) {
bSend.setVisibility(View.VISIBLE);
bSend.setEnabled(true);
@@ -81,6 +81,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
public void setInfos(List<TransactionInfo> data) {
// TODO do stuff with data so we can really recycle elements (i.e. add only new tx)
// as the TransactionInfo items are always recreated, we cannot recycle
this.infoItems.clear();
if (data != null) {
Log.d(TAG, "setInfos " + data.size());
@@ -135,9 +136,8 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
void bind(int position) {
this.infoItem = infoItems.get(position);
String displayAmount = Wallet.getDisplayAmount(infoItem.amount);
// TODO fix this with i8n code
// TODO fix this with i8n code but cryptonote::print_money always uses '.' for decimal point
String amountParts[] = displayAmount.split("\\.");
// TODO what if there is no decimal point?
this.tvAmount.setText(amountParts[0]);
this.tvAmountDecimal.setText(amountParts[1]);
@@ -38,7 +38,7 @@ public class WalletManager {
// no need to keep a reference to the REAL WalletManager (we get it every tvTime we need it)
private static WalletManager Instance = null;
public static WalletManager getInstance() { // TODO not threadsafe
public static synchronized WalletManager getInstance() {
if (WalletManager.Instance == null) {
WalletManager.Instance = new WalletManager();
}
@@ -120,12 +120,11 @@ public class WalletService extends Service {
updateDaemonState(wallet, wallet.isSynchronized() ? height : 0);
if (!wallet.isSynchronized()) {
// we want to see our transactions as they come in
Log.d(TAG, "newBlock() refresh history");
wallet.getHistory().refresh();
Log.d(TAG, "newBlock() history refreshed");
int txCount = wallet.getHistory().getCount();
if (txCount > lastTxCount) {
lastTxCount = txCount; // TODO maybe do this later
// update the transaction list only if we have more than before
lastTxCount = txCount;
fullRefresh = true;
}
}
@@ -173,10 +172,9 @@ public class WalletService extends Service {
// these calls really connect to the daemon - wasting time
daemonHeight = wallet.getDaemonBlockChainHeight();
if (daemonHeight > 0) {
// if we get a valid height, the obviously we are connected
// if we get a valid height, then obviously we are connected
connectionStatus = Wallet.ConnectionStatus.ConnectionStatus_Connected;
} else {
// TODO: or connectionStatus = wallet.getConnectionStatus(); ?
connectionStatus = Wallet.ConnectionStatus.ConnectionStatus_Disconnected;
}
}
@@ -485,7 +483,6 @@ public class WalletService extends Service {
listener = null;
}
stopSelf();
// TODO ensure the Looper & thread actually stop and go away?
}
private Wallet loadWallet(String walletName, String walletPassword) {