diff options
-rw-r--r-- | build.gradle | 2 | ||||
-rw-r--r-- | main/build.gradle | 5 | ||||
-rw-r--r-- | main/src/main/AndroidManifest.xml | 10 | ||||
-rw-r--r-- | main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java | 139 | ||||
-rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java | 14 | ||||
-rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java | 3 | ||||
-rwxr-xr-x | main/src/main/res/values/strings.xml | 3 |
7 files changed, 173 insertions, 3 deletions
diff --git a/build.gradle b/build.gradle index 644795c2..ca6943d4 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0-alpha5' + classpath 'com.android.tools.build:gradle:2.1.0-rc1' } } diff --git a/main/build.gradle b/main/build.gradle index 43204e17..41cf114f 100644 --- a/main/build.gradle +++ b/main/build.gradle @@ -22,11 +22,12 @@ dependencies { android { compileSdkVersion 23 - buildToolsVersion '23.0.2' + compileSdkVersion 'android-N' + buildToolsVersion '24.0.0-rc1' defaultConfig { minSdkVersion 14 - targetSdkVersion 23 + targetSdkVersion 'N' versionCode = 132 versionName = "0.6.52" } diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index 08ed2388..dbc44a68 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -82,6 +82,16 @@ </intent-filter> </service> + <service + android:name=".OpenVPNTileService" + android:label="@string/qs_title" + android:icon="@drawable/icon" + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> + <intent-filter> + <action android:name="android.service.quicksettings.action.QS_TILE" /> + </intent-filter> + </service> + <activity android:name=".api.GrantPermissionsActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java new file mode 100644 index 00000000..244eb62c --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Build; +import android.os.IBinder; +import android.service.quicksettings.Tile; +import android.service.quicksettings.TileService; +import android.widget.Toast; + +import java.util.Locale; + +import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.OpenVPNService; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus; + + +/** + * Created by arne on 22.04.16. + */ +@TargetApi(Build.VERSION_CODES.N) +public class OpenVPNTileService extends TileService implements VpnStatus.StateListener { + + @SuppressLint("Override") + @TargetApi(Build.VERSION_CODES.N) + @Override + public void onClick() { + super.onClick(); + final VpnProfile bootProfile = getQSVPN(); + if (bootProfile == null) { + Toast.makeText(this, R.string.novpn_selected, Toast.LENGTH_SHORT).show(); + } else { + if (!isLocked()) + clickAction(bootProfile); + else + unlockAndRun(new Runnable() { + @Override + public void run() { + clickAction(bootProfile); + } + }); + } + } + + private void clickAction(VpnProfile bootProfile) { + if (VpnStatus.isVPNActive()) { + Intent intent = new Intent(this, OpenVPNService.class); + intent.setAction(OpenVPNService.START_SERVICE); + bindService(intent, new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder binder) { + OpenVPNService service = ((OpenVPNService.LocalBinder) binder).getService(); + + if (service != null && service.getManagement() != null) + service.getManagement().stopVPN(false); + + unbindService(this); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + + } + }, Context.BIND_AUTO_CREATE); + } + else + launchVPN(bootProfile, this); + } + + + @SuppressLint("Override") + @TargetApi(Build.VERSION_CODES.N) + void launchVPN(VpnProfile profile, Context context) { + Intent startVpnIntent = new Intent(Intent.ACTION_MAIN); + startVpnIntent.setClass(context, LaunchVPN.class); + startVpnIntent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); + startVpnIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startVpnIntent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); + + context.startActivity(startVpnIntent); + } + + @SuppressLint("Override") + @TargetApi(Build.VERSION_CODES.N) + @Override + public int onTileAdded() { + return TILE_MODE_ACTIVE; + } + + @Override + public void onStartListening() { + super.onStartListening(); + VpnStatus.addStateListener(this); + } + + + @TargetApi(Build.VERSION_CODES.N) + public VpnProfile getQSVPN() { + return ProfileManager.getAlwaysOnVPN(this); + } + + @Override + public void updateState(String state, String logmessage, int localizedResId, VpnStatus.ConnectionStatus level) { + VpnProfile vpn; + Tile t = getQsTile(); + if (level == VpnStatus.ConnectionStatus.LEVEL_AUTH_FAILED || level == VpnStatus.ConnectionStatus.LEVEL_NOTCONNECTED) { + // No VPN connected, use stadnard VPN + vpn = getQSVPN(); + if (vpn == null) { + t.setLabel(getString(R.string.novpn_selected)); + t.setState(Tile.STATE_UNAVAILABLE); + } else { + t.setLabel(getString(R.string.qs_connect, vpn.getName())); + t.setState(Tile.STATE_INACTIVE); + } + } else { + vpn = ProfileManager.getLastConnectedVpn(); + t.setLabel(getString(R.string.qs_disconnect, vpn.getName())); + t.setState(Tile.STATE_ACTIVE); + } + t.updateTile(); + } + + @Override + public void onStopListening() { + VpnStatus.removeStateListener(this); + super.onStopListening(); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index abb8c270..025ba786 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -11,6 +11,7 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.UiModeManager; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -27,6 +28,7 @@ import android.os.IBinder; import android.os.Message; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; +import android.service.quicksettings.TileService; import android.system.OsConstants; import android.text.TextUtils; import android.util.Log; @@ -44,6 +46,7 @@ import java.util.Locale; import java.util.Vector; import de.blinkt.openvpn.BuildConfig; +import de.blinkt.openvpn.OpenVPNTileService; import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.activities.DisconnectVPN; @@ -926,6 +929,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if (mProcessThread == null && !mNotificationAlwaysVisible) return; + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) + tileUpdateN(); + + + boolean lowpriority = false; // Display byte count only after being connected @@ -954,6 +963,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } } + @TargetApi(Build.VERSION_CODES.N) + private void tileUpdateN() { + TileService.requestListeningState(this, new ComponentName(this, OpenVPNTileService.class)); + } + private void doSendBroadcast(String state, ConnectionStatus level) { Intent vpnstatus = new Intent(); vpnstatus.setAction("de.blinkt.openvpn.VPN_STATUS"); diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index d23f0013..8b076437 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -59,6 +59,9 @@ public class VpnStatus { static final int MAXLOGENTRIES = 1000; + public static boolean isVPNActive() { + return mLastLevel != ConnectionStatus.LEVEL_AUTH_FAILED && !(mLastLevel == ConnectionStatus.LEVEL_NOTCONNECTED); + } public static String getLastCleanLogMessage(Context c) { String message = mLaststatemsg; diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index f68832e9..ae28cabc 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -409,4 +409,7 @@ <string name="samsung_broken_title">Samsung phones</string> <string name="novpn_selected">No VPN selected.</string> <string name="alwaysonvpn">VPN used on boot and for Always-On</string> + <string name="qs_title">Toggle VPN</string> + <string name="qs_connect">Connect to %s</string> + <string name="qs_disconnect">Disconnect %s</string> </resources> |