diff --git a/src/frontends/android/res/layout/vpn_state_fragment.xml b/src/frontends/android/res/layout/vpn_state_fragment.xml
index c3adeae8a..12d890a90 100644
--- a/src/frontends/android/res/layout/vpn_state_fragment.xml
+++ b/src/frontends/android/res/layout/vpn_state_fragment.xml
@@ -22,6 +22,56 @@
android:background="@drawable/vpn_state_background"
android:orientation="vertical" >
+
+
+
+
+
+
+
+
+
+
+
+
+
No CA certificate selected
Please select one or activate Select automatically
+
+ Status:
+ Profile:
+ Connecting…
+ Connected
+ Disconnecting…
+ No active VPN
+
Enter password to connect
Connect
+ Connecting: %1$s
+ Establishing VPN with \""%1$s\".
diff --git a/src/frontends/android/src/org/strongswan/android/ui/VpnStateFragment.java b/src/frontends/android/src/org/strongswan/android/ui/VpnStateFragment.java
index 5c4ffdd5d..fc250f18d 100644
--- a/src/frontends/android/src/org/strongswan/android/ui/VpnStateFragment.java
+++ b/src/frontends/android/src/org/strongswan/android/ui/VpnStateFragment.java
@@ -18,23 +18,35 @@
package org.strongswan.android.ui;
import org.strongswan.android.R;
+import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.logic.VpnStateService;
+import org.strongswan.android.logic.VpnStateService.State;
import org.strongswan.android.logic.VpnStateService.VpnStateListener;
import android.app.Fragment;
+import android.app.ProgressDialog;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.graphics.Color;
import android.os.Bundle;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
public class VpnStateFragment extends Fragment implements VpnStateListener
{
+ private TextView mProfileNameView;
+ private TextView mProfileView;
+ private TextView mStateView;
+ private int stateBaseColor;
+ private ProgressDialog mProgressDialog;
+ private State mState;
private VpnStateService mService;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
@@ -47,6 +59,8 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
public void onServiceConnected(ComponentName name, IBinder service)
{
mService = ((VpnStateService.LocalBinder)service).getService();
+ mService.registerListener(VpnStateFragment.this);
+ updateView();
}
};
@@ -66,13 +80,30 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.vpn_state_fragment, null);
+
+ mStateView = (TextView)view.findViewById(R.id.vpn_state);
+ stateBaseColor = mStateView.getCurrentTextColor();
+ mProfileView = (TextView)view.findViewById(R.id.vpn_profile_label);
+ mProfileNameView = (TextView)view.findViewById(R.id.vpn_profile_name);
+
return view;
}
+ @Override
+ public void onStart()
+ {
+ super.onStart();
+ if (mService != null)
+ {
+ updateView();
+ }
+ }
+
@Override
public void onStop()
{
super.onStop();
+ hideProgressDialog();
}
@Override
@@ -89,5 +120,103 @@ public class VpnStateFragment extends Fragment implements VpnStateListener
@Override
public void stateChanged()
{
+ updateView();
+ }
+
+ public void updateView()
+ {
+ State state = mService.getState();
+ String name = "", gateway = "";
+
+ if (state != State.DISABLED)
+ {
+ VpnProfile profile = mService.getProfile();
+ if (profile != null)
+ {
+ name = profile.getName();
+ gateway = profile.getGateway();
+ }
+ }
+
+ if (state == mState)
+ { /* avoid unnecessary updates */
+ return;
+ }
+
+ hideProgressDialog();
+ mProfileNameView.setText(name);
+ mState = state;
+
+ switch (state)
+ {
+ case DISABLED:
+ showProfile(false);
+ mStateView.setText(R.string.state_disabled);
+ mStateView.setTextColor(stateBaseColor);
+ break;
+ case CONNECTING:
+ showProfile(true);
+ showConnectDialog(name, gateway);
+ mStateView.setText(R.string.state_connecting);
+ mStateView.setTextColor(stateBaseColor);
+ break;
+ case CONNECTED:
+ showProfile(true);
+ mStateView.setText(R.string.state_connected);
+ mStateView.setTextColor(Color.GREEN);
+ break;
+ case DISCONNECTING:
+ showProfile(true);
+ showDisconnectDialog(name);
+ mStateView.setText(R.string.state_disconnecting);
+ mStateView.setTextColor(stateBaseColor);
+ break;
+ }
+ }
+
+ private void showProfile(boolean show)
+ {
+ mProfileView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mProfileNameView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+
+ private void hideProgressDialog()
+ {
+ if (mProgressDialog != null)
+ {
+ mProgressDialog.dismiss();
+ mProgressDialog = null;
+ }
+ }
+
+ private void showConnectDialog(String profile, String gateway)
+ {
+ mProgressDialog = new ProgressDialog(getActivity());
+ mProgressDialog.setTitle(String.format(getString(R.string.connecting_title), profile));
+ mProgressDialog.setMessage(String.format(getString(R.string.connecting_message), gateway));
+ mProgressDialog.setIndeterminate(true);
+ mProgressDialog.setCancelable(false);
+ mProgressDialog.setButton(getString(android.R.string.cancel),
+ new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ if (mService != null)
+ {
+ mService.disconnect();
+ }
+ }
+ });
+ mProgressDialog.show();
+ }
+
+ private void showDisconnectDialog(String profile)
+ {
+ mProgressDialog = new ProgressDialog(getActivity());
+ mProgressDialog.setMessage(getString(R.string.state_disconnecting));
+ mProgressDialog.setIndeterminate(true);
+ mProgressDialog.setCancelable(false);
+ mProgressDialog.show();
}
}