From 62d9a47c3d60cb5cf224f0159135ef02c3568cc3 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 18:23:05 +0800 Subject: [PATCH 1/6] android work 1 --- .../org/purplei2p/i2pd/DaemonSingleton.java | 58 ++++++-------- .../org/purplei2p/i2pd/ForegroundService.java | 8 +- .../src/org/purplei2p/i2pd/I2PDActivity.java | 79 +++++++++---------- 3 files changed, 63 insertions(+), 82 deletions(-) diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index 64568f83..cba29a18 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -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 stateUpdateListeners = new HashSet(); + public interface StateUpdateListener { void daemonStateUpdate(); } + private final Set 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 boolean startedOkay; + private volatile boolean startedOkay; - public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress,stopped}; + public 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); } } } diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index 74761b07..07254439 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -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(); } diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 36e992b3..64316112 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -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; } } From 0994211a48a77329282f0deeec4e37b67ffcd120 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 18:24:51 +0800 Subject: [PATCH 2/6] android gitignore --- android/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/.gitignore b/android/.gitignore index d9fa5a57..efb83e7b 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -5,4 +5,5 @@ ant.properties local.properties build.sh bin -log* \ No newline at end of file +log* +.gradle android.iml build gradle gradlew gradlew.bat From 1b56d66fc80147e0e91b6774ef63bfa81e05aa48 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 18:25:36 +0800 Subject: [PATCH 3/6] android gitignore --- android/.gitignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android/.gitignore b/android/.gitignore index efb83e7b..90cd315e 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -6,4 +6,10 @@ local.properties build.sh bin log* -.gradle android.iml build gradle gradlew gradlew.bat +.gradle +android.iml +build +gradle +gradlew +gradlew.bat + From 33735b343d1205d5d4ead28d537146ba66e94334 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 19:24:43 +0800 Subject: [PATCH 4/6] fixes 1094; fixes grac stop --- android/res/values/strings.xml | 11 ++- .../org/purplei2p/i2pd/DaemonSingleton.java | 20 ++++- .../org/purplei2p/i2pd/ForegroundService.java | 40 ++++++++-- .../src/org/purplei2p/i2pd/I2PDActivity.java | 73 ++++++++++++++----- 4 files changed, 118 insertions(+), 26 deletions(-) diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index c147a808..1421b261 100755 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -1,12 +1,17 @@ i2pd - i2pd started - i2pd service started - i2pd service stopped Stop Graceful Stop Graceful stop is already in progress Graceful stop is in progress Already stopped + i2pd initializing + i2pd is starting + i2pd: loaded JNI libraries + i2pd started + i2pd start failed + i2pd: graceful shutdown in progress + i2pd has stopped + remaining diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index cba29a18..4f3e62f7 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -35,7 +35,25 @@ public class DaemonSingleton { private volatile boolean startedOkay; - public enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress,stopped}; + public enum State { + uninitialized(R.string.uninitialized), + starting(R.string.starting), + jniLibraryLoaded(R.string.jniLibraryLoaded), + startedOkay(R.string.startedOkay), + startFailed(R.string.startFailed), + gracefulShutdownInProgress(R.string.gracefulShutdownInProgress), + stopped(R.string.stopped); + + State(int statusStringResourceId) { + this.statusStringResourceId = statusStringResourceId; + } + + private final int statusStringResourceId; + + public int getStatusStringResourceId() { + return statusStringResourceId; + } + }; private volatile State state = State.uninitialized; diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index 07254439..6116b982 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -11,11 +11,32 @@ import android.util.Log; import android.widget.Toast; public class ForegroundService extends Service { + private static final String TAG="FgService"; + + private volatile boolean shown; + + private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = + new DaemonSingleton.StateUpdateListener() { + + @Override + public void daemonStateUpdate() { + try { + synchronized (ForegroundService.this) { + if (shown) cancelNotification(); + showNotification(); + } + } catch (Throwable tr) { + Log.e(TAG,"error ignored",tr); + } + } + }; + + private NotificationManager notificationManager; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. - private int NOTIFICATION = R.string.i2pd_started; + private int NOTIFICATION = 1; /** * Class for clients to access. Because we know this service always @@ -32,8 +53,10 @@ public class ForegroundService extends Service { public void onCreate() { notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - // Display a notification about us starting. We put an icon in the status bar. - showNotification(); + synchronized (this) { + DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener); + if (!shown) daemonStateUpdatedListener.daemonStateUpdate(); + } // Tell the user we started. // Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show(); } @@ -46,6 +69,11 @@ public class ForegroundService extends Service { @Override public void onDestroy() { + DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener); + cancelNotification(); + } + + private synchronized void cancelNotification() { // Cancel the persistent notification. notificationManager.cancel(NOTIFICATION); @@ -53,6 +81,7 @@ public class ForegroundService extends Service { // Tell the user we stopped. // Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show(); + shown=false; } @Override @@ -67,9 +96,9 @@ public class ForegroundService extends Service { /** * Show a notification while this service is running. */ - private void showNotification() { + private synchronized void showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(R.string.i2pd_started); + CharSequence text = getText(DaemonSingleton.getInstance().getState().getStatusStringResourceId()); // The PendingIntent to launch our activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, @@ -88,6 +117,7 @@ public class ForegroundService extends Service { // Send the notification. //mNM.notify(NOTIFICATION, notification); startForeground(NOTIFICATION, notification); + shown=true; } private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 64316112..af0c8000 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -19,9 +19,10 @@ import android.widget.TextView; import android.widget.Toast; public class I2PDActivity extends Activity { - private static final String TAG = "i2pd"; + private static final String TAG = "i2pdActvt"; + public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; - private TextView textView; + private TextView textView; private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); @@ -42,8 +43,11 @@ public class I2PDActivity extends Activity { return; } DaemonSingleton.State state = daemon.getState(); - textView.setText(String.valueOf(state)+ - (DaemonSingleton.State.startFailed.equals(state)?": "+daemon.getDaemonStartResult():"")); + textView.setText( + String.valueOf(state)+ + (DaemonSingleton.State.startFailed.equals(state)?": "+daemon.getDaemonStartResult():"")+ + (DaemonSingleton.State.gracefulShutdownInProgress.equals(state)?": "+formatGraceTimeRemaining()+" "+getText(R.string.remaining):"") + ); } catch (Throwable tr) { Log.e(TAG,"error ignored",tr); } @@ -51,6 +55,18 @@ public class I2PDActivity extends Activity { }); } }; + private volatile long graceStartedMillis; + private final Object graceStartedMillis_LOCK=new Object(); + + private String formatGraceTimeRemaining() { + long remainingSeconds; + synchronized (graceStartedMillis_LOCK){ + remainingSeconds=Math.round(Math.max(0,graceStartedMillis+GRACEFUL_DELAY_MILLIS-System.currentTimeMillis())/1000.0D); + } + long remainingMinutes=(long)Math.floor(remainingSeconds/60.0D); + long remSec=remainingSeconds-remainingMinutes*60; + return remainingMinutes+":"+(remSec/10)+remSec%10; + } @Override public void onCreate(Bundle savedInstanceState) { @@ -70,11 +86,7 @@ public class I2PDActivity extends Activity { super.onDestroy(); textView = null; daemon.removeStateChangeListener(daemonStateUpdatedListener); - Timer gracefulQuitTimer = getGracefulQuitTimer(); - if(gracefulQuitTimer!=null) { - gracefulQuitTimer.cancel(); - setGracefulQuitTimer(null); - } + cancelGracefulStop(); try{ doUnbindService(); }catch(Throwable tr){ @@ -82,7 +94,15 @@ public class I2PDActivity extends Activity { } } - private CharSequence throwableToString(Throwable tr) { + private void cancelGracefulStop() { + Timer gracefulQuitTimer = getGracefulQuitTimer(); + if(gracefulQuitTimer!=null) { + gracefulQuitTimer.cancel(); + setGracefulQuitTimer(null); + } + } + + private CharSequence throwableToString(Throwable tr) { StringWriter sw = new StringWriter(8192); PrintWriter pw = new PrintWriter(sw); tr.printStackTrace(pw); @@ -169,11 +189,20 @@ public class I2PDActivity extends Activity { } private void i2pdStop() { - try{ - daemon.stopDaemon(); - }catch (Throwable tr) { - Log.e(TAG, "", tr); - } + cancelGracefulStop(); + new Thread(new Runnable(){ + + @Override + public void run() { + Log.d(TAG, "stopping"); + try{ + daemon.stopDaemon(); + }catch (Throwable tr) { + Log.e(TAG, "", tr); + } + } + + },"stop").start(); } private volatile Timer gracefulQuitTimer; @@ -199,8 +228,11 @@ public class I2PDActivity extends Activity { Log.d(TAG, "grac stopping"); if(daemon.isStartedOkay()) { daemon.stopAcceptingTunnels(); - Timer gracefulQuitTimer = new Timer(true); + final Timer gracefulQuitTimer = new Timer(true); setGracefulQuitTimer(gracefulQuitTimer); + synchronized (graceStartedMillis_LOCK) { + graceStartedMillis = System.currentTimeMillis(); + } gracefulQuitTimer.schedule(new TimerTask(){ @Override @@ -208,7 +240,14 @@ public class I2PDActivity extends Activity { i2pdStop(); } - }, 10*60*1000/*milliseconds*/); + }, GRACEFUL_DELAY_MILLIS); + final TimerTask tickerTask = new TimerTask() { + @Override + public void run() { + daemonStateUpdatedListener.daemonStateUpdate(); + } + }; + gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/); }else{ i2pdStop(); } From 56f6e57118a58bc2d7c2a6ab73b6ad627bbb036a Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 19:54:19 +0800 Subject: [PATCH 5/6] fixes grac stop --- .../src/org/purplei2p/i2pd/I2PDActivity.java | 70 ++++++++++++------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index af0c8000..840e0bfa 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -20,7 +20,7 @@ import android.widget.Toast; public class I2PDActivity extends Activity { private static final String TAG = "i2pdActvt"; - public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; + public static final int GRACEFUL_DELAY_MILLIS = 120 * 1000; private TextView textView; @@ -55,10 +55,10 @@ public class I2PDActivity extends Activity { }); } }; - private volatile long graceStartedMillis; - private final Object graceStartedMillis_LOCK=new Object(); + private static volatile long graceStartedMillis; + private static final Object graceStartedMillis_LOCK=new Object(); - private String formatGraceTimeRemaining() { + private static String formatGraceTimeRemaining() { long remainingSeconds; synchronized (graceStartedMillis_LOCK){ remainingSeconds=Math.round(Math.max(0,graceStartedMillis+GRACEFUL_DELAY_MILLIS-System.currentTimeMillis())/1000.0D); @@ -79,6 +79,15 @@ public class I2PDActivity extends Activity { //set the app be foreground doBindService(); + + final Timer gracefulQuitTimer = getGracefulQuitTimer(); + if(gracefulQuitTimer!=null){ + long gracefulStopAtMillis; + synchronized (graceStartedMillis_LOCK) { + gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; + } + rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis); + } } @Override @@ -86,7 +95,7 @@ public class I2PDActivity extends Activity { super.onDestroy(); textView = null; daemon.removeStateChangeListener(daemonStateUpdatedListener); - cancelGracefulStop(); + //cancelGracefulStop(); try{ doUnbindService(); }catch(Throwable tr){ @@ -94,7 +103,7 @@ public class I2PDActivity extends Activity { } } - private void cancelGracefulStop() { + private static void cancelGracefulStop() { Timer gracefulQuitTimer = getGracefulQuitTimer(); if(gracefulQuitTimer!=null) { gracefulQuitTimer.cancel(); @@ -205,7 +214,7 @@ public class I2PDActivity extends Activity { },"stop").start(); } - private volatile Timer gracefulQuitTimer; + private static volatile Timer gracefulQuitTimer; private void i2pdGracefulStop() { if(daemon.getState()==DaemonSingleton.State.stopped){ @@ -228,26 +237,12 @@ public class I2PDActivity extends Activity { Log.d(TAG, "grac stopping"); if(daemon.isStartedOkay()) { daemon.stopAcceptingTunnels(); - final Timer gracefulQuitTimer = new Timer(true); - setGracefulQuitTimer(gracefulQuitTimer); + long gracefulStopAtMillis; synchronized (graceStartedMillis_LOCK) { graceStartedMillis = System.currentTimeMillis(); + gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; } - gracefulQuitTimer.schedule(new TimerTask(){ - - @Override - public void run() { - i2pdStop(); - } - - }, GRACEFUL_DELAY_MILLIS); - final TimerTask tickerTask = new TimerTask() { - @Override - public void run() { - daemonStateUpdatedListener.daemonStateUpdate(); - } - }; - gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/); + rescheduleGraceStop(null,gracefulStopAtMillis); }else{ i2pdStop(); } @@ -259,11 +254,32 @@ public class I2PDActivity extends Activity { },"gracInit").start(); } - private Timer getGracefulQuitTimer() { + private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) { + if(gracefulQuitTimerOld!=null)gracefulQuitTimerOld.cancel(); + final Timer gracefulQuitTimer = new Timer(true); + setGracefulQuitTimer(gracefulQuitTimer); + gracefulQuitTimer.schedule(new TimerTask(){ + + @Override + public void run() { + i2pdStop(); + } + + }, Math.max(0,gracefulStopAtMillis-System.currentTimeMillis())); + final TimerTask tickerTask = new TimerTask() { + @Override + public void run() { + daemonStateUpdatedListener.daemonStateUpdate(); + } + }; + gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/); + } + + private static Timer getGracefulQuitTimer() { return gracefulQuitTimer; } - private void setGracefulQuitTimer(Timer gracefulQuitTimer) { - this.gracefulQuitTimer = gracefulQuitTimer; + private static void setGracefulQuitTimer(Timer gracefulQuitTimer) { + I2PDActivity.gracefulQuitTimer = gracefulQuitTimer; } } From ac495da5fe6c8e688329bab0142392e56fe51dac Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 7 Feb 2018 19:56:44 +0800 Subject: [PATCH 6/6] fixes grac stop --- android/src/org/purplei2p/i2pd/I2PDActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 840e0bfa..99672eb7 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -20,7 +20,7 @@ import android.widget.Toast; public class I2PDActivity extends Activity { private static final String TAG = "i2pdActvt"; - public static final int GRACEFUL_DELAY_MILLIS = 120 * 1000; + public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; private TextView textView;