Bugfix Service restart after OS kill (#96)

* single open wallet

* prevent WalletService & Activity from restarting
removed stray png
This commit is contained in:
m2049r 2017-10-03 22:45:03 +02:00 committed by GitHub
parent f282f01edd
commit e8b749af3b
5 changed files with 52 additions and 56 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 25 targetSdkVersion 25
versionCode 24 versionCode 25
versionName "1.0.1" versionName "1.0.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

View File

@ -151,7 +151,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
Log.d(TAG, "onCreate()"); Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (savedInstanceState != null) { if (savedInstanceState != null) {
// we don't store anything ourselves // activity restarted
// we don't want that - finish it and fall back to previous activity
finish();
return;
} }
setContentView(R.layout.wallet_activity); setContentView(R.layout.wallet_activity);

View File

@ -16,6 +16,7 @@
package com.m2049r.xmrwallet.model; package com.m2049r.xmrwallet.model;
import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -45,36 +46,36 @@ public class WalletManager {
return WalletManager.Instance; return WalletManager.Instance;
} }
private WalletManager() { //private Map<String, Wallet> managedWallets;
this.managedWallets = new HashMap<>(); private Wallet managedWallet = null;
public Wallet getWallet() {
return managedWallet;
} }
private Map<String, Wallet> managedWallets; private void manageWallet(Wallet wallet) {
Log.d(TAG, "Managing " + wallet.getName());
public Wallet getWallet(String walletId) { managedWallet = wallet;
return managedWallets.get(walletId);
} }
private void manageWallet(String walletId, Wallet wallet) { private void unmanageWallet(Wallet wallet) {
if (getWallet(walletId) != null) { if (wallet == null) {
throw new IllegalStateException(walletId + " already under management!"); throw new IllegalArgumentException("Cannot unmanage null!");
} }
Log.d(TAG, "Managing " + walletId); if (getWallet() == null) {
managedWallets.put(walletId, wallet); throw new IllegalStateException("No wallet under management!");
}
private void unmanageWallet(String walletId) {
if (getWallet(walletId) == null) {
throw new IllegalStateException(walletId + " not under management!");
} }
Log.d(TAG, "Unmanaging " + walletId); if (getWallet() != wallet) {
managedWallets.remove(walletId); throw new IllegalStateException(wallet.getName() + " not under management!");
}
Log.d(TAG, "Unmanaging " + managedWallet.getName());
managedWallet = null;
} }
public Wallet createWallet(File aFile, String password, String language) { public Wallet createWallet(File aFile, String password, String language) {
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet()); long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
Wallet wallet = new Wallet(walletHandle); Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet); manageWallet(wallet);
return wallet; return wallet;
} }
@ -83,7 +84,7 @@ public class WalletManager {
public Wallet openWallet(String path, String password) { public Wallet openWallet(String path, String password) {
long walletHandle = openWalletJ(path, password, isTestNet()); long walletHandle = openWalletJ(path, password, isTestNet());
Wallet wallet = new Wallet(walletHandle); Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet); manageWallet(wallet);
return wallet; return wallet;
} }
@ -91,14 +92,14 @@ public class WalletManager {
public Wallet recoveryWallet(File aFile, String mnemonic) { public Wallet recoveryWallet(File aFile, String mnemonic) {
Wallet wallet = recoveryWallet(aFile, mnemonic, 0); Wallet wallet = recoveryWallet(aFile, mnemonic, 0);
manageWallet(wallet.getName(), wallet); manageWallet(wallet);
return wallet; return wallet;
} }
public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) { public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) {
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight); long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight);
Wallet wallet = new Wallet(walletHandle); Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet); manageWallet(wallet);
return wallet; return wallet;
} }
@ -109,7 +110,7 @@ public class WalletManager {
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight, long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight,
addressString, viewKeyString, spendKeyString); addressString, viewKeyString, spendKeyString);
Wallet wallet = new Wallet(walletHandle); Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet); manageWallet(wallet);
return wallet; return wallet;
} }
@ -123,13 +124,12 @@ public class WalletManager {
public native boolean closeJ(Wallet wallet); public native boolean closeJ(Wallet wallet);
public boolean close(Wallet wallet) { public boolean close(Wallet wallet) {
String walletId = new File(wallet.getFilename()).getName(); unmanageWallet(wallet);
unmanageWallet(walletId);
boolean closed = closeJ(wallet); boolean closed = closeJ(wallet);
if (!closed) { if (!closed) {
// in case we could not close it // in case we could not close it
// we unmanage it // we manage it again
manageWallet(walletId, wallet); manageWallet(wallet);
} }
return closed; return closed;
} }

View File

@ -70,20 +70,11 @@ public class WalletService extends Service {
private MyWalletListener listener = null; private MyWalletListener listener = null;
private class MyWalletListener implements WalletListener { private class MyWalletListener implements WalletListener {
private Wallet wallet;
boolean updated = true; boolean updated = true;
Wallet getWallet() {
return wallet;
}
MyWalletListener(Wallet aWallet) {
if (aWallet == null) throw new IllegalArgumentException("Cannot open wallet!");
this.wallet = aWallet;
}
void start() { void start() {
Log.d(TAG, "MyWalletListener.start()"); Log.d(TAG, "MyWalletListener.start()");
Wallet wallet = getWallet();
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
//acquireWakeLock(); //acquireWakeLock();
wallet.setListener(this); wallet.setListener(this);
@ -92,6 +83,7 @@ public class WalletService extends Service {
void stop() { void stop() {
Log.d(TAG, "MyWalletListener.stop()"); Log.d(TAG, "MyWalletListener.stop()");
Wallet wallet = getWallet();
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
wallet.pauseRefresh(); wallet.pauseRefresh();
wallet.setListener(null); wallet.setListener(null);
@ -115,6 +107,7 @@ public class WalletService extends Service {
int lastTxCount = 0; int lastTxCount = 0;
public void newBlock(long height) { public void newBlock(long height) {
Wallet wallet = getWallet();
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
// don't flood with an update for every block ... // don't flood with an update for every block ...
if (lastBlockTime < System.currentTimeMillis() - 2000) { if (lastBlockTime < System.currentTimeMillis() - 2000) {
@ -141,14 +134,16 @@ public class WalletService extends Service {
} }
public void updated() { public void updated() {
Log.d(TAG, "updated() " + wallet.getBalance()); Log.d(TAG, "updated()");
Wallet wallet = getWallet();
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
updated = true; updated = true;
} }
public void refreshed() { public void refreshed() {
Log.d(TAG, "refreshed()");
Wallet wallet = getWallet();
if (wallet == null) throw new IllegalStateException("No wallet!"); if (wallet == null) throw new IllegalStateException("No wallet!");
Log.d(TAG, "refreshed() " + wallet.getName() + " " + wallet.getBalance() + " sync=" + wallet.isSynchronized() + " with observer " + observer);
if (updated) { if (updated) {
if (observer != null) { if (observer != null) {
updateDaemonState(wallet, 0); updateDaemonState(wallet, 0);
@ -253,8 +248,7 @@ public class WalletService extends Service {
// //
public Wallet getWallet() { public Wallet getWallet() {
if (listener == null) throw new IllegalStateException("no listener"); return WalletManager.getInstance().getWallet();
return listener.getWallet();
} }
///////////////////////////////////////////// /////////////////////////////////////////////
@ -441,10 +435,15 @@ public class WalletService extends Service {
// 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();
msg.arg2 = START_SERVICE; msg.arg2 = START_SERVICE;
msg.setData(intent.getExtras()); if (intent != null) {
mServiceHandler.sendMessage(msg); msg.setData(intent.getExtras());
//Log.d(TAG, "onStartCommand() message sent"); mServiceHandler.sendMessage(msg);
return START_STICKY; return START_STICKY;
} else {
// process restart - don't do anything - let system kill it again
stop();
return START_NOT_STICKY;
}
} }
@Override @Override
@ -466,9 +465,8 @@ public class WalletService extends Service {
} }
private boolean start(String walletName, String walletPassword) { private boolean start(String walletName, String walletPassword) {
startNotfication();
// if there is an listener it is always started / syncing
Log.d(TAG, "start()"); Log.d(TAG, "start()");
startNotfication();
showProgress(getString(R.string.status_wallet_loading)); showProgress(getString(R.string.status_wallet_loading));
showProgress(10); showProgress(10);
if (listener == null) { if (listener == null) {
@ -478,7 +476,7 @@ public class WalletService extends Service {
if (aWallet != null) aWallet.close(); if (aWallet != null) aWallet.close();
return false; return false;
} }
listener = new MyWalletListener(aWallet); listener = new MyWalletListener();
listener.start(); listener.start();
showProgress(100); showProgress(100);
} }
@ -496,10 +494,6 @@ public class WalletService extends Service {
if (listener != null) { if (listener != null) {
listener.stop(); listener.stop();
Wallet myWallet = getWallet(); Wallet myWallet = getWallet();
// if (!myWallet.isSynchronized()) { // save only if NOT synced (to continue later)
// Log.d(TAG, "stop() saving");
// myWallet.store();
// }
Log.d(TAG, "stop() closing"); Log.d(TAG, "stop() closing");
myWallet.close(); myWallet.close();
Log.d(TAG, "stop() closed"); Log.d(TAG, "stop() closed");
@ -561,6 +555,5 @@ public class WalletService extends Service {
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.build(); .build();
startForeground(NOTIFICATION_ID, notification); startForeground(NOTIFICATION_ID, notification);
} }
} }