mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-06 02:27:11 +02:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3f09e73df7 | ||
![]() |
11b7e23ad2 | ||
![]() |
ae48027689 | ||
![]() |
a42f750fc4 | ||
![]() |
3406f585f2 | ||
![]() |
7546637c89 | ||
![]() |
4da2106f04 | ||
![]() |
93c11fb90e | ||
![]() |
9fa710f75b | ||
![]() |
c53dd300bc | ||
![]() |
97f40648be | ||
![]() |
1ece6bfbeb | ||
![]() |
4b3b99ff2a | ||
![]() |
ca833d7017 | ||
![]() |
f1b6f859de | ||
![]() |
61d19c7066 | ||
![]() |
ffda0e965b | ||
![]() |
cc7cdb383c | ||
![]() |
ac1ea05ef6 | ||
![]() |
1ddd4f30b9 | ||
![]() |
1dc081834f | ||
![]() |
ce084927e1 | ||
![]() |
3610781f43 | ||
![]() |
ef3ddbac71 | ||
![]() |
0512af1496 | ||
![]() |
bd2c49669a | ||
![]() |
ac7831d0f9 | ||
![]() |
0f0b9a38c7 | ||
![]() |
807db19603 |
@@ -1,4 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.4.1)
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
|
project(monerujo)
|
||||||
message(STATUS ABI_INFO = ${ANDROID_ABI})
|
message(STATUS ABI_INFO = ${ANDROID_ABI})
|
||||||
|
|
||||||
add_library( monerujo
|
add_library( monerujo
|
||||||
@@ -121,7 +122,7 @@ set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
|||||||
|
|
||||||
add_library(unbound STATIC IMPORTED)
|
add_library(unbound STATIC IMPORTED)
|
||||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libunbound.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libunbound.a)
|
||||||
|
|
||||||
add_library(epee STATIC IMPORTED)
|
add_library(epee STATIC IMPORTED)
|
||||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 33
|
||||||
buildToolsVersion '30.0.3'
|
buildToolsVersion '33.0.2'
|
||||||
ndkVersion '17.2.4988734'
|
ndkVersion '17.2.4988734'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 1403
|
versionCode 3130
|
||||||
versionName "2.4.3 'Baldaŭ'"
|
versionName "3.1.3 'Fluorine Fermi'"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
@@ -72,7 +72,7 @@ android {
|
|||||||
abi {
|
abi {
|
||||||
enable true
|
enable true
|
||||||
reset()
|
reset()
|
||||||
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
include 'armeabi-v7a', 'arm64-v8a', 'x86_64'
|
||||||
universalApk true
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,16 +121,18 @@ static def getId(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'androidx.core:core:1.7.0'
|
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
|
||||||
|
implementation 'androidx.core:core:1.10.0'
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
implementation 'androidx.recyclerview:recyclerview:1.3.0'
|
||||||
implementation 'androidx.cardview:cardview:1.0.0'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
implementation 'androidx.preference:preference:1.2.0'
|
implementation 'androidx.preference:preference:1.2.0'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.6.0'
|
implementation 'com.google.android.material:material:1.8.0'
|
||||||
|
|
||||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||||
implementation "com.squareup.okhttp3:okhttp:4.9.3"
|
implementation "com.squareup.okhttp3:okhttp:4.9.3"
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
<uses-permission android:name="android.permission.NFC" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
package com.btchip.comm;
|
package com.btchip.comm;
|
||||||
|
|
||||||
import com.btchip.BTChipException;
|
|
||||||
|
|
||||||
public interface BTChipTransport {
|
public interface BTChipTransport {
|
||||||
byte[] exchange(byte[] command);
|
byte[] exchange(byte[] command);
|
||||||
|
|
||||||
|
@@ -28,7 +28,6 @@ import android.hardware.usb.UsbInterface;
|
|||||||
import android.hardware.usb.UsbManager;
|
import android.hardware.usb.UsbManager;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
|
|
||||||
import com.btchip.BTChipException;
|
|
||||||
import com.btchip.comm.BTChipTransport;
|
import com.btchip.comm.BTChipTransport;
|
||||||
import com.btchip.comm.LedgerHelper;
|
import com.btchip.comm.LedgerHelper;
|
||||||
import com.btchip.utils.Dump;
|
import com.btchip.utils.Dump;
|
||||||
|
@@ -16,36 +16,18 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.nfc.FormatException;
|
|
||||||
import android.nfc.NdefMessage;
|
|
||||||
import android.nfc.NdefRecord;
|
|
||||||
import android.nfc.NfcAdapter;
|
|
||||||
import android.nfc.Tag;
|
|
||||||
import android.nfc.tech.Ndef;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.dialog.ProgressDialog;
|
import com.m2049r.xmrwallet.dialog.ProgressDialog;
|
||||||
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
|
||||||
import com.m2049r.xmrwallet.ledger.Ledger;
|
import com.m2049r.xmrwallet.ledger.Ledger;
|
||||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class BaseActivity extends SecureActivity
|
public class BaseActivity extends SecureActivity
|
||||||
@@ -141,91 +123,6 @@ public class BaseActivity extends SecureActivity
|
|||||||
Timber.d("WakeLock released");
|
Timber.d("WakeLock released");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
initNfc();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostResume() {
|
|
||||||
super.onPostResume();
|
|
||||||
if (nfcAdapter != null) {
|
|
||||||
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, null, null);
|
|
||||||
// intercept all techs so we can tell the user their tag is no good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
Timber.d("onPause()");
|
|
||||||
if (nfcAdapter != null)
|
|
||||||
nfcAdapter.disableForegroundDispatch(this);
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onNewIntent(Intent intent) {
|
|
||||||
super.onNewIntent(intent);
|
|
||||||
processNfcIntent(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NFC stuff
|
|
||||||
private NfcAdapter nfcAdapter;
|
|
||||||
private PendingIntent nfcPendingIntent;
|
|
||||||
|
|
||||||
public void initNfc() {
|
|
||||||
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
|
||||||
if (nfcAdapter == null) // no NFC support
|
|
||||||
return;
|
|
||||||
nfcPendingIntent = PendingIntent.getActivity(this, 0,
|
|
||||||
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
|
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processNfcIntent(Intent intent) {
|
|
||||||
String action = intent.getAction();
|
|
||||||
Timber.d("ACTION=%s", action);
|
|
||||||
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
|
|
||||||
|| NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|
|
||||||
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
|
|
||||||
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
|
||||||
Ndef ndef = Ndef.get(tag);
|
|
||||||
if (ndef == null) {
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_unsupported), Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
|
||||||
if (f instanceof ReceiveFragment) {
|
|
||||||
// We want to write a Tag from the ReceiveFragment
|
|
||||||
BarcodeData bc = ((ReceiveFragment) f).getBarcodeData();
|
|
||||||
if (bc != null) {
|
|
||||||
new AsyncWriteTag(ndef, bc.getUri()).execute();
|
|
||||||
} // else wallet is not loaded yet or receive is otherwise not ready - ignore
|
|
||||||
} else if (f instanceof SendFragment) {
|
|
||||||
// We want to read a Tag for the SendFragment
|
|
||||||
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
|
|
||||||
if (ndefMessage == null) {
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NdefRecord firstRecord = ndefMessage.getRecords()[0];
|
|
||||||
Uri uri = firstRecord.toUri(); // we insist on the first record
|
|
||||||
if (uri == null) {
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
|
||||||
} else {
|
|
||||||
BarcodeData bc = BarcodeData.fromString(uri.toString());
|
|
||||||
if (bc == null)
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
|
||||||
else
|
|
||||||
onUriScanned(bc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this gets called only if we get data
|
// this gets called only if we get data
|
||||||
@CallSuper
|
@CallSuper
|
||||||
void onUriScanned(BarcodeData barcodeData) {
|
void onUriScanned(BarcodeData barcodeData) {
|
||||||
@@ -239,75 +136,4 @@ public class BaseActivity extends SecureActivity
|
|||||||
barcodeData = null;
|
barcodeData = null;
|
||||||
return popped;
|
return popped;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AsyncWriteTag extends AsyncTask<Void, Void, Boolean> {
|
|
||||||
|
|
||||||
Ndef ndef;
|
|
||||||
Uri uri;
|
|
||||||
String errorMessage = null;
|
|
||||||
|
|
||||||
AsyncWriteTag(Ndef ndef, Uri uri) {
|
|
||||||
this.ndef = ndef;
|
|
||||||
this.uri = uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
super.onPreExecute();
|
|
||||||
showProgressDialog(R.string.progress_nfc_write);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(Void... params) {
|
|
||||||
if (params.length != 0) return false;
|
|
||||||
try {
|
|
||||||
writeNdef(ndef, uri);
|
|
||||||
return true;
|
|
||||||
} catch (IOException | FormatException ex) {
|
|
||||||
Timber.e(ex);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
errorMessage = ex.getMessage();
|
|
||||||
Timber.d(errorMessage);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
ndef.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Timber.e(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
if (isDestroyed()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dismissProgressDialog();
|
|
||||||
if (!result) {
|
|
||||||
if (errorMessage != null)
|
|
||||||
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
|
|
||||||
else
|
|
||||||
Toast.makeText(getApplicationContext(), getString(R.string.nfc_write_failed), Toast.LENGTH_LONG).show();
|
|
||||||
} else {
|
|
||||||
Toast.makeText(getApplicationContext(), getString(R.string.nfc_write_successful), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeNdef(Ndef ndef, Uri uri) throws IOException, FormatException {
|
|
||||||
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
|
||||||
if (nfcAdapter == null) return; // no NFC support here
|
|
||||||
|
|
||||||
NdefRecord recordNFC = NdefRecord.createUri(uri);
|
|
||||||
NdefMessage message = new NdefMessage(recordNFC);
|
|
||||||
ndef.connect();
|
|
||||||
int tagSize = ndef.getMaxSize();
|
|
||||||
int msgSize = message.getByteArrayLength();
|
|
||||||
Timber.d("tagSize=%d, msgSIze=%d, uriSize=%d", tagSize, msgSize, uri.toString().length());
|
|
||||||
if (tagSize < msgSize)
|
|
||||||
throw new IllegalArgumentException(getString(R.string.nfc_tag_size, tagSize, msgSize));
|
|
||||||
ndef.writeNdefMessage(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@@ -37,6 +35,7 @@ import android.view.inputmethod.EditorInfo;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
@@ -49,7 +49,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|||||||
import com.m2049r.xmrwallet.data.DefaultNodes;
|
import com.m2049r.xmrwallet.data.DefaultNodes;
|
||||||
import com.m2049r.xmrwallet.data.Node;
|
import com.m2049r.xmrwallet.data.Node;
|
||||||
import com.m2049r.xmrwallet.data.NodeInfo;
|
import com.m2049r.xmrwallet.data.NodeInfo;
|
||||||
import com.m2049r.xmrwallet.dialog.CreditsFragment;
|
|
||||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||||
import com.m2049r.xmrwallet.ledger.Ledger;
|
import com.m2049r.xmrwallet.ledger.Ledger;
|
||||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||||
@@ -916,9 +915,9 @@ public class LoginActivity extends BaseActivity
|
|||||||
@Override
|
@Override
|
||||||
public boolean createWallet(File aFile, String password) {
|
public boolean createWallet(File aFile, String password) {
|
||||||
NodeInfo currentNode = getNode();
|
NodeInfo currentNode = getNode();
|
||||||
// get it from the connected node if we have one, and go back ca. 4 days
|
// get it from the connected node if we have one
|
||||||
final long restoreHeight =
|
final long restoreHeight =
|
||||||
(currentNode != null) ? currentNode.getHeight() - 2000 : -1;
|
(currentNode != null) ? currentNode.getHeight() : -1;
|
||||||
Wallet newWallet = WalletManager.getInstance()
|
Wallet newWallet = WalletManager.getInstance()
|
||||||
.createWallet(aFile, password, MNEMONIC_LANGUAGE, restoreHeight);
|
.createWallet(aFile, password, MNEMONIC_LANGUAGE, restoreHeight);
|
||||||
return checkAndCloseWallet(newWallet);
|
return checkAndCloseWallet(newWallet);
|
||||||
|
@@ -29,7 +29,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
|
@@ -20,7 +20,6 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
|
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
|
||||||
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
|
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
|
||||||
|
@@ -22,7 +22,6 @@ import android.graphics.Bitmap;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.nfc.NfcManager;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
@@ -191,11 +190,6 @@ public class ReceiveFragment extends Fragment {
|
|||||||
throw new IllegalStateException("no wallet info");
|
throw new IllegalStateException("no wallet info");
|
||||||
}
|
}
|
||||||
|
|
||||||
View tvNfc = view.findViewById(R.id.tvNfc);
|
|
||||||
NfcManager manager = (NfcManager) getContext().getSystemService(Context.NFC_SERVICE);
|
|
||||||
if ((manager != null) && (manager.getDefaultAdapter() != null))
|
|
||||||
tvNfc.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +397,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
|
|
||||||
private Bitmap getMoneroLogo() {
|
private Bitmap getMoneroLogo() {
|
||||||
if (logo == null) {
|
if (logo == null) {
|
||||||
logo = Helper.getBitmap(getContext(), R.drawable.ic_monero_logo_b);
|
logo = Helper.getBitmap(getContext(), R.drawable.ic_monerujo_qr);
|
||||||
}
|
}
|
||||||
return logo;
|
return logo;
|
||||||
}
|
}
|
||||||
|
@@ -19,12 +19,13 @@ package com.m2049r.xmrwallet;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
|
import static android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -29,8 +31,6 @@ import com.m2049r.xmrwallet.util.LocaleHelper;
|
|||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static android.view.WindowManager.LayoutParams;
|
|
||||||
|
|
||||||
public abstract class SecureActivity extends AppCompatActivity {
|
public abstract class SecureActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
@@ -238,4 +238,5 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
|
|||||||
activityCallback.showSubaddress(view, subaddress.getAddressIndex());
|
activityCallback.showSubaddress(view, subaddress.getAddressIndex());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ import java.util.List;
|
|||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class SubaddressInfoFragment extends Fragment
|
public class SubaddressInfoFragment extends Fragment
|
||||||
implements TransactionInfoAdapter.OnInteractionListener, OnBlockUpdateListener {
|
implements TransactionInfoAdapter.Listener, OnBlockUpdateListener {
|
||||||
private TransactionInfoAdapter adapter;
|
private TransactionInfoAdapter adapter;
|
||||||
|
|
||||||
private Subaddress subaddress;
|
private Subaddress subaddress;
|
||||||
@@ -76,7 +76,7 @@ public class SubaddressInfoFragment extends Fragment
|
|||||||
|
|
||||||
etName.getEditText().setText(subaddress.getDisplayLabel());
|
etName.getEditText().setText(subaddress.getDisplayLabel());
|
||||||
tvAddress.setText(getContext().getString(R.string.subbaddress_info_subtitle,
|
tvAddress.setText(getContext().getString(R.string.subbaddress_info_subtitle,
|
||||||
subaddress.getAddressIndex(), subaddress.getSquashedAddress()));
|
subaddress.getAddressIndex(), subaddress.getAddress()));
|
||||||
|
|
||||||
etName.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
|
etName.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
|
||||||
if (!hasFocus) {
|
if (!hasFocus) {
|
||||||
@@ -145,6 +145,8 @@ public class SubaddressInfoFragment extends Fragment
|
|||||||
void setTitle(String title, String subtitle);
|
void setTitle(String title, String subtitle);
|
||||||
|
|
||||||
void setSubtitle(String subtitle);
|
void setSubtitle(String subtitle);
|
||||||
|
|
||||||
|
long getDaemonHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -170,4 +172,9 @@ public class SubaddressInfoFragment extends Fragment
|
|||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDaemonHeight() {
|
||||||
|
return activityCallback.getDaemonHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,6 +83,9 @@ public class TxFragment extends Fragment {
|
|||||||
private TextView tvTxTransfers;
|
private TextView tvTxTransfers;
|
||||||
private TextView etTxNotes;
|
private TextView etTxNotes;
|
||||||
|
|
||||||
|
private View llWarning;
|
||||||
|
private TextView tvWarning;
|
||||||
|
|
||||||
// XMRTO stuff
|
// XMRTO stuff
|
||||||
private View cvXmrTo;
|
private View cvXmrTo;
|
||||||
private TextView tvTxXmrToKey;
|
private TextView tvTxXmrToKey;
|
||||||
@@ -116,9 +119,11 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||||
tvTxTransfers = view.findViewById(R.id.tvTxTransfers);
|
tvTxTransfers = view.findViewById(R.id.tvTxTransfers);
|
||||||
etTxNotes = view.findViewById(R.id.etTxNotes);
|
etTxNotes = view.findViewById(R.id.etTxNotes);
|
||||||
|
|
||||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|
||||||
|
llWarning = view.findViewById(R.id.llWarning);
|
||||||
|
tvWarning = view.findViewById(R.id.tvWarning);
|
||||||
|
|
||||||
tvTxXmrToKey.setOnClickListener(v -> {
|
tvTxXmrToKey.setOnClickListener(v -> {
|
||||||
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
|
||||||
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
|
||||||
@@ -299,6 +304,20 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxTransfers.setText(sb.toString());
|
tvTxTransfers.setText(sb.toString());
|
||||||
tvDestination.setText(dstSb.toString());
|
tvDestination.setText(dstSb.toString());
|
||||||
showBtcInfo();
|
showBtcInfo();
|
||||||
|
|
||||||
|
showLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLock() {
|
||||||
|
llWarning.setVisibility(View.GONE);
|
||||||
|
if (info.unlockTime == 0) return;
|
||||||
|
final long blockheight = activityCallback.getDaemonHeight();
|
||||||
|
final long blocks = info.unlockTime - blockheight;
|
||||||
|
final double unlockDays = blocks / (30. * 24);
|
||||||
|
if (unlockDays > 0) {
|
||||||
|
llWarning.setVisibility(View.VISIBLE);
|
||||||
|
tvWarning.setText(getString(R.string.tx_locked, info.unlockTime, blocks, unlockDays));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@@ -370,6 +389,7 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
void showSubaddress(View view, final int subaddressIndex);
|
void showSubaddress(View view, final int subaddressIndex);
|
||||||
|
|
||||||
|
long getDaemonHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -451,7 +451,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
String walletId = extras.getString(REQUEST_ID);
|
String walletId = extras.getString(REQUEST_ID);
|
||||||
if (walletId != null) {
|
if (walletId != null) {
|
||||||
setTitle(walletId, getString(R.string.status_wallet_connecting));
|
setTitle(walletId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateProgress();
|
updateProgress();
|
||||||
@@ -925,12 +925,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
@Override
|
@Override
|
||||||
void onUriScanned(BarcodeData barcodeData) {
|
void onUriScanned(BarcodeData barcodeData) {
|
||||||
super.onUriScanned(barcodeData);
|
super.onUriScanned(barcodeData);
|
||||||
boolean processed = false;
|
|
||||||
if (onUriScannedListener != null) {
|
if (onUriScannedListener != null) {
|
||||||
processed = onUriScannedListener.onUriScanned(barcodeData);
|
onUriScannedListener.onUriScanned(barcodeData);
|
||||||
}
|
|
||||||
if (!processed || (onUriScannedListener == null)) {
|
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_what), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,13 +1024,14 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
final Wallet wallet = getWallet();
|
final Wallet wallet = getWallet();
|
||||||
if (wallet != null) {
|
if (wallet != null) {
|
||||||
final int n = wallet.getNumAccounts();
|
final int n = wallet.getNumAccounts();
|
||||||
|
final int currentAccount = getWallet().getAccountIndex();
|
||||||
final boolean showBalances = (n > 1) && !isStreetMode();
|
final boolean showBalances = (n > 1) && !isStreetMode();
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
final String label = (showBalances ?
|
final String label = (showBalances ?
|
||||||
getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2))
|
getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2))
|
||||||
: wallet.getAccountLabel(i));
|
: wallet.getAccountLabel(i));
|
||||||
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
||||||
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp);
|
item.setIcon(i == currentAccount ? R.drawable.ic_outline_folder_open_24 : R.drawable.ic_outline_folder_24);
|
||||||
if (i == wallet.getAccountIndex())
|
if (i == wallet.getAccountIndex())
|
||||||
item.setChecked(true);
|
item.setChecked(true);
|
||||||
}
|
}
|
||||||
|
@@ -62,7 +62,7 @@ import java.util.List;
|
|||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class WalletFragment extends Fragment
|
public class WalletFragment extends Fragment
|
||||||
implements TransactionInfoAdapter.OnInteractionListener {
|
implements TransactionInfoAdapter.Listener {
|
||||||
private TransactionInfoAdapter adapter;
|
private TransactionInfoAdapter adapter;
|
||||||
private final NumberFormat formatter = NumberFormat.getInstance();
|
private final NumberFormat formatter = NumberFormat.getInstance();
|
||||||
|
|
||||||
@@ -118,9 +118,9 @@ public class WalletFragment extends Fragment
|
|||||||
tvProgress = view.findViewById(R.id.tvProgress);
|
tvProgress = view.findViewById(R.id.tvProgress);
|
||||||
pbProgress = view.findViewById(R.id.pbProgress);
|
pbProgress = view.findViewById(R.id.pbProgress);
|
||||||
tvBalance = view.findViewById(R.id.tvBalance);
|
tvBalance = view.findViewById(R.id.tvBalance);
|
||||||
showBalance(Helper.getDisplayAmount(0));
|
showBalance();
|
||||||
tvUnconfirmedAmount = view.findViewById(R.id.tvUnconfirmedAmount);
|
tvUnconfirmedAmount = view.findViewById(R.id.tvUnconfirmedAmount);
|
||||||
showUnconfirmed(0);
|
showUnconfirmed();
|
||||||
ivSynced = view.findViewById(R.id.ivSynced);
|
ivSynced = view.findViewById(R.id.ivSynced);
|
||||||
|
|
||||||
sCurrency = view.findViewById(R.id.sCurrency);
|
sCurrency = view.findViewById(R.id.sCurrency);
|
||||||
@@ -205,7 +205,18 @@ public class WalletFragment extends Fragment
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showBalance(String balance) {
|
String amountToString(double amount) {
|
||||||
|
if (!Helper.BASE_CRYPTO.equals(balanceCurrency)) { // not XMR
|
||||||
|
double amountB = amount * balanceRate;
|
||||||
|
return Helper.getFormattedAmount(amountB, false);
|
||||||
|
} else { // XMR
|
||||||
|
return Helper.getFormattedAmount(amount, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showBalance() {
|
||||||
|
double amountA = Helper.getDecimalAmount(unlockedBalance).doubleValue();
|
||||||
|
String balance = amountToString(amountA);
|
||||||
tvBalance.setText(balance);
|
tvBalance.setText(balance);
|
||||||
final boolean streetMode = activityCallback.isStreetMode();
|
final boolean streetMode = activityCallback.isStreetMode();
|
||||||
if (!streetMode) {
|
if (!streetMode) {
|
||||||
@@ -218,13 +229,14 @@ public class WalletFragment extends Fragment
|
|||||||
setStreetModeBackground(streetMode);
|
setStreetModeBackground(streetMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showUnconfirmed(double unconfirmedAmount) {
|
void showUnconfirmed() {
|
||||||
|
double unconfirmedAmount = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
||||||
if (activityCallback.isStreetMode() || unconfirmedAmount == 0) {
|
if (activityCallback.isStreetMode() || unconfirmedAmount == 0) {
|
||||||
tvUnconfirmedAmount.setText(null);
|
tvUnconfirmedAmount.setText(null);
|
||||||
tvUnconfirmedAmount.setVisibility(View.GONE);
|
tvUnconfirmedAmount.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
String unconfirmed = Helper.getFormattedAmount(unconfirmedAmount, true);
|
String unconfirmed = amountToString(unconfirmedAmount);
|
||||||
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed));
|
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed, balanceCurrency));
|
||||||
tvUnconfirmedAmount.setVisibility(View.VISIBLE);
|
tvUnconfirmedAmount.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,15 +244,8 @@ public class WalletFragment extends Fragment
|
|||||||
void updateBalance() {
|
void updateBalance() {
|
||||||
if (isExchanging) return; // wait for exchange to finish - it will fire this itself then.
|
if (isExchanging) return; // wait for exchange to finish - it will fire this itself then.
|
||||||
// at this point selection is XMR in case of error
|
// at this point selection is XMR in case of error
|
||||||
String displayB;
|
showBalance();
|
||||||
double amountA = Helper.getDecimalAmount(unlockedBalance).doubleValue();
|
showUnconfirmed();
|
||||||
if (!Helper.BASE_CRYPTO.equals(balanceCurrency)) { // not XMR
|
|
||||||
double amountB = amountA * balanceRate;
|
|
||||||
displayB = Helper.getFormattedAmount(amountB, false);
|
|
||||||
} else { // XMR
|
|
||||||
displayB = Helper.getFormattedAmount(amountA, true);
|
|
||||||
}
|
|
||||||
showBalance(displayB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String balanceCurrency = Helper.BASE_CRYPTO;
|
String balanceCurrency = Helper.BASE_CRYPTO;
|
||||||
@@ -249,11 +254,11 @@ public class WalletFragment extends Fragment
|
|||||||
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
||||||
|
|
||||||
void refreshBalance() {
|
void refreshBalance() {
|
||||||
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
|
||||||
showUnconfirmed(unconfirmedXmr);
|
|
||||||
if (sCurrency.getSelectedItemPosition() == 0) { // XMR
|
if (sCurrency.getSelectedItemPosition() == 0) { // XMR
|
||||||
double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue();
|
balanceCurrency = Helper.BASE_CRYPTO;
|
||||||
showBalance(Helper.getFormattedAmount(amountXmr, true));
|
balanceRate = 1.0;
|
||||||
|
showBalance();
|
||||||
|
showUnconfirmed();
|
||||||
} else { // not XMR
|
} else { // not XMR
|
||||||
String currency = (String) sCurrency.getSelectedItem();
|
String currency = (String) sCurrency.getSelectedItem();
|
||||||
Timber.d(currency);
|
Timber.d(currency);
|
||||||
@@ -298,8 +303,7 @@ public class WalletFragment extends Fragment
|
|||||||
|
|
||||||
public void exchangeFailed() {
|
public void exchangeFailed() {
|
||||||
sCurrency.setSelection(0, true); // default to XMR
|
sCurrency.setSelection(0, true); // default to XMR
|
||||||
double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue();
|
showBalance();
|
||||||
showBalance(Helper.getFormattedAmount(amountXmr, true));
|
|
||||||
hideExchanging();
|
hideExchanging();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,12 +447,13 @@ public class WalletFragment extends Fragment
|
|||||||
String sync;
|
String sync;
|
||||||
if (!activityCallback.hasBoundService())
|
if (!activityCallback.hasBoundService())
|
||||||
throw new IllegalStateException("WalletService not bound.");
|
throw new IllegalStateException("WalletService not bound.");
|
||||||
|
ivSynced.setVisibility(View.GONE);
|
||||||
Wallet.ConnectionStatus daemonConnected = activityCallback.getConnectionStatus();
|
Wallet.ConnectionStatus daemonConnected = activityCallback.getConnectionStatus();
|
||||||
if (daemonConnected == Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
if (daemonConnected == Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
||||||
if (!wallet.isSynchronized()) {
|
if (!wallet.isSynchronized()) {
|
||||||
long daemonHeight = activityCallback.getDaemonHeight();
|
final long daemonHeight = getDaemonHeight();
|
||||||
long walletHeight = wallet.getBlockChainHeight();
|
final long walletHeight = wallet.getBlockChainHeight();
|
||||||
long n = daemonHeight - walletHeight;
|
final long n = daemonHeight - walletHeight;
|
||||||
sync = getString(R.string.status_syncing) + " " + formatter.format(n) + " " + getString(R.string.status_remaining);
|
sync = getString(R.string.status_syncing) + " " + formatter.format(n) + " " + getString(R.string.status_remaining);
|
||||||
if (firstBlock == 0) {
|
if (firstBlock == 0) {
|
||||||
firstBlock = walletHeight;
|
firstBlock = walletHeight;
|
||||||
@@ -456,7 +461,6 @@ public class WalletFragment extends Fragment
|
|||||||
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
|
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
|
||||||
if (x == 0) x = 101; // indeterminate
|
if (x == 0) x = 101; // indeterminate
|
||||||
setProgress(x);
|
setProgress(x);
|
||||||
ivSynced.setVisibility(View.GONE);
|
|
||||||
} else {
|
} else {
|
||||||
sync = getString(R.string.status_synced) + " " + formatter.format(wallet.getBlockChainHeight());
|
sync = getString(R.string.status_synced) + " " + formatter.format(wallet.getBlockChainHeight());
|
||||||
ivSynced.setVisibility(View.VISIBLE);
|
ivSynced.setVisibility(View.VISIBLE);
|
||||||
@@ -556,4 +560,9 @@ public class WalletFragment extends Fragment
|
|||||||
} else
|
} else
|
||||||
ivStreetGunther.setImageDrawable(null);
|
ivStreetGunther.setImageDrawable(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDaemonHeight() {
|
||||||
|
return activityCallback.getDaemonHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,6 @@ import android.text.Html;
|
|||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import com.m2049r.levin.scanner.LevinPeer;
|
import com.m2049r.levin.scanner.LevinPeer;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.util.NetCipherHelper;
|
import com.m2049r.xmrwallet.util.NetCipherHelper;
|
||||||
|
@@ -19,15 +19,16 @@ package com.m2049r.xmrwallet.dialog;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.m2049r.xmrwallet.BuildConfig;
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
@@ -17,12 +17,10 @@
|
|||||||
package com.m2049r.xmrwallet.fragment.send;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.nfc.NfcManager;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -268,11 +266,6 @@ public class SendAddressWizardFragment extends SendWizardFragment {
|
|||||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etDummy.requestFocus();
|
etDummy.requestFocus();
|
||||||
|
|
||||||
View tvNfc = view.findViewById(R.id.tvNfc);
|
|
||||||
NfcManager manager = (NfcManager) getContext().getSystemService(Context.NFC_SERVICE);
|
|
||||||
if ((manager != null) && (manager.getDefaultAdapter() != null))
|
|
||||||
tvNfc.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,9 +17,6 @@
|
|||||||
package com.m2049r.xmrwallet.fragment.send;
|
package com.m2049r.xmrwallet.fragment.send;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -28,7 +25,6 @@ import android.widget.TextView;
|
|||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.data.UserNotes;
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
|
@@ -17,10 +17,11 @@
|
|||||||
package com.m2049r.xmrwallet.layout;
|
package com.m2049r.xmrwallet.layout;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
import com.m2049r.xmrwallet.fragment.send.SendFragment;
|
||||||
|
|
||||||
public class SpendViewPager extends ViewPager {
|
public class SpendViewPager extends ViewPager {
|
||||||
|
@@ -26,7 +26,6 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
@@ -61,12 +60,19 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
void onInteraction(View view, TransactionInfo item);
|
void onInteraction(View view, TransactionInfo item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface DaemonHeightProvider {
|
||||||
|
long getDaemonHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Listener extends OnInteractionListener, DaemonHeightProvider {
|
||||||
|
}
|
||||||
|
|
||||||
private final List<TransactionInfo> infoItems;
|
private final List<TransactionInfo> infoItems;
|
||||||
private final OnInteractionListener listener;
|
private final Listener listener;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
public TransactionInfoAdapter(Context context, OnInteractionListener listener) {
|
public TransactionInfoAdapter(Context context, Listener listener) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
inboundColour = ThemeHelper.getThemedColor(context, R.attr.positiveColor);
|
inboundColour = ThemeHelper.getThemedColor(context, R.attr.positiveColor);
|
||||||
outboundColour = ThemeHelper.getThemedColor(context, R.attr.negativeColor);
|
outboundColour = ThemeHelper.getThemedColor(context, R.attr.negativeColor);
|
||||||
@@ -158,6 +164,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
final TextView tvDateTime;
|
final TextView tvDateTime;
|
||||||
final CircularProgressIndicator pbConfirmations;
|
final CircularProgressIndicator pbConfirmations;
|
||||||
final TextView tvConfirmations;
|
final TextView tvConfirmations;
|
||||||
|
final ImageView ivLock;
|
||||||
TransactionInfo infoItem;
|
TransactionInfo infoItem;
|
||||||
|
|
||||||
ViewHolder(View itemView) {
|
ViewHolder(View itemView) {
|
||||||
@@ -170,6 +177,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
pbConfirmations = itemView.findViewById(R.id.pbConfirmations);
|
pbConfirmations = itemView.findViewById(R.id.pbConfirmations);
|
||||||
pbConfirmations.setMax(TransactionInfo.CONFIRMATION);
|
pbConfirmations.setMax(TransactionInfo.CONFIRMATION);
|
||||||
tvConfirmations = itemView.findViewById(R.id.tvConfirmations);
|
tvConfirmations = itemView.findViewById(R.id.tvConfirmations);
|
||||||
|
ivLock = itemView.findViewById(R.id.ivLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDateTime(long time) {
|
private String getDateTime(long time) {
|
||||||
@@ -180,6 +188,21 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
tvAmount.setTextColor(clr);
|
tvAmount.setTextColor(clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showLock() {
|
||||||
|
Timber.d("UNLOCK %d:%d", infoItem.unlockTime, infoItem.blockheight);
|
||||||
|
if (infoItem.unlockTime == 0) {
|
||||||
|
ivLock.setVisibility(View.GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getDaemonHeight() < infoItem.unlockTime) {
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
|
ivLock.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
ivLock.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void bind(int position) {
|
void bind(int position) {
|
||||||
infoItem = infoItems.get(position);
|
infoItem = infoItems.get(position);
|
||||||
itemView.setTransitionName(context.getString(R.string.tx_item_transition_name, infoItem.hash));
|
itemView.setTransitionName(context.getString(R.string.tx_item_transition_name, infoItem.hash));
|
||||||
@@ -238,6 +261,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
pbConfirmations.setVisibility(View.GONE);
|
pbConfirmations.setVisibility(View.GONE);
|
||||||
tvConfirmations.setVisibility(View.GONE);
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
showLock();
|
||||||
|
|
||||||
String tag = null;
|
String tag = null;
|
||||||
String info = "";
|
String info = "";
|
||||||
@@ -275,4 +299,8 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long getDaemonHeight() {
|
||||||
|
return listener.getDaemonHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ public class Ledger {
|
|||||||
public static final int SW_OK = 0x9000;
|
public static final int SW_OK = 0x9000;
|
||||||
public static final int SW_INS_NOT_SUPPORTED = 0x6D00;
|
public static final int SW_INS_NOT_SUPPORTED = 0x6D00;
|
||||||
public static final int OK[] = {SW_OK};
|
public static final int OK[] = {SW_OK};
|
||||||
public static final int MINIMUM_LEDGER_VERSION = (1 << 16) + (6 << 8) + (0); // 1.6.0
|
public static final int MINIMUM_LEDGER_VERSION = (1 << 16) + (8 << 8) + (0); // 1.6.0
|
||||||
|
|
||||||
public static UsbDevice findDevice(UsbManager usbManager) {
|
public static UsbDevice findDevice(UsbManager usbManager) {
|
||||||
if (!ENABLED) return null;
|
if (!ENABLED) return null;
|
||||||
|
@@ -62,6 +62,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
|||||||
public int accountIndex;
|
public int accountIndex;
|
||||||
public int addressIndex;
|
public int addressIndex;
|
||||||
public long confirmations;
|
public long confirmations;
|
||||||
|
public long unlockTime;
|
||||||
public String subaddressLabel;
|
public String subaddressLabel;
|
||||||
public List<Transfer> transfers;
|
public List<Transfer> transfers;
|
||||||
|
|
||||||
@@ -82,6 +83,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
|||||||
int accountIndex,
|
int accountIndex,
|
||||||
int addressIndex,
|
int addressIndex,
|
||||||
long confirmations,
|
long confirmations,
|
||||||
|
long unlockTime,
|
||||||
String subaddressLabel,
|
String subaddressLabel,
|
||||||
List<Transfer> transfers) {
|
List<Transfer> transfers) {
|
||||||
this.direction = Direction.values()[direction];
|
this.direction = Direction.values()[direction];
|
||||||
@@ -96,6 +98,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
|||||||
this.accountIndex = accountIndex;
|
this.accountIndex = accountIndex;
|
||||||
this.addressIndex = addressIndex;
|
this.addressIndex = addressIndex;
|
||||||
this.confirmations = confirmations;
|
this.confirmations = confirmations;
|
||||||
|
this.unlockTime = unlockTime;
|
||||||
this.subaddressLabel = subaddressLabel;
|
this.subaddressLabel = subaddressLabel;
|
||||||
this.transfers = transfers;
|
this.transfers = transfers;
|
||||||
}
|
}
|
||||||
@@ -129,6 +132,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
|||||||
out.writeInt(accountIndex);
|
out.writeInt(accountIndex);
|
||||||
out.writeInt(addressIndex);
|
out.writeInt(addressIndex);
|
||||||
out.writeLong(confirmations);
|
out.writeLong(confirmations);
|
||||||
|
out.writeLong(unlockTime);
|
||||||
out.writeString(subaddressLabel);
|
out.writeString(subaddressLabel);
|
||||||
out.writeList(transfers);
|
out.writeList(transfers);
|
||||||
out.writeString(txKey);
|
out.writeString(txKey);
|
||||||
@@ -159,6 +163,7 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
|||||||
accountIndex = in.readInt();
|
accountIndex = in.readInt();
|
||||||
addressIndex = in.readInt();
|
addressIndex = in.readInt();
|
||||||
confirmations = in.readLong();
|
confirmations = in.readLong();
|
||||||
|
unlockTime = in.readLong();
|
||||||
subaddressLabel = in.readString();
|
subaddressLabel = in.readString();
|
||||||
transfers = in.readArrayList(Transfer.class.getClassLoader());
|
transfers = in.readArrayList(Transfer.class.getClassLoader());
|
||||||
txKey = in.readString();
|
txKey = in.readString();
|
||||||
|
@@ -24,7 +24,7 @@ import com.m2049r.xmrwallet.util.RestoreHeight;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -96,8 +96,11 @@ public class WalletManager {
|
|||||||
if (wallet.getStatus().isOk()) {
|
if (wallet.getStatus().isOk()) {
|
||||||
// (Re-)Estimate restore height based on what we know
|
// (Re-)Estimate restore height based on what we know
|
||||||
final long oldHeight = wallet.getRestoreHeight();
|
final long oldHeight = wallet.getRestoreHeight();
|
||||||
|
// Go back 4 days if we don't have a precise restore height
|
||||||
|
Calendar restoreDate = Calendar.getInstance();
|
||||||
|
restoreDate.add(Calendar.DAY_OF_MONTH, -4);
|
||||||
final long restoreHeight =
|
final long restoreHeight =
|
||||||
(height > -1) ? height : RestoreHeight.getInstance().getHeight(new Date());
|
(height > -1) ? height : RestoreHeight.getInstance().getHeight(restoreDate.getTime());
|
||||||
wallet.setRestoreHeight(restoreHeight);
|
wallet.setRestoreHeight(restoreHeight);
|
||||||
Timber.d("Changed Restore Height from %d to %d", oldHeight, wallet.getRestoreHeight());
|
Timber.d("Changed Restore Height from %d to %d", oldHeight, wallet.getRestoreHeight());
|
||||||
wallet.setPassword(password); // this rewrites the keys file (which contains the restore height)
|
wallet.setPassword(password); // this rewrites the keys file (which contains the restore height)
|
||||||
|
@@ -19,8 +19,6 @@ package com.m2049r.xmrwallet.onboarding;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
@@ -25,7 +25,6 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
|||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -23,7 +23,6 @@ import com.m2049r.xmrwallet.service.shift.NetworkCallback;
|
|||||||
import com.m2049r.xmrwallet.service.shift.ShiftApiCall;
|
import com.m2049r.xmrwallet.service.shift.ShiftApiCall;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
|
||||||
import com.m2049r.xmrwallet.util.DateHelper;
|
import com.m2049r.xmrwallet.util.DateHelper;
|
||||||
import com.m2049r.xmrwallet.util.ServiceHelper;
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
|
@@ -20,9 +20,8 @@ import androidx.annotation.NonNull;
|
|||||||
|
|
||||||
import com.m2049r.xmrwallet.service.shift.NetworkCallback;
|
import com.m2049r.xmrwallet.service.shift.NetworkCallback;
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftApiCall;
|
import com.m2049r.xmrwallet.service.shift.ShiftApiCall;
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
|
||||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||||
|
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters;
|
||||||
import com.m2049r.xmrwallet.util.ServiceHelper;
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user