summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/AndroidManifest.xml20
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/BitmaskTileService.java101
-rw-r--r--app/src/main/res/values/strings.xml2
3 files changed, 122 insertions, 1 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c2ae2cb3..ec053185 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -79,9 +79,11 @@
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.MAIN" />
-
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
+ <intent-filter>
+ <action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
+ </intent-filter>
</activity>
<activity
@@ -114,6 +116,22 @@
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+
+ <service
+ android:name=".BitmaskTileService"
+ android:icon="@drawable/vpn_disconnected"
+ android:label="@string/qs_title"
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
+ android:value="true">
+ <intent-filter>
+ <action android:name="android.service.quicksettings.action.QS_TILE" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.service.quicksettings.ACTIVE_TILE"
+ android:value="false" />
+ </service>
+
</application>
</manifest>
diff --git a/app/src/main/java/se/leap/bitmaskclient/BitmaskTileService.java b/app/src/main/java/se/leap/bitmaskclient/BitmaskTileService.java
new file mode 100644
index 00000000..4b423624
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/BitmaskTileService.java
@@ -0,0 +1,101 @@
+package se.leap.bitmaskclient;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Build;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+
+import java.util.Observable;
+import java.util.Observer;
+
+import se.leap.bitmaskclient.eip.EipCommand;
+import se.leap.bitmaskclient.eip.EipStatus;
+
+
+@TargetApi(Build.VERSION_CODES.N)
+public class BitmaskTileService extends TileService implements Observer {
+
+ @SuppressLint("Override")
+ @TargetApi(Build.VERSION_CODES.N)
+ @Override
+ public void onClick() {
+ super.onClick();
+ Provider provider = ProviderObservable.getInstance().getCurrentProvider();
+ if (provider.isConfigured()) {
+ if (!isLocked()) {
+ onTileTap();
+ } else {
+ unlockAndRun(this::onTileTap);
+ }
+ } else {
+ Intent intent = new Intent(getApplicationContext(), StartActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+ }
+
+ private void onTileTap() {
+ EipStatus eipStatus = EipStatus.getInstance();
+ if (eipStatus.isConnecting() || eipStatus.isBlocking() || eipStatus.isConnected() || eipStatus.isReconnecting()) {
+ EipCommand.stopVPN(getApplicationContext());
+ } else {
+ EipCommand.startVPN(getApplicationContext(), false);
+ }
+ }
+
+
+ @TargetApi(Build.VERSION_CODES.N)
+ @Override
+ public void onTileAdded() {
+ }
+
+ @Override
+ public void onStartListening() {
+ super.onStartListening();
+ EipStatus.getInstance().addObserver(this);
+ update(EipStatus.getInstance(), null);
+ }
+
+ @Override
+ public void onStopListening() {
+ super.onStopListening();
+ EipStatus.getInstance().deleteObserver(this);
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ Tile t = getQsTile();
+
+ if (o instanceof EipStatus) {
+ EipStatus status = (EipStatus) o;
+ Icon icon;
+ String title;
+ if (status.isConnecting() || status.isReconnecting()) {
+ icon = Icon.createWithResource(getApplicationContext(), R.drawable.vpn_connecting);
+ title = getResources().getString(R.string.cancel);
+ t.setState(Tile.STATE_ACTIVE);
+ } else if (status.isConnected()) {
+ icon = Icon.createWithResource(getApplicationContext(), R.drawable.vpn_connected);
+ title = String.format(getString(R.string.qs_disconnect), getString(R.string.app_name));
+ t.setState(Tile.STATE_ACTIVE);
+ } else if (status.isBlocking()) {
+ icon = Icon.createWithResource(getApplicationContext(), R.drawable.vpn_blocking);
+ title = getString(R.string.vpn_button_turn_off_blocking);
+ t.setState(Tile.STATE_ACTIVE);
+ } else {
+ icon = Icon.createWithResource(getApplicationContext(), R.drawable.vpn_disconnected);
+ title = String.format(getString(R.string.qs_enable_vpn), getString(R.string.app_name));
+ t.setState(Tile.STATE_INACTIVE);
+ }
+
+
+ t.setIcon(icon);
+ t.setLabel(title);
+
+ t.updateTile();
+ }
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7ec78b70..a488fc7c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -140,4 +140,6 @@
<string name="warning_option_try_ovpn">Try standard connection</string>
<string name="vpn_error_establish">Android failed to establish the VPN service.</string>
<string name="root_permission_error">%s cannot execute features like VPN Hotspot or IPv6 firewall without root permissions.</string>
+
+ <string name="qs_enable_vpn">Start %s</string>
</resources>