From 1df79a1ff67a3388a26e9acd62c97639abbdc267 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Mon, 25 Apr 2016 23:31:34 +0300 Subject: Implement quick settings tile --- build.gradle | 2 +- main/build.gradle | 5 +- main/src/main/AndroidManifest.xml | 10 ++ .../java/de/blinkt/openvpn/OpenVPNTileService.java | 139 +++++++++++++++++++++ .../de/blinkt/openvpn/core/OpenVPNService.java | 14 +++ .../java/de/blinkt/openvpn/core/VpnStatus.java | 3 + main/src/main/res/values/strings.xml | 3 + 7 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java 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 @@ + + + + + + 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 @@ Samsung phones No VPN selected. VPN used on boot and for Always-On + Toggle VPN + Connect to %s + Disconnect %s -- cgit v1.2.3