2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 package org
.strongswan
.android
.logic
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
20 import java
.util
.concurrent
.Callable
;
22 import org
.strongswan
.android
.data
.VpnProfile
;
24 import android
.app
.Service
;
25 import android
.content
.Intent
;
26 import android
.os
.Binder
;
27 import android
.os
.Handler
;
28 import android
.os
.IBinder
;
30 public class VpnStateService
extends Service
32 private final List
<VpnStateListener
> mListeners
= new ArrayList
<VpnStateListener
>();
33 private final IBinder mBinder
= new LocalBinder();
34 private Handler mHandler
;
35 private VpnProfile mProfile
;
36 private State mState
= State
.DISABLED
;
37 private ErrorState mError
= ErrorState
.NO_ERROR
;
47 public enum ErrorState
58 * Listener interface for bound clients that are interested in changes to
61 public interface VpnStateListener
63 public void stateChanged();
67 * Simple Binder that allows to directly access this Service class itself
68 * after binding to it.
70 public class LocalBinder
extends Binder
72 public VpnStateService
getService()
74 return VpnStateService
.this;
79 public void onCreate()
81 /* this handler allows us to notify listeners from the UI thread and
82 * not from the threads that actually report any state changes */
83 mHandler
= new Handler();
87 public IBinder
onBind(Intent intent
)
93 public void onDestroy()
98 * Register a listener with this Service. We assume this is called from
99 * the main thread so no synchronization is happening.
101 * @param listener listener to register
103 public void registerListener(VpnStateListener listener
)
105 mListeners
.add(listener
);
109 * Unregister a listener from this Service.
111 * @param listener listener to unregister
113 public void unregisterListener(VpnStateListener listener
)
115 mListeners
.remove(listener
);
119 * Get the current VPN profile.
123 public VpnProfile
getProfile()
124 { /* only updated from the main thread so no synchronization needed */
129 * Get the current state.
133 public State
getState()
134 { /* only updated from the main thread so no synchronization needed */
139 * Get the current error, if any.
143 public ErrorState
getErrorState()
144 { /* only updated from the main thread so no synchronization needed */
149 * Update state and notify all listeners about the change. By using a Handler
150 * this is done from the main UI thread and not the initial reporter thread.
151 * Also, in doing the actual state change from the main thread, listeners
152 * see all changes and none are skipped.
154 * @param change the state update to perform before notifying listeners, returns true if state changed
156 private void notifyListeners(final Callable
<Boolean
> change
)
158 mHandler
.post(new Runnable() {
165 { /* otherwise there is no need to notify the listeners */
166 for (VpnStateListener listener
: mListeners
)
168 listener
.stateChanged();
181 * Set the VPN profile currently active. Listeners are not notified.
183 * May be called from threads other than the main thread.
185 * @param profile current profile
187 public void setProfile(final VpnProfile profile
)
189 /* even though we don't notify the listeners the update is done from the
190 * same handler so updates are predictable for listeners */
191 mHandler
.post(new Runnable() {
195 VpnStateService
.this.mProfile
= profile
;
201 * Update the state and notify all listeners, if changed.
203 * May be called from threads other than the main thread.
205 * @param state new state
207 public void setState(final State state
)
209 notifyListeners(new Callable
<Boolean
>() {
211 public Boolean
call() throws Exception
213 if (VpnStateService
.this.mState
!= state
)
215 VpnStateService
.this.mState
= state
;
224 * Set the current error state and notify all listeners, if changed.
226 * May be called from threads other than the main thread.
228 * @param error error state
230 public void setError(final ErrorState error
)
232 notifyListeners(new Callable
<Boolean
>() {
234 public Boolean
call() throws Exception
236 if (VpnStateService
.this.mError
!= error
)
238 VpnStateService
.this.mError
= error
;