check daemon availability

show txs immediately
only save on first sync

no store on close

Increased Version
This commit is contained in:
m2049r 2017-08-08 22:06:48 +02:00
parent cb5795e64b
commit 95e47e3407
17 changed files with 175 additions and 96 deletions

View File

@ -89,6 +89,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/cmake" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/cmake" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />

View File

@ -7,8 +7,8 @@ android {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 25 targetSdkVersion 25
versionCode 2 versionCode 3
versionName "0.2.0" versionName "0.3.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {

View File

@ -386,8 +386,9 @@ Java_com_m2049r_xmrwallet_model_WalletManager_setDaemonAddressJ(JNIEnv *env, job
env->ReleaseStringUTFChars(address, _address); env->ReleaseStringUTFChars(address, _address);
} }
// returns whether the daemon can be reached, and its version number
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_m2049r_xmrwallet_model_WalletManager_getConnectedDaemonVersion(JNIEnv *env, Java_com_m2049r_xmrwallet_model_WalletManager_getDaemonVersion(JNIEnv *env,
jobject instance) { jobject instance) {
uint32_t version; uint32_t version;
bool isConnected = bool isConnected =

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -25,6 +25,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.StrictMode;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -46,11 +47,19 @@ import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
public class LoginActivity extends Activity { public class LoginActivity extends Activity {
static final String TAG = "LoginActivity"; static final String TAG = "LoginActivity";
static final int MIN_DAEMON_VERSION = 65544;
static final int DAEMON_TIMEOUT = 500; // deamon must respond in 500ms
ListView listView; ListView listView;
List<String> walletList = new ArrayList<>(); List<String> walletList = new ArrayList<>();
List<String> displayedList = new ArrayList<>(); List<String> displayedList = new ArrayList<>();
@ -124,9 +133,17 @@ public class LoginActivity extends Activity {
final int preambleLength = "[123456] ".length(); final int preambleLength = "[123456] ".length();
if (itemValue.length() <= (preambleLength)) { if (itemValue.length() <= (preambleLength)) {
Toast.makeText(LoginActivity.this, "something's wrong", Toast.LENGTH_LONG).show(); Toast.makeText(LoginActivity.this, getString(R.string.panic), Toast.LENGTH_LONG).show();
return; return;
} }
setWalletDaemon();
if (!checkWalletDaemon()) {
Toast.makeText(LoginActivity.this, getString(R.string.warn_daemon_unavailable), Toast.LENGTH_LONG).show();
return;
}
// looking good
savePrefs(false);
String wallet = itemValue.substring(preambleLength); String wallet = itemValue.substring(preambleLength);
promptPassword(wallet); promptPassword(wallet);
@ -200,6 +217,32 @@ public class LoginActivity extends Activity {
} }
} }
private boolean checkWalletDaemon() {
// if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy prevPolicy = StrictMode.getThreadPolicy();
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder(prevPolicy).permitNetwork().build();
StrictMode.setThreadPolicy(policy);
String d[] = WalletManager.getInstance().getDaemonAddress().split(":");
String host = d[0];
int port = Integer.parseInt(d[1]);
Socket socket = new Socket();
long a = new Date().getTime();
try {
socket.connect(new InetSocketAddress(host, port), DAEMON_TIMEOUT);
socket.close();
} catch (IOException ex) {
Log.d(TAG, "Cannot reach daemon " + host + ":" + port + " because " + ex.getLocalizedMessage());
return false;
} finally {
StrictMode.setThreadPolicy(prevPolicy);
}
long b = new Date().getTime();
Log.d(TAG, "Daemon is " + (b - a) + "ms away.");
int version = WalletManager.getInstance().getDaemonVersion();
Log.d(TAG, "Daemon is v" + version);
return (version >= MIN_DAEMON_VERSION);
}
private boolean checkWalletPassword(String walletName, String password) { private boolean checkWalletPassword(String walletName, String password) {
String walletPath = new File(Helper.getStorageRoot(getApplicationContext()), String walletPath = new File(Helper.getStorageRoot(getApplicationContext()),
walletName + ".keys").getAbsolutePath(); walletName + ".keys").getAbsolutePath();
@ -207,7 +250,6 @@ public class LoginActivity extends Activity {
return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true); return WalletManager.getInstance().verifyWalletPassword(walletPath, password, true);
} }
@Override @Override
protected void onPause() { protected void onPause() {
Log.d(TAG, "onPause()"); Log.d(TAG, "onPause()");
@ -215,6 +257,12 @@ public class LoginActivity extends Activity {
super.onPause(); super.onPause();
} }
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
}
boolean isMainNet() { boolean isMainNet() {
ToggleButton tbMainNet = (ToggleButton) findViewById(R.id.tbMainNet); ToggleButton tbMainNet = (ToggleButton) findViewById(R.id.tbMainNet);
return tbMainNet.isChecked(); return tbMainNet.isChecked();
@ -275,19 +323,20 @@ public class LoginActivity extends Activity {
editor.apply(); editor.apply();
} }
void startWallet(String walletName, String walletPassword) { private void setWalletDaemon() {
Log.d(TAG, "startWallet()");
savePrefs(false);
boolean testnet = !isMainNet(); boolean testnet = !isMainNet();
String daemon = getDaemon(); String daemon = getDaemon();
Intent intent = new Intent(getApplicationContext(), WalletActivity.class);
if (!daemon.contains(":")) { if (!daemon.contains(":")) {
daemon = daemon + (testnet ? ":28081" : ":18081"); daemon = daemon + (testnet ? ":28081" : ":18081");
} }
WalletManager.getInstance().setDaemon(daemon, testnet); WalletManager.getInstance().setDaemon(daemon, testnet);
}
void startWallet(String walletName, String walletPassword) {
Log.d(TAG, "startWallet()");
Intent intent = new Intent(getApplicationContext(), WalletActivity.class);
intent.putExtra(WalletActivity.REQUEST_ID, walletName); intent.putExtra(WalletActivity.REQUEST_ID, walletName);
intent.putExtra(WalletActivity.REQUEST_PW, walletPassword); intent.putExtra(WalletActivity.REQUEST_PW, walletPassword);
startActivity(intent); startActivity(intent);
@ -332,7 +381,7 @@ public class LoginActivity extends Activity {
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],@NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()"); Log.d(TAG, "onRequestPermissionsResult()");
switch (requestCode) { switch (requestCode) {
case Helper.PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: case Helper.PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE:

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -97,6 +97,7 @@ public class WalletActivity extends AppCompatActivity
Log.d(TAG, "onStop()"); Log.d(TAG, "onStop()");
releaseWakeLock(); releaseWakeLock();
disconnectWalletService(); disconnectWalletService();
this.synced = false;
super.onStop(); super.onStop();
} }
@ -145,6 +146,7 @@ public class WalletActivity extends AppCompatActivity
balanceView.setText(Wallet.getDisplayAmount(wallet.getBalance())); balanceView.setText(Wallet.getDisplayAmount(wallet.getBalance()));
unlockedView.setText(Wallet.getDisplayAmount(wallet.getUnlockedBalance())); unlockedView.setText(Wallet.getDisplayAmount(wallet.getUnlockedBalance()));
String sync = ""; String sync = "";
// TODO: getConnectionStatus() blocks as it tries to connect - this is bad in the UI thread!
if (wallet.getConnectionStatus() == Wallet.ConnectionStatus.ConnectionStatus_Connected) { if (wallet.getConnectionStatus() == Wallet.ConnectionStatus.ConnectionStatus_Connected) {
if (!wallet.isSynchronized()) { if (!wallet.isSynchronized()) {
long n = wallet.getDaemonBlockChainHeight() - wallet.getBlockChainHeight(); long n = wallet.getDaemonBlockChainHeight() - wallet.getBlockChainHeight();
@ -160,13 +162,19 @@ public class WalletActivity extends AppCompatActivity
sync = getString(R.string.status_synced) + ": " + wallet.getBlockChainHeight(); sync = getString(R.string.status_synced) + ": " + wallet.getBlockChainHeight();
if (!synced) { if (!synced) {
hideProgress(); hideProgress();
saveWallet(); // save ONLY on first sync
// the usual use case is:
// open the wallet, wait for sync, check balance, close app
// even if we wait for new transactions, they will be synced and saved next time
// the advantage here is that we are storing the state while the app is open
// and don't get into timing issues
synced = true; synced = true;
} }
} }
} }
String t = (wallet.isTestNet() ? getString(R.string.connect_testnet) : getString(R.string.connect_mainnet)); String net = (wallet.isTestNet() ? getString(R.string.connect_testnet) : getString(R.string.connect_mainnet));
syncProgressView.setText(sync); syncProgressView.setText(sync);
connectionStatusView.setText(t + " " + wallet.getConnectionStatus().toString().substring(17)); connectionStatusView.setText(net + " " + wallet.getConnectionStatus().toString().substring(17));
} }
@Override @Override
@ -241,11 +249,22 @@ public class WalletActivity extends AppCompatActivity
mBoundService.setObserver(null); mBoundService.setObserver(null);
unbindService(mConnection); unbindService(mConnection);
mIsBound = false; mIsBound = false;
Toast.makeText(getApplicationContext(), getString(R.string.status_wallet_unloading), Toast.LENGTH_LONG).show();
Log.d(TAG, "UNBOUND"); Log.d(TAG, "UNBOUND");
} }
} }
void saveWallet() {
if (mIsBound) { // no point in talking to unbound service
Intent intent = new Intent(getApplicationContext(), WalletService.class);
intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_STORE);
startService(intent);
Toast.makeText(getApplicationContext(), getString(R.string.status_wallet_unloading), Toast.LENGTH_LONG).show();
Log.d(TAG, "STORE request sent");
} else {
Log.e(TAG, "Service not bound");
}
}
// Callbacks from TransactionInfoAdapter // Callbacks from TransactionInfoAdapter
@Override @Override
public void onInteraction(final View view, final TransactionInfo infoItem) { public void onInteraction(final View view, final TransactionInfo infoItem) {
@ -279,6 +298,7 @@ public class WalletActivity extends AppCompatActivity
@Override @Override
protected void onPause() { protected void onPause() {
Log.d(TAG, "onPause()"); Log.d(TAG, "onPause()");
//saveWallet(); //TODO: do it here if we really need to ...
super.onPause(); super.onPause();
} }

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -38,10 +38,10 @@ import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> { public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
static final String TAG = "TransactionInfoAdapter"; private static final String TAG = "TransactionInfoAdapter";
static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd"); private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
static final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss"); private static final SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss");
static final int TX_RED = Color.rgb(255, 79, 65); static final int TX_RED = Color.rgb(255, 79, 65);
static final int TX_GREEN = Color.rgb(54, 176, 91); static final int TX_GREEN = Color.rgb(54, 176, 91);
@ -100,15 +100,15 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
notifyDataSetChanged(); notifyDataSetChanged();
} }
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView tvAmount; final TextView tvAmount;
public final TextView tvAmountPoint; final TextView tvAmountPoint;
public final TextView tvAmountDecimal; final TextView tvAmountDecimal;
public final TextView tvDate; final TextView tvDate;
public final TextView tvTime; final TextView tvTime;
public TransactionInfo infoItem; TransactionInfo infoItem;
public ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
this.tvAmount = (TextView) itemView.findViewById(R.id.tx_amount); this.tvAmount = (TextView) itemView.findViewById(R.id.tx_amount);
// I know this is stupid but can't be bothered to align decimals otherwise // I know this is stupid but can't be bothered to align decimals otherwise

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -23,7 +23,7 @@ public class TransactionInfo {
public long handle; public long handle;
public TransactionInfo(long handle) { TransactionInfo(long handle) {
this.handle = handle; this.handle = handle;
} }

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -35,7 +35,7 @@ public class Wallet {
private long handle = 0; private long handle = 0;
private long listenerHandle = 0; private long listenerHandle = 0;
public Wallet(long handle) { Wallet(long handle) {
this.handle = handle; this.handle = handle;
} }

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -29,7 +29,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class WalletManager { public class WalletManager {
final static String TAG = "WalletManager"; private final static String TAG = "WalletManager";
static { static {
System.loadLibrary("monerujo"); System.loadLibrary("monerujo");
@ -204,7 +204,7 @@ public class WalletManager {
private native void setDaemonAddressJ(String address); private native void setDaemonAddressJ(String address);
public native int getConnectedDaemonVersion(); public native int getDaemonVersion();
public native long getBlockchainHeight(); public native long getBlockchainHeight();

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,9 +16,7 @@
package com.m2049r.xmrwallet.service; package com.m2049r.xmrwallet.service;
import android.app.ProgressDialog;
import android.app.Service; import android.app.Service;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
@ -27,10 +25,8 @@ import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.PowerManager;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
@ -47,10 +43,11 @@ import com.m2049r.xmrwallet.util.Helper;
public class WalletService extends Service { public class WalletService extends Service {
final static String TAG = "WalletService"; final static String TAG = "WalletService";
public static final String REQUEST = "request";
public static final String REQUEST_WALLET = "wallet"; public static final String REQUEST_WALLET = "wallet";
public static final String REQUEST = "request";
public static final String REQUEST_CMD_LOAD = "load"; public static final String REQUEST_CMD_LOAD = "load";
public static final String REQUEST_CMD_LOAD_PW = "walletPassword"; public static final String REQUEST_CMD_LOAD_PW = "walletPassword";
public static final String REQUEST_CMD_STORE = "store";
public static final int START_SERVICE = 1; public static final int START_SERVICE = 1;
public static final int STOP_SERVICE = 2; public static final int STOP_SERVICE = 2;
@ -70,7 +67,7 @@ public class WalletService extends Service {
this.wallet = aWallet; this.wallet = aWallet;
} }
public void start() { void start() {
Log.d(TAG, "MyWalletListener.start()"); Log.d(TAG, "MyWalletListener.start()");
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
//acquireWakeLock(); //acquireWakeLock();
@ -78,7 +75,7 @@ public class WalletService extends Service {
wallet.startRefresh(); wallet.startRefresh();
} }
public void stop() { void stop() {
Log.d(TAG, "MyWalletListener.stop()"); Log.d(TAG, "MyWalletListener.stop()");
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
wallet.pauseRefresh(); wallet.pauseRefresh();
@ -178,7 +175,7 @@ public class WalletService extends Service {
// Handler that receives messages from the thread // Handler that receives messages from the thread
private final class ServiceHandler extends Handler { private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) { ServiceHandler(Looper looper) {
super(looper); super(looper);
} }
@ -188,11 +185,19 @@ public class WalletService extends Service {
switch (msg.arg2) { switch (msg.arg2) {
case START_SERVICE: { case START_SERVICE: {
Bundle extras = msg.getData(); Bundle extras = msg.getData();
String walletId = extras.getString(REQUEST_WALLET, null); String cmd = extras.getString(REQUEST, null);
String walletPw = extras.getString(REQUEST_CMD_LOAD_PW, null); if (cmd.equals(REQUEST_CMD_LOAD)) {
Log.d(TAG, "LOAD wallet " + walletId);// + ":" + walletPw); String walletId = extras.getString(REQUEST_WALLET, null);
if (walletId != null) { String walletPw = extras.getString(REQUEST_CMD_LOAD_PW, null);
start(walletId, walletPw); // TODO What if this fails? Log.d(TAG, "LOAD wallet " + walletId);// + ":" + walletPw);
if (walletId != null) {
start(walletId, walletPw); // TODO What if this fails?
}
} else if (cmd.equals(REQUEST_CMD_STORE)) {
Wallet myWallet = getWallet();
Log.d(TAG, "storing wallet: " + myWallet.getName());
getWallet().store();
Log.d(TAG, "wallet stored: " + myWallet.getName());
} }
} }
break; break;
@ -251,7 +256,6 @@ public class WalletService extends Service {
// this should not matter since the old activity is not getting updates // this should not matter since the old activity is not getting updates
// and the new one is not listening yet (although it will be bound) // and the new one is not listening yet (although it will be bound)
Log.d(TAG, "onStartCommand()"); Log.d(TAG, "onStartCommand()");
//acquireWakeLock(); // we want to be awake for the fun stuff
// For each start request, send a message to start a job and deliver the // For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job // start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage(); Message msg = mServiceHandler.obtainMessage();
@ -293,6 +297,11 @@ public class WalletService extends Service {
showProgress(95); showProgress(95);
} }
Log.d(TAG, "start() done"); Log.d(TAG, "start() done");
if (observer != null) {
Wallet myWallet = getWallet();
myWallet.getHistory().refresh();
observer.onRefreshed(myWallet, true);
}
} }
public void stop() { public void stop() {

View File

@ -1,12 +1,12 @@
/** /*
* Copyright (c) 2017 m2049r * Copyright (c) 2017 m2049r
* <p> *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* <p> *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -28,8 +28,8 @@ import com.m2049r.xmrwallet.R;
import java.io.File; import java.io.File;
public class Helper { public class Helper {
static final String TAG = "Helper"; private static final String TAG = "Helper";
static final String WALLET_DIR = "Monerujo"; private static final String WALLET_DIR = "Monerujo";
static public File getStorageRoot(Context context) { static public File getStorageRoot(Context context) {
if (!isExternalStorageWritable()) { if (!isExternalStorageWritable()) {
@ -79,10 +79,7 @@ public class Helper {
/* Checks if external storage is available for read and write */ /* Checks if external storage is available for read and write */
static public boolean isExternalStorageWritable() { static public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState(); String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) { return Environment.MEDIA_MOUNTED.equals(state);
return true;
}
return false;
} }
} }

View File

@ -62,7 +62,7 @@
android:textSize="10sp" android:textSize="10sp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:text="Connecting..." android:text="Loading..."
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -73,7 +73,7 @@
android:textSize="10sp" android:textSize="10sp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:text="Connecting..." android:text="Loading..."
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvConnectionStatus" /> app:layout_constraintTop_toBottomOf="@+id/tvConnectionStatus" />
@ -81,8 +81,8 @@
<LinearLayout <LinearLayout
android:id="@+id/llProgress" android:id="@+id/llProgress"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:orientation="vertical" android:orientation="vertical"
android:visibility="gone" > android:visibility="gone" >
@ -94,7 +94,7 @@
android:textSize="16sp" android:textSize="16sp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:text="Connecting..." /> android:text="Loading..." />
<ProgressBar <ProgressBar
android:id="@+id/pbProgress" android:id="@+id/pbProgress"

View File

@ -14,7 +14,9 @@
<string name="prompt_password">Password for</string> <string name="prompt_password">Password for</string>
<string name="bad_password">Bad password!</string> <string name="bad_password">Bad password!</string>
<string name="prompt_daemon_missing">Daemon address must be set!</string> <string name="prompt_daemon_missing">Daemon address must be set!</string>
<string name="prompt_wrong_net">Daemon does not fit wallet!</string> <string name="prompt_wrong_net">Daemon type does not fit to wallet!</string>
<string name="warn_daemon_unavailable">Warning: cannot reach daemon!</string>
<string name="panic">Something\'s wrong!</string>
<string name="title_amount">Amount</string> <string name="title_amount">Amount</string>
<string name="title_date">Date</string> <string name="title_date">Date</string>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="xmrwallet" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> <module external.linked.project.id="xmrwallet" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle"> <facet type="java-gradle" name="Java-Gradle">
<configuration> <configuration>
@ -13,7 +13,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> <excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>