diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2016-04-25 23:31:34 +0300 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2016-04-25 23:31:34 +0300 | 
| commit | 1df79a1ff67a3388a26e9acd62c97639abbdc267 (patch) | |
| tree | 00d8c343c769c6ec0fefeb6ed3e83482a93b7872 /main | |
| parent | 32478332830697ef36a6bc6bcc0ef3b914a86e6d (diff) | |
Implement quick settings tile
Diffstat (limited to 'main')
| -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 | 
6 files changed, 172 insertions, 2 deletions
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>  | 
