diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2012-05-03 22:51:47 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2012-05-03 22:51:47 +0200 | 
| commit | 2b3ea917b0a830e3ff4817c7240e0f1808ae58bc (patch) | |
| tree | 2359f4fca5e51d2b7eb253728f62b74db7da0e69 /src | |
| parent | 9cd2069d5d57fc605a8eae3e6f8a0b09b56d4c16 (diff) | |
| parent | d3c50d3637462d4e3e3a3c09d43d37ce5656f67a (diff) | |
Merge Merge try number 2
Diffstat (limited to 'src')
| -rw-r--r-- | src/de/blinkt/openvpn/LaunchVPN.java | 252 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 3 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 21 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 19 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/Settings_Obscure.java | 6 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VPNProfileList.java | 191 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 9 | 
7 files changed, 308 insertions, 193 deletions
| diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java index caeedc09..7a034e4c 100644 --- a/src/de/blinkt/openvpn/LaunchVPN.java +++ b/src/de/blinkt/openvpn/LaunchVPN.java @@ -22,6 +22,7 @@ import java.util.Vector;  import android.app.Activity;  import android.app.AlertDialog;  import android.app.ListActivity; +import android.content.ActivityNotFoundException;  import android.content.DialogInterface;  import android.content.Intent;  import android.net.VpnService; @@ -70,27 +71,27 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  	private ProfileManager mPM;  	private VpnProfile mSelectedProfile; -    @Override -    public void onCreate(Bundle icicle) { -        super.onCreate(icicle); +	@Override +	public void onCreate(Bundle icicle) { +		super.onCreate(icicle); + +		// Resolve the intent + +		final Intent intent = getIntent(); +		final String action = intent.getAction(); -        // Resolve the intent +		mPM =ProfileManager.getInstance(); +		if(mPM.getNumberOfProfiles() == 0) { +			mPM.loadVPNList(this); +		} -        final Intent intent = getIntent(); -        final String action = intent.getAction(); -         -        mPM =ProfileManager.getInstance(); -        if(mPM.getNumberOfProfiles() == 0) { -        	mPM.loadVPNList(this); -        } -         -        // If the intent is a request to create a shortcut, we'll do that and exit +		// If the intent is a request to create a shortcut, we'll do that and exit  		if(Intent.ACTION_MAIN.equals(action)) {  			// we got called to be the starting point, most likely a shortcut  			String shortcutUUID = intent.getStringExtra( EXTRA_KEY); -			 +  			VpnProfile profileToConnect = ProfileManager.get(shortcutUUID);  			if(profileToConnect ==null) {  				Toast notfound = Toast.makeText(this, R.string.shortcut_profile_notfound, Toast.LENGTH_SHORT); @@ -98,111 +99,111 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  				finish();  				return;  			} -			 +  			mSelectedProfile = profileToConnect;  			launchVPN(); -			 -			 -			 + + +  		} else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {  			createListView();  		} -		 -           -         -         -		   -		   - -    } - -    private void createListView() { -        ListView lv = getListView(); -		  //lv.setTextFilterEnabled(true); -         -        Collection<VpnProfile> vpnlist = mPM.getProfiles(); -         -        Vector<String> vpnnames=new Vector<String>(); -        for (VpnProfile vpnProfile : vpnlist) { -        	vpnnames.add(vpnProfile.mName); + + + + + + + +	} + +	private void createListView() { +		ListView lv = getListView(); +		//lv.setTextFilterEnabled(true); + +		Collection<VpnProfile> vpnlist = mPM.getProfiles(); + +		Vector<String> vpnnames=new Vector<String>(); +		for (VpnProfile vpnProfile : vpnlist) { +			vpnnames.add(vpnProfile.mName);  		} -         -         -         -		  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,vpnnames); -		  lv.setAdapter(adapter); -         -		  lv.setOnItemClickListener(this); + + + +		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,vpnnames); +		lv.setAdapter(adapter); + +		lv.setOnItemClickListener(this);  	}  	/** -     * This function creates a shortcut and returns it to the caller.  There are actually two  -     * intents that you will send back. -     *  -     * The first intent serves as a container for the shortcut and is returned to the launcher by  -     * setResult().  This intent must contain three fields: -     *  -     * <ul> -     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li> -     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with -     * the shortcut.</li> -     * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a -     * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as -     * a drawable resource.</li> -     * </ul> -     *  -     * If you use a simple drawable resource, note that you must wrapper it using -     * {@link android.content.Intent.ShortcutIconResource}, as shown below.  This is required so -     * that the launcher can access resources that are stored in your application's .apk file.  If  -     * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras  -     * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. -     *  -     * The shortcut intent can be any intent that you wish the launcher to send, when the user  -     * clicks on the shortcut.  Typically this will be {@link android.content.Intent#ACTION_VIEW}  -     * with an appropriate Uri for your content, but any Intent will work here as long as it  -     * triggers the desired action within your Activity. -     * @param profile  -     */ -    private void setupShortcut(VpnProfile profile) { -        // First, set up the shortcut intent.  For this example, we simply create an intent that -        // will bring us directly back to this activity.  A more typical implementation would use a  -        // data Uri in order to display a more specific result, or a custom action in order to  -        // launch a specific operation. - -        Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); -        shortcutIntent.setClass(this, LaunchVPN.class); -        shortcutIntent.putExtra(EXTRA_KEY,profile.getUUID().toString()); - -        // Then, set up the container intent (the response to the caller) - -        Intent intent = new Intent(); -        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); -        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); -        Parcelable iconResource = Intent.ShortcutIconResource.fromContext( -                this,  R.drawable.icon); -        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - -        // Now, return the result to the launcher - -        setResult(RESULT_OK, intent); -    } -     +	 * This function creates a shortcut and returns it to the caller.  There are actually two  +	 * intents that you will send back. +	 *  +	 * The first intent serves as a container for the shortcut and is returned to the launcher by  +	 * setResult().  This intent must contain three fields: +	 *  +	 * <ul> +	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li> +	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with +	 * the shortcut.</li> +	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a +	 * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as +	 * a drawable resource.</li> +	 * </ul> +	 *  +	 * If you use a simple drawable resource, note that you must wrapper it using +	 * {@link android.content.Intent.ShortcutIconResource}, as shown below.  This is required so +	 * that the launcher can access resources that are stored in your application's .apk file.  If  +	 * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras  +	 * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. +	 *  +	 * The shortcut intent can be any intent that you wish the launcher to send, when the user  +	 * clicks on the shortcut.  Typically this will be {@link android.content.Intent#ACTION_VIEW}  +	 * with an appropriate Uri for your content, but any Intent will work here as long as it  +	 * triggers the desired action within your Activity. +	 * @param profile  +	 */ +	private void setupShortcut(VpnProfile profile) { +		// First, set up the shortcut intent.  For this example, we simply create an intent that +		// will bring us directly back to this activity.  A more typical implementation would use a  +		// data Uri in order to display a more specific result, or a custom action in order to  +		// launch a specific operation. + +		Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); +		shortcutIntent.setClass(this, LaunchVPN.class); +		shortcutIntent.putExtra(EXTRA_KEY,profile.getUUID().toString()); + +		// Then, set up the container intent (the response to the caller) + +		Intent intent = new Intent(); +		intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); +		intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); +		Parcelable iconResource = Intent.ShortcutIconResource.fromContext( +				this,  R.drawable.icon); +		intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); + +		// Now, return the result to the launcher + +		setResult(RESULT_OK, intent); +	} +  	@Override  	public void onItemClick(AdapterView<?> parent, View view, int position,  			long id) { -		 String profilename = ((TextView) view).getText().toString(); -		  -		 VpnProfile profile = mPM.getProfileByName(profilename); - -	      // if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {	 -	            setupShortcut(profile); -	            finish(); -	            return; -	    //    } -		  +		String profilename = ((TextView) view).getText().toString(); + +		VpnProfile profile = mPM.getProfileByName(profilename); + +		// if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {	 +		setupShortcut(profile); +		finish(); +		return; +		//    } +  	} -	 +  	private void askForPW(final String type) {  		final EditText entry = new EditText(this); @@ -243,16 +244,21 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  	@Override  	protected void onActivityResult(int requestCode, int resultCode, Intent data) {  		super.onActivityResult(requestCode, resultCode, data); -		 -		if(requestCode==START_VPN_PROFILE && resultCode == Activity.RESULT_OK) { -			 -			if(mSelectedProfile.needUserPWInput()!=null) { -				askForPW(mSelectedProfile.needUserPWInput()); -			} else { -				new startOpenVpnThread().start(); -			} -		}  +		if(requestCode==START_VPN_PROFILE) { +			if(resultCode == Activity.RESULT_OK) { + +				if(mSelectedProfile.needUserPWInput()!=null) { +					askForPW(mSelectedProfile.needUserPWInput()); +				} else { +					new startOpenVpnThread().start(); +				} + +			} else if (resultCode == Activity.RESULT_CANCELED) { +				// User does want us to start, so we just vanish +				finish(); +			} +		}  	}  	void showConfigErrorDialog(int vpnok) { @@ -262,10 +268,10 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  		d.setPositiveButton(android.R.string.ok, null);  		d.show();  	} -	 +  	void launchVPN () { -		 -		 + +  		int vpnok = mSelectedProfile.checkProfile();  		if(vpnok!= R.string.no_error_found) {  			showConfigErrorDialog(vpnok); @@ -276,13 +282,17 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  		if (intent != null) {  			// Start the query -			startActivityForResult(intent, START_VPN_PROFILE); +			try { +				startActivityForResult(intent, START_VPN_PROFILE); +			} catch (ActivityNotFoundException ane){ +				Toast.makeText(this, "Your image does not support the VPNService API,sorry :(", Toast.LENGTH_LONG); +			}  		} else {  			onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);  		} -		 +  	} -	 +  	private class startOpenVpnThread extends Thread {  		@Override @@ -305,5 +315,5 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {  		}  	} -	 +  } diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index ea6c4926..86bd3665 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -100,8 +100,7 @@ public class OpenVPN {  	public static int openTunDevice() {  		Log.d(TAG,"Opening tun device"); -		ParcelFileDescriptor pfd = mOpenVpnService.openTun(); -		return pfd.detachFd(); +		return mOpenVpnService.openTun();  	}  	//! Dummy method being called to force loading of JNI Libraries  	public static void foo() {	} diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index 02e5dc46..19f8d7e5 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -1,10 +1,13 @@  package de.blinkt.openvpn;
 +import java.io.FileDescriptor;
  import java.io.IOException;
  import java.io.InputStream;
 +import java.net.DatagramSocket;
  import java.util.Vector;
  import android.net.LocalSocket;
 +import android.os.ParcelFileDescriptor;
  import android.util.Log;
  public class OpenVpnManagementThread implements Runnable {
 @@ -12,11 +15,14 @@ public class OpenVpnManagementThread implements Runnable {  	private static final String TAG = "openvpn";
  	private LocalSocket mSocket;
  	private VpnProfile mProfile;
 +	private OpenVpnService mOpenVPNService;
 +	
  private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
 -	public OpenVpnManagementThread(VpnProfile profile, LocalSocket mgmtsocket) {
 +	public OpenVpnManagementThread(VpnProfile profile, LocalSocket mgmtsocket, OpenVpnService openVpnService) {
  		mProfile = profile;
  		mSocket = mgmtsocket;
 +		mOpenVPNService = openVpnService;
  	}
 @@ -102,6 +108,8 @@ private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManageme  				processPWCommand(argument);
  			} else if (cmd.equals("HOLD")) {
  				managmentCommand("hold release\n");
 +			} else if (cmd.equals("PROTECT-FD")) {
 +				protectFD(argument);
  			}
  		}
          Log.i(TAG, "Got unrecognized command" + command);
 @@ -109,6 +117,17 @@ private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManageme  	}
 +	private void protectFD(String argument) {
 +		try {
 +			FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
 +			
 +		} catch (IOException e) {
 +			e.printStackTrace();
 +		}
 +
 +	}
 +
 +
  	private void processPWCommand(String argument) {
  		//argument has the form 	Need 'Private Key' password
  		int p1 =argument.indexOf('\'');
 diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index 442fd94c..076fe7b5 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -33,8 +33,6 @@ public class OpenVpnService extends VpnService implements Handler.Callback {  	Handler mHandler;  	private Thread mServiceThread; -	private ParcelFileDescriptor mInterface; -  	private Vector<String> mDnslist=new Vector<String>();  	private VpnProfile mProfile; @@ -159,12 +157,12 @@ public class OpenVpnService extends VpnService implements Handler.Callback {  		if(mgmtsocket!=null) {  			// start a Thread that handles incoming messages of the managment socket -			mSocketManager = new OpenVpnManagementThread(mProfile,mgmtsocket); +			mSocketManager = new OpenVpnManagementThread(mProfile,mgmtsocket,this);  			mSocketManagerThread = new Thread(mSocketManager,"OpenVPNMgmtThread");  			mSocketManagerThread.start();  		} -		return START_STICKY; +		return START_NOT_STICKY;  	} @@ -191,7 +189,7 @@ public class OpenVpnService extends VpnService implements Handler.Callback { -	public ParcelFileDescriptor openTun() { +	public int openTun() {  		Builder builder = new Builder();  		builder.addAddress(mLocalIP.mIp, mLocalIP.len); @@ -223,8 +221,15 @@ public class OpenVpnService extends VpnService implements Handler.Callback {  		Intent intent = new Intent(getBaseContext(),LogWindow.class);  		PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);  		builder.setConfigureIntent(startLW); -		mInterface = builder.establish(); -		return mInterface; +		try { +			ParcelFileDescriptor pfd = builder.establish(); +			return pfd.detachFd(); +		} catch (Exception e) { +			OpenVPN.logMessage(0, "", getString(R.string.tun_open_error)); +			OpenVPN.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage()); +			OpenVPN.logMessage(0, "", getString(R.string.tun_error_helpful)); +			return -1; +		}  	} diff --git a/src/de/blinkt/openvpn/Settings_Obscure.java b/src/de/blinkt/openvpn/Settings_Obscure.java index d7bce9ad..65d1c400 100644 --- a/src/de/blinkt/openvpn/Settings_Obscure.java +++ b/src/de/blinkt/openvpn/Settings_Obscure.java @@ -63,12 +63,14 @@ public class Settings_Obscure extends PreferenceFragment implements OnPreference  		mProfile.mVerb = mLogverbosity.getValue();  	} +	  	@Override  	public boolean onPreferenceChange(Preference preference, Object newValue) {  		if(preference==mLogverbosity) {  			mLogverbosity.setDefaultValue(newValue); -			// Does not refresh otherwise -			mLogverbosity.setSummary("%s"); +			//This is idiotic.  +			int i =Integer.parseInt((String) newValue); +			mLogverbosity.setSummary(mLogverbosity.getEntries()[i]);  		}  		return true; diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java index 58c9237a..c9ff9805 100644 --- a/src/de/blinkt/openvpn/VPNProfileList.java +++ b/src/de/blinkt/openvpn/VPNProfileList.java @@ -2,38 +2,90 @@ package de.blinkt.openvpn;  import android.app.Activity;  import android.app.AlertDialog; +import android.app.ListFragment;  import android.content.Context;  import android.content.DialogInterface;  import android.content.Intent;  import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; +import android.view.ActionMode;  import android.view.Menu;  import android.view.MenuInflater;  import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.ArrayAdapter;  import android.widget.EditText; +import android.widget.ListView;  import android.widget.Toast; -import de.blinkt.openvpn.VPNConfigPreference.VpnPreferencesClickListener; -public class VPNProfileList extends PreferenceFragment implements  VpnPreferencesClickListener { +public class VPNProfileList extends ListFragment {  	private static final int MENU_ADD_PROFILE = Menu.FIRST;  	private static final int START_VPN_CONFIG = 92; -	private VpnProfile mSelectedVPN; +	private ArrayAdapter<VpnProfile> mArrayadapter; +	protected Object mActionMode; + +	protected VpnProfile mEditProfile=null; + +	 +	  	@Override  	public void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState); -		addPreferencesFromResource(R.xml.vpn_profile_list);  		setHasOptionsMenu(true); -		refreshList();  		// Debug load JNI  		//OpenVPN.foo();  	} +	@Override +	public void onActivityCreated(Bundle savedInstanceState) { +		super.onActivityCreated(savedInstanceState); +		ListView lv = getListView(); +		lv.setOnItemLongClickListener(new OnItemLongClickListener() { + +			// Called when the user long-clicks on someView + +			@Override +			public boolean onItemLongClick(AdapterView<?> parent, View view, +					int position, long id) { +		        if (mActionMode != null) { +		            return false; +		        } + +		        // Start the CAB using the ActionMode.Callback defined above +		        mActionMode = getActivity().startActionMode(mActionModeCallback); +				mEditProfile =(VpnProfile) getListAdapter().getItem(position); + +				//getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); +		        //getListView().setSelection(position); +		        return true; +			} +		}); +		 +		lv.setOnItemClickListener(new OnItemClickListener() { + +			@Override +			public void onItemClick(AdapterView<?> parent, View view, +					int position, long id) { +				VpnProfile profile =(VpnProfile) getListAdapter().getItem(position); +				startVPN(profile); +			} +		}); +		 + +        if(getPM().getNumberOfProfiles() == 0) { +        	getPM().loadVPNList(getActivity()); +        } +		 +		mArrayadapter = new ArrayAdapter<VpnProfile>(getActivity(),android.R.layout.simple_list_item_activated_1); +		mArrayadapter.addAll(getPM().getProfiles()); +		setListAdapter(mArrayadapter); +	}  	@Override  	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { @@ -56,7 +108,27 @@ public class VPNProfileList extends PreferenceFragment implements  VpnPreference  		}  	} +	private void askProfileRemoval() { +		AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); +		dialog.setTitle("Confirm deletion"); +		dialog.setMessage(getString(R.string.remove_vpn_query, mEditProfile.mName)); + +		dialog.setPositiveButton(android.R.string.yes, +				new DialogInterface.OnClickListener() { +			@Override +			public void onClick(DialogInterface dialog, int which) { +				removeProfile(mEditProfile); +			} + +		}); +		dialog.setNegativeButton(android.R.string.no,null); +		dialog.create().show(); +	} +	protected void removeProfile(VpnProfile profile) { +		mArrayadapter.remove(profile); +		 +	}  	private void onAddProfileClicked() {  		Context context = getActivity(); @@ -78,7 +150,6 @@ public class VPNProfileList extends PreferenceFragment implements  VpnPreference  					if (getPM().getProfileByName(name)==null) {  						VpnProfile profile = new VpnProfile(name);  						addProfile(profile); -						refreshList();  					} else {  						Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show();  					} @@ -102,58 +173,17 @@ public class VPNProfileList extends PreferenceFragment implements  VpnPreference  		getPM().addProfile(profile);  		getPM().saveProfileList(getActivity());  		getPM().saveProfile(getActivity(),profile); - +		mArrayadapter.add(profile);  	} -	public void refreshList() { -		PreferenceScreen plist = getPreferenceScreen(); -		if (plist != null) { -			plist.removeAll();  -			getPM().loadVPNList(getActivity()); - -			for (VpnProfile vpnprofile: getPM().getProfiles()) { - -				String profileuuid = vpnprofile.getUUID().toString(); - - -				VPNConfigPreference vpref = new VPNConfigPreference(this); -				vpref.setKey(profileuuid); -				vpref.setTitle(vpnprofile.getName()); -				vpref.setPersistent(false); -				vpref.setOnQuickSettingsClickListener(this); -				plist.addPreference(vpref); -			} - - -		} -	} - - -  	private ProfileManager getPM() {  		return ProfileManager.getInstance();  	} -	@Override -	public boolean onQuickSettingsClick(Preference preference) { -		String key = preference.getKey(); - -		VpnProfile vprofile = ProfileManager.get(key); - -		Intent vprefintent = new Intent(getActivity(),VPNPreferences.class) -		.putExtra(getActivity().getPackageName() + ".profileUUID", vprofile.getUUID().toString()); - -		startActivityForResult(vprefintent,START_VPN_CONFIG); -		return true; -	} - - - -  	@Override  	public void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -164,26 +194,69 @@ public class VPNProfileList extends PreferenceFragment implements  VpnPreference  			VpnProfile profile = ProfileManager.get(configuredVPN);  			getPM().saveProfile(getActivity(), profile);  			// Name could be modified -			refreshList(); +  		}  	} +	private void editVPN(VpnProfile profile) { -	@Override -	public void onStartVPNClick(VPNConfigPreference preference) { -		getPM(); -		// Query the System for permission  -		mSelectedVPN = ProfileManager.get(preference.getKey()); +		Intent vprefintent = new Intent(getActivity(),VPNPreferences.class) +		.putExtra(getActivity().getPackageName() + ".profileUUID", profile.getUUID().toString()); -		getPM().saveProfile(getActivity(), mSelectedVPN); +		startActivityForResult(vprefintent,START_VPN_CONFIG); +	} + +	private void startVPN(VpnProfile profile) { + +		getPM().saveProfile(getActivity(), profile);  		Intent intent = new Intent(getActivity(),LaunchVPN.class); -		intent.putExtra(LaunchVPN.EXTRA_KEY, mSelectedVPN.getUUID().toString()); +		intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString());  		intent.setAction(Intent.ACTION_MAIN);  		startActivity(intent);  		getActivity().finish();  	} + +	private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { +		@Override +		public boolean onCreateActionMode(ActionMode mode, Menu menu) { +			MenuInflater inflater = mode.getMenuInflater(); +			inflater.inflate(R.menu.vpn_context, menu); +			return true; +		} + +		@Override +		public boolean onPrepareActionMode(ActionMode mode, Menu menu) { +			return false;// Return false if nothing is done +		} + +		@Override +		public boolean onActionItemClicked(ActionMode mode, MenuItem item) { +		      switch (item.getItemId()) { +	            case R.id.remove_vpn: +	                askProfileRemoval(); +	                mode.finish(); // Action picked, so close the CAB +	                return true; +	            case R.id.connect_vpn: +	            	startVPN(mEditProfile); +	            	mode.finish(); +	            	return true; +	            case R.id.edit_vpn: +	            	editVPN(mEditProfile); +	            	mode.finish(); +	            	return true; +	            default: +	                return false; +	        }		} + +		@Override +		public void onDestroyActionMode(ActionMode mode) { +	        mActionMode = null; +	        getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); +		} +	}; +  } diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 683ba663..18fe59d5 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -422,7 +422,7 @@ public class VpnProfile implements  Serializable{  		return intent;  	} -	public String getTemporaryPKCS12Password() { +	private String getTemporaryPKCS12Password() {  		if(mTempPKCS12Password!=null)  			return mTempPKCS12Password; @@ -550,6 +550,13 @@ public class VpnProfile implements  Serializable{  			return mPassword;  		}  	} +	 +	 +	// Used by the Array Adapter +	@Override +	public String toString() { +		return mName; +	} | 
