From 03de55ad987ea40dbb2446091cea3a1b87b84ff7 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 8 Aug 2012 12:04:38 +0200 Subject: [PATCH] CharonVpnService binds to VpnStateService and does basic state updates --- .../strongswan/android/logic/CharonVpnService.java | 95 +++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java index 2f11cf1..083b98c 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/src/org/strongswan/android/logic/CharonVpnService.java @@ -19,10 +19,16 @@ package org.strongswan.android.logic; import org.strongswan.android.data.VpnProfile; import org.strongswan.android.data.VpnProfileDataSource; +import org.strongswan.android.logic.VpnStateService.ErrorState; +import org.strongswan.android.logic.VpnStateService.State; +import android.app.Service; +import android.content.ComponentName; import android.content.Intent; +import android.content.ServiceConnection; import android.net.VpnService; import android.os.Bundle; +import android.os.IBinder; import android.util.Log; public class CharonVpnService extends VpnService implements Runnable @@ -34,6 +40,29 @@ public class CharonVpnService extends VpnService implements Runnable private VpnProfile mNextProfile; private volatile boolean mProfileUpdated; private volatile boolean mTerminate; + private VpnStateService mService; + private final Object mServiceLock = new Object(); + private final ServiceConnection mServiceConnection = new ServiceConnection() { + @Override + public void onServiceDisconnected(ComponentName name) + { /* since the service is local this is theoretically only called when the process is terminated */ + synchronized (mServiceLock) + { + mService = null; + } + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) + { + synchronized (mServiceLock) + { + mService = ((VpnStateService.LocalBinder)service).getService(); + } + /* we are now ready to start the handler thread */ + mConnectionHandler.start(); + } + }; @Override public int onStartCommand(Intent intent, int flags, int startId) @@ -63,7 +92,9 @@ public class CharonVpnService extends VpnService implements Runnable mDataSource.open(); /* use a separate thread as main thread for charon */ mConnectionHandler = new Thread(this); - mConnectionHandler.start(); + /* the thread is started when the service is bound */ + bindService(new Intent(this, VpnStateService.class), + mServiceConnection, Service.BIND_AUTO_CREATE); } @Override @@ -86,6 +117,10 @@ public class CharonVpnService extends VpnService implements Runnable { e.printStackTrace(); } + if (mService != null) + { + unbindService(mServiceConnection); + } mDataSource.close(); } @@ -122,6 +157,8 @@ public class CharonVpnService extends VpnService implements Runnable stopCurrentConnection(); if (mNextProfile == null) { + setProfile(null); + setState(State.DISABLED); if (mTerminate) { break; @@ -132,6 +169,10 @@ public class CharonVpnService extends VpnService implements Runnable mCurrentProfile = mNextProfile; mNextProfile = null; + setProfile(mCurrentProfile); + setError(ErrorState.NO_ERROR); + setState(State.CONNECTING); + initializeCharon(); Log.i(TAG, "charon started"); } @@ -139,6 +180,7 @@ public class CharonVpnService extends VpnService implements Runnable catch (InterruptedException ex) { stopCurrentConnection(); + setState(State.DISABLED); } } } @@ -153,6 +195,7 @@ public class CharonVpnService extends VpnService implements Runnable { if (mCurrentProfile != null) { + setState(State.DISCONNECTING); deinitializeCharon(); Log.i(TAG, "charon stopped"); mCurrentProfile = null; @@ -161,6 +204,56 @@ public class CharonVpnService extends VpnService implements Runnable } /** + * Update the VPN profile on the state service. Called by the handler thread. + * + * @param profile currently active VPN profile + */ + private void setProfile(VpnProfile profile) + { + synchronized (mServiceLock) + { + if (mService != null) + { + mService.setProfile(profile); + } + } + } + + /** + * Update the current VPN state on the state service. Called by the handler + * thread and any of charon's threads. + * + * @param state current state + */ + private void setState(State state) + { + synchronized (mServiceLock) + { + if (mService != null) + { + mService.setState(state); + } + } + } + + /** + * Set an error on the state service. Called by the handler thread and any + * of charon's threads. + * + * @param error error state + */ + private void setError(ErrorState error) + { + synchronized (mServiceLock) + { + if (mService != null) + { + mService.setError(error); + } + } + } + + /** * Initialization of charon, provided by libandroidbridge.so */ public native void initializeCharon(); -- 2.7.4