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 --- 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 + 6 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java (limited to 'main') 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 From d1bf5e72905f681281f6db13005107a31849cb3e Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sun, 22 May 2016 11:47:06 +0200 Subject: Make Tile work in passive mode which suits OpenVPN for Android well enough. --- main/src/main/AndroidManifest.xml | 3 +++ .../java/de/blinkt/openvpn/OpenVPNTileService.java | 18 +++++++++++------- .../java/de/blinkt/openvpn/core/OpenVPNService.java | 11 ----------- 3 files changed, 14 insertions(+), 18 deletions(-) (limited to 'main') diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index dbc44a68..53509ae4 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -84,12 +84,15 @@ + diff --git a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java index 244eb62c..7d954894 100644 --- a/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java +++ b/main/src/main/java/de/blinkt/openvpn/OpenVPNTileService.java @@ -59,7 +59,7 @@ public class OpenVPNTileService extends TileService implements VpnStatus.StateLi bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { - OpenVPNService service = ((OpenVPNService.LocalBinder) binder).getService(); + OpenVPNService service = ((OpenVPNService.LocalBinder) binder).getService(); if (service != null && service.getManagement() != null) service.getManagement().stopVPN(false); @@ -72,8 +72,7 @@ public class OpenVPNTileService extends TileService implements VpnStatus.StateLi } }, Context.BIND_AUTO_CREATE); - } - else + } else launchVPN(bootProfile, this); } @@ -90,11 +89,9 @@ public class OpenVPNTileService extends TileService implements VpnStatus.StateLi context.startActivity(startVpnIntent); } - @SuppressLint("Override") @TargetApi(Build.VERSION_CODES.N) @Override - public int onTileAdded() { - return TILE_MODE_ACTIVE; + public void onTileAdded() { } @Override @@ -125,9 +122,16 @@ public class OpenVPNTileService extends TileService implements VpnStatus.StateLi } } else { vpn = ProfileManager.getLastConnectedVpn(); - t.setLabel(getString(R.string.qs_disconnect, vpn.getName())); + String name; + if (vpn == null) + name = "null?!"; + else + name = vpn.getName(); + t.setLabel(getString(R.string.qs_disconnect, name)); t.setState(Tile.STATE_ACTIVE); } + + t.updateTile(); } 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 752fbb2a..321140fd 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -929,12 +929,6 @@ 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 @@ -963,11 +957,6 @@ 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"); -- cgit v1.2.3 From 9f06b49e156da1675979fd3da7ec1cf3af57f6d9 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sun, 22 May 2016 13:22:50 +0200 Subject: Add icon for Android N quicktile --- main/src/main/res/drawable-hdpi/ic_quick.png | Bin 0 -> 1236 bytes main/src/main/res/drawable-mdpi/ic_quick.png | Bin 0 -> 973 bytes main/src/main/res/drawable-xhdpi/ic_quick.png | Bin 0 -> 1671 bytes main/src/main/res/drawable-xxhdpi/ic_quick.png | Bin 0 -> 2375 bytes main/src/main/res/drawable-xxhdpi/icon.png | Bin 14248 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 main/src/main/res/drawable-hdpi/ic_quick.png create mode 100644 main/src/main/res/drawable-mdpi/ic_quick.png create mode 100644 main/src/main/res/drawable-xhdpi/ic_quick.png create mode 100644 main/src/main/res/drawable-xxhdpi/ic_quick.png delete mode 100644 main/src/main/res/drawable-xxhdpi/icon.png (limited to 'main') diff --git a/main/src/main/res/drawable-hdpi/ic_quick.png b/main/src/main/res/drawable-hdpi/ic_quick.png new file mode 100644 index 00000000..343d6c5a Binary files /dev/null and b/main/src/main/res/drawable-hdpi/ic_quick.png differ diff --git a/main/src/main/res/drawable-mdpi/ic_quick.png b/main/src/main/res/drawable-mdpi/ic_quick.png new file mode 100644 index 00000000..83285eeb Binary files /dev/null and b/main/src/main/res/drawable-mdpi/ic_quick.png differ diff --git a/main/src/main/res/drawable-xhdpi/ic_quick.png b/main/src/main/res/drawable-xhdpi/ic_quick.png new file mode 100644 index 00000000..70dc3593 Binary files /dev/null and b/main/src/main/res/drawable-xhdpi/ic_quick.png differ diff --git a/main/src/main/res/drawable-xxhdpi/ic_quick.png b/main/src/main/res/drawable-xxhdpi/ic_quick.png new file mode 100644 index 00000000..5adc85c1 Binary files /dev/null and b/main/src/main/res/drawable-xxhdpi/ic_quick.png differ diff --git a/main/src/main/res/drawable-xxhdpi/icon.png b/main/src/main/res/drawable-xxhdpi/icon.png deleted file mode 100644 index 16afb418..00000000 Binary files a/main/src/main/res/drawable-xxhdpi/icon.png and /dev/null differ -- cgit v1.2.3 From 840e8389b93e8687484f7e0cc9a4b267ae3048e0 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sun, 22 May 2016 13:35:50 +0200 Subject: Use the new icon in the quick tile. --- main/src/main/AndroidManifest.xml | 2 +- main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'main') diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index 53509ae4..da2c6ab2 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -86,7 +86,7 @@ android:name=".OpenVPNTileService" android:value="true" android:label="@string/qs_title" - android:icon="@drawable/icon" + android:icon="@drawable/ic_quick" android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> diff --git a/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java b/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java index e7af25c7..e1cb8862 100644 --- a/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java +++ b/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java @@ -136,7 +136,7 @@ public class CreateShortcuts extends ListActivity implements OnItemClickListener intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); Parcelable iconResource = Intent.ShortcutIconResource.fromContext( - this, R.drawable.icon); + this, R.mipmap.ic_launcher); intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); // Now, return the result to the launcher -- cgit v1.2.3