diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java index c2bd6f956..b77f115bd 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java @@ -79,6 +79,7 @@ public class VpnProfileControlActivity extends AppCompatActivity implements VpnD private Bundle mProfileInfo; private boolean mWaitingForResult; private VpnStateService mService; + private boolean mBound; /* profile lookups are SQLite queries and must not block the main thread */ private final ExecutorService mProfileExecutor = Executors.newSingleThreadExecutor(); private final ServiceConnection mServiceConnection = new ServiceConnection() @@ -140,8 +141,8 @@ public class VpnProfileControlActivity extends AppCompatActivity implements VpnD { mWaitingForResult = savedInstanceState.getBoolean(WAITING_FOR_RESULT, false); } - this.bindService(new Intent(this, VpnStateService.class), - mServiceConnection, Service.BIND_AUTO_CREATE); + mBound = this.bindService(new Intent(this, VpnStateService.class), + mServiceConnection, Service.BIND_AUTO_CREATE); VpnDialogBus.INSTANCE.setListener(this); VpnDialogsKt.installVpnDialogHost(this); } @@ -159,10 +160,12 @@ public class VpnProfileControlActivity extends AppCompatActivity implements VpnD super.onDestroy(); VpnDialogBus.INSTANCE.setListener(null); mProfileExecutor.shutdown(); - if (mService != null) + if (mBound) { this.unbindService(mServiceConnection); + mBound = false; } + mService = null; } /** @@ -429,6 +432,10 @@ public class VpnProfileControlActivity extends AppCompatActivity implements VpnD mProfileExecutor.execute(() -> { VpnProfile profile = loadProfile(uuid); runOnUiThread(() -> { + if (isFinishing() || isDestroyed()) + { /* rotated or finished while the query ran */ + return; + } if (profile != null) { startVpnProfile(profile); @@ -479,7 +486,12 @@ public class VpnProfileControlActivity extends AppCompatActivity implements VpnD final Intent startIntent = intent; mProfileExecutor.execute(() -> { VpnProfile profile = loadProfile(uuid); - runOnUiThread(() -> handleDisconnect(startIntent, profile)); + runOnUiThread(() -> { + if (!isFinishing() && !isDestroyed()) + { + handleDisconnect(startIntent, profile); + } + }); }); } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnTileService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnTileService.java index 53e6eaae0..10852e539 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnTileService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnTileService.java @@ -45,6 +45,7 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt private boolean mListening; private VpnProfileDataSource mDataSource; private VpnStateService mService; + private boolean mBound; private final ServiceConnection mServiceConnection = new ServiceConnection() { @Override @@ -71,8 +72,8 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt super.onCreate(); Context context = getApplicationContext(); - context.bindService(new Intent(context, VpnStateService.class), - mServiceConnection, Service.BIND_AUTO_CREATE); + mBound = context.bindService(new Intent(context, VpnStateService.class), + mServiceConnection, Service.BIND_AUTO_CREATE); mDataSource = new VpnProfileSource(this); mDataSource.open(); @@ -83,10 +84,14 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt { super.onDestroy(); - if (mService != null) + /* the binding lives on the application context: unbind even if the + * service never connected, or it leaks for the life of the process */ + if (mBound) { getApplicationContext().unbindService(mServiceConnection); + mBound = false; } + mService = null; mDataSource.close(); mDataSource = null; }