From 1f1dae89983ed10b7913638e2153d4d3bcb3ac75 Mon Sep 17 00:00:00 2001 From: Ted Romer Date: Fri, 26 Sep 2025 02:22:57 -0700 Subject: Add setDefaultProfile and getDefaultProfile methods to API. Also: * add corresponding setDefaultVPN intent * add sample usage to remoteExample * bring remoteExample/.../IOpenVPNAPIService.aidl into sync with main/... * make APIVpnProfile.java in remoteExample/ and main/ identical. --- .../de/blinkt/openvpn/api/IOpenVPNAPIService.aidl | 22 ++++++++++++++++------ .../java/de/blinkt/openvpn/api/APIVpnProfile.java | 6 ++++-- .../de/blinkt/openvpn/remote/MainFragment.java | 21 ++++++++++++++++++++- .../src/main/res/layout/fragment_main.xml | 8 ++++++++ remoteExample/src/main/res/values/strings.xml | 1 + 5 files changed, 49 insertions(+), 9 deletions(-) (limited to 'remoteExample/src/main') diff --git a/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl index 1989b771..5e259d29 100644 --- a/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl +++ b/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl @@ -18,14 +18,14 @@ interface IOpenVPNAPIService { boolean addVPNProfile (String name, String config); /** start a profile using a config as inline string. Make sure that all needed data is inlined, - * e.g., using ... or ... + * e.g., using ... or ... * See the OpenVPN manual page for more on inlining files */ - void startVPN (String inlineconfig); + void startVPN (in String inlineconfig); /** This permission framework is used to avoid confused deputy style attack to the VPN * calling this will give null if the app is allowed to use the external API and an Intent * that can be launched to request permissions otherwise */ - Intent prepare (String packagename); + Intent prepare (in String packagename); /** Used to trigger to the Android VPN permission dialog (VPNService.prepare()) in advance, * if this return null OpenVPN for ANdroid already has the permissions otherwise you can start the returned Intent @@ -44,15 +44,15 @@ interface IOpenVPNAPIService { /** * Registers to receive OpenVPN Status Updates */ - void registerStatusCallback(IOpenVPNStatusCallback cb); + void registerStatusCallback(in IOpenVPNStatusCallback cb); /** * Remove a previously registered callback interface. */ - void unregisterStatusCallback(IOpenVPNStatusCallback cb); + void unregisterStatusCallback(in IOpenVPNStatusCallback cb); /** Remove a profile by UUID */ - void removeProfile (String profileUUID); + void removeProfile (in String profileUUID); /** Request a socket to be protected as a VPN socket would be. Useful for creating * a helper socket for an app controlling OpenVPN @@ -64,9 +64,19 @@ interface IOpenVPNAPIService { /** Use a profile with all certificates etc. embedded */ APIVpnProfile addNewVPNProfile (String name, boolean userEditable, String config); + /** Same as startVPN(String), but also takes a Bundle with extra parameters, + * which will be applied to the created VPNProfile (e.g. allow vpn bypass). */ + void startVPNwithExtras(in String inlineconfig, in Bundle extras); + /** Same as addNewVPNProfile(String, boolean, String) but giving possibility to pass a Bundle like * in startVPNwithExtras(String, Bundle) to apply e.g. "allow vpn bypass" to profile. * up to now the only extra that can be put is a boolean "de.blinkt.openvpn.api.ALLOW_VPN_BYPASS" */ APIVpnProfile addNewVPNProfileWithExtras (String name, boolean userEditable, String config, in Bundle extras); + + /** Get the current default profile, or null if there is no default */ + @nullable APIVpnProfile getDefaultProfile(); + + /** Set the default profile by UUID */ + void setDefaultProfile (String profileUUID); } \ No newline at end of file diff --git a/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java b/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java index 65c6ad57..cf310dbc 100644 --- a/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java +++ b/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java @@ -1,6 +1,8 @@ /* - * Copyright (c) 2012-2015 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + * Copyright (c) 2012-2016 Arne Schwabe + * This file is used for implementing the external API and this file like the AIDL and is exempted + * from the GPLv2. + * */ package de.blinkt.openvpn.api; diff --git a/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java b/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java index d98fdedd..c4e92f27 100644 --- a/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java +++ b/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java @@ -52,6 +52,7 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_main, container, false); v.findViewById(R.id.disconnect).setOnClickListener(this); + v.findViewById(R.id.setDefaultProfile).setOnClickListener(this); v.findViewById(R.id.getMyIP).setOnClickListener(this); v.findViewById(R.id.startembedded).setOnClickListener(this); v.findViewById(R.id.addNewProfile).setOnClickListener(this); @@ -70,6 +71,7 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand private static final int MSG_UPDATE_MYIP = 1; private static final int START_PROFILE_EMBEDDED = 2; private static final int START_PROFILE_BYUUID = 3; + private static final int SET_DEFAULT_PROFILE_BYUUID = 4; private static final int ICS_OPENVPN_PERMISSION = 7; private static final int PROFILE_ADD_NEW = 8; private static final int PROFILE_ADD_NEW_EDIT = 9; @@ -195,9 +197,12 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand try { List list = mService.getProfiles(); + APIVpnProfile defaultProfile = mService.getDefaultProfile(); + String defaultUUID = defaultProfile != null ? defaultProfile.mUUID : null; String all="List:"; for(APIVpnProfile vp:list.subList(0, Math.min(5, list.size()))) { - all = all + vp.mName + ":" + vp.mUUID + "\n"; + String suffix = (vp.mUUID.equals(defaultUUID)) ? " (default)" : ""; + all = all + vp.mName + ":" + vp.mUUID + suffix + "\n"; } if (list.size() > 5) @@ -253,6 +258,14 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand e.printStackTrace(); } break; + case R.id.setDefaultProfile: + try { + prepareStartProfile(SET_DEFAULT_PROFILE_BYUUID); + } catch (RemoteException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + break; case R.id.getMyIP: // Socket handling is not allowed on main thread @@ -317,6 +330,12 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand } catch (RemoteException e) { e.printStackTrace(); } + if(requestCode==SET_DEFAULT_PROFILE_BYUUID) + try { + mService.setDefaultProfile(mStartUUID); + } catch (RemoteException e) { + e.printStackTrace(); + } if (requestCode == ICS_OPENVPN_PERMISSION) { listVPNs(); try { diff --git a/remoteExample/src/main/res/layout/fragment_main.xml b/remoteExample/src/main/res/layout/fragment_main.xml index 6b8102e2..0780bba4 100644 --- a/remoteExample/src/main/res/layout/fragment_main.xml +++ b/remoteExample/src/main/res/layout/fragment_main.xml @@ -63,6 +63,14 @@ android:layout_toRightOf="@+id/startVPN" android:text="@string/disconnect" /> +