mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2024-11-16 00:12:43 +00:00
android work 1
This commit is contained in:
parent
e77037c2b8
commit
62d9a47c3d
@ -8,8 +8,8 @@ import android.util.Log;
|
||||
public class DaemonSingleton {
|
||||
private static final String TAG="i2pd";
|
||||
private static final DaemonSingleton instance = new DaemonSingleton();
|
||||
public static interface StateUpdateListener { void daemonStateUpdate(); }
|
||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<StateUpdateListener>();
|
||||
public interface StateUpdateListener { void daemonStateUpdate(); }
|
||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
||||
|
||||
public static DaemonSingleton getInstance() {
|
||||
return instance;
|
||||
@ -18,63 +18,54 @@ public class DaemonSingleton {
|
||||
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
||||
|
||||
private synchronized void setState(State newState) {
|
||||
if(newState==null)throw new NullPointerException();
|
||||
State oldState = state;
|
||||
if(oldState==null)throw new NullPointerException();
|
||||
if(oldState.equals(newState))return;
|
||||
state=newState;
|
||||
fireStateUpdate1();
|
||||
}
|
||||
public synchronized void stopAcceptingTunnels() {
|
||||
if(isStartedOkay()){
|
||||
state=State.gracefulShutdownInProgress;
|
||||
fireStateUpdate();
|
||||
setState(State.gracefulShutdownInProgress);
|
||||
I2PD_JNI.stopAcceptingTunnels();
|
||||
}
|
||||
}
|
||||
|
||||
public void onNetworkStateChange(boolean isConnected) {
|
||||
I2PD_JNI.onNetworkStateChanged(isConnected);
|
||||
}
|
||||
private volatile boolean startedOkay;
|
||||
|
||||
private boolean startedOkay;
|
||||
public enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress,stopped};
|
||||
|
||||
public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress,stopped};
|
||||
|
||||
private State state = State.uninitialized;
|
||||
private volatile State state = State.uninitialized;
|
||||
|
||||
public State getState() { return state; }
|
||||
|
||||
public synchronized void start() {
|
||||
if(state != State.uninitialized)return;
|
||||
state = State.starting;
|
||||
fireStateUpdate();
|
||||
{
|
||||
setState(State.starting);
|
||||
new Thread(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
I2PD_JNI.loadLibraries();
|
||||
synchronized (DaemonSingleton.this) {
|
||||
state = State.jniLibraryLoaded;
|
||||
fireStateUpdate();
|
||||
}
|
||||
setState(State.jniLibraryLoaded);
|
||||
} catch (Throwable tr) {
|
||||
lastThrowable=tr;
|
||||
synchronized (DaemonSingleton.this) {
|
||||
state = State.startFailed;
|
||||
fireStateUpdate();
|
||||
}
|
||||
setState(State.startFailed);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
synchronized (DaemonSingleton.this) {
|
||||
daemonStartResult = I2PD_JNI.startDaemon();
|
||||
if("ok".equals(daemonStartResult)){
|
||||
state=State.startedOkay;
|
||||
setState(State.startedOkay);
|
||||
setStartedOkay(true);
|
||||
}else state=State.startFailed;
|
||||
fireStateUpdate();
|
||||
}else setState(State.startFailed);
|
||||
}
|
||||
} catch (Throwable tr) {
|
||||
lastThrowable=tr;
|
||||
synchronized (DaemonSingleton.this) {
|
||||
state = State.startFailed;
|
||||
fireStateUpdate();
|
||||
}
|
||||
setState(State.startFailed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -84,7 +75,7 @@ public class DaemonSingleton {
|
||||
private Throwable lastThrowable;
|
||||
private String daemonStartResult="N/A";
|
||||
|
||||
private synchronized void fireStateUpdate() {
|
||||
private void fireStateUpdate1() {
|
||||
Log.i(TAG, "daemon state change: "+state);
|
||||
for(StateUpdateListener listener : stateUpdateListeners) {
|
||||
try {
|
||||
@ -121,10 +112,7 @@ public class DaemonSingleton {
|
||||
if(isStartedOkay()){
|
||||
try {I2PD_JNI.stopDaemon();}catch(Throwable tr){Log.e(TAG, "", tr);}
|
||||
setStartedOkay(false);
|
||||
synchronized (DaemonSingleton.this) {
|
||||
state = State.stopped;
|
||||
fireStateUpdate();
|
||||
}
|
||||
setState(State.stopped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,15 +34,13 @@ public class ForegroundService extends Service {
|
||||
|
||||
// Display a notification about us starting. We put an icon in the status bar.
|
||||
showNotification();
|
||||
daemon.start();
|
||||
// Tell the user we started.
|
||||
Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
||||
// Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
|
||||
daemon.start();
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@ -54,7 +52,7 @@ public class ForegroundService extends Service {
|
||||
stopForeground(true);
|
||||
|
||||
// Tell the user we stopped.
|
||||
Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
||||
// Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,6 +90,6 @@ public class ForegroundService extends Service {
|
||||
startForeground(NOTIFICATION, notification);
|
||||
}
|
||||
|
||||
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ public class I2PDActivity extends Activity {
|
||||
|
||||
private TextView textView;
|
||||
|
||||
private final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||
|
||||
private DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
||||
new DaemonSingleton.StateUpdateListener() {
|
||||
|
||||
@Override
|
||||
@ -58,7 +58,7 @@ public class I2PDActivity extends Activity {
|
||||
|
||||
textView = new TextView(this);
|
||||
setContentView(textView);
|
||||
DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener);
|
||||
daemon.addStateChangeListener(daemonStateUpdatedListener);
|
||||
daemonStateUpdatedListener.daemonStateUpdate();
|
||||
|
||||
//set the app be foreground
|
||||
@ -68,22 +68,18 @@ public class I2PDActivity extends Activity {
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
localDestroy();
|
||||
}
|
||||
|
||||
private void localDestroy() {
|
||||
textView = null;
|
||||
DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener);
|
||||
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||
if(gracefulQuitTimer!=null) {
|
||||
gracefulQuitTimer.cancel();
|
||||
setGracefulQuitTimer(null);
|
||||
textView = null;
|
||||
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
||||
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||
if(gracefulQuitTimer!=null) {
|
||||
gracefulQuitTimer.cancel();
|
||||
setGracefulQuitTimer(null);
|
||||
}
|
||||
try{
|
||||
doUnbindService();
|
||||
}catch(Throwable tr){
|
||||
Log.e(TAG, "", tr);
|
||||
}
|
||||
// try{
|
||||
// doUnbindService();
|
||||
// }catch(Throwable tr){
|
||||
// Log.e(TAG, "", tr);
|
||||
// }
|
||||
}
|
||||
|
||||
private CharSequence throwableToString(Throwable tr) {
|
||||
@ -122,24 +118,27 @@ public class I2PDActivity extends Activity {
|
||||
};
|
||||
|
||||
|
||||
private boolean mIsBound;
|
||||
private static volatile boolean mIsBound;
|
||||
|
||||
private synchronized void doBindService() {
|
||||
if(mIsBound)return;
|
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because we want a specific service implementation that
|
||||
// we know will be running in our own process (and thus won't be
|
||||
// supporting component replacement by other applications).
|
||||
bindService(new Intent(this,
|
||||
ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
|
||||
mIsBound = true;
|
||||
private void doBindService() {
|
||||
synchronized (I2PDActivity.class) {
|
||||
if (mIsBound) return;
|
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because we want a specific service implementation that
|
||||
// we know will be running in our own process (and thus won't be
|
||||
// supporting component replacement by other applications).
|
||||
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
|
||||
mIsBound = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void doUnbindService() {
|
||||
if (mIsBound) {
|
||||
// Detach our existing connection.
|
||||
unbindService(mConnection);
|
||||
mIsBound = false;
|
||||
synchronized (I2PDActivity.class) {
|
||||
if (mIsBound) {
|
||||
// Detach our existing connection.
|
||||
unbindService(mConnection);
|
||||
mIsBound = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,9 +176,9 @@ public class I2PDActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private Timer gracefulQuitTimer;
|
||||
private final Object gracefulQuitTimerLock = new Object();
|
||||
private synchronized void i2pdGracefulStop() {
|
||||
private volatile Timer gracefulQuitTimer;
|
||||
|
||||
private void i2pdGracefulStop() {
|
||||
if(daemon.getState()==DaemonSingleton.State.stopped){
|
||||
Toast.makeText(this, R.string.already_stopped,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
@ -218,18 +217,14 @@ public class I2PDActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
},"gracQuitInit").start();
|
||||
},"gracInit").start();
|
||||
}
|
||||
|
||||
private Timer getGracefulQuitTimer() {
|
||||
synchronized (gracefulQuitTimerLock) {
|
||||
return gracefulQuitTimer;
|
||||
}
|
||||
return gracefulQuitTimer;
|
||||
}
|
||||
|
||||
private void setGracefulQuitTimer(Timer gracefulQuitTimer) {
|
||||
synchronized (gracefulQuitTimerLock) {
|
||||
this.gracefulQuitTimer = gracefulQuitTimer;
|
||||
}
|
||||
this.gracefulQuitTimer = gracefulQuitTimer;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user