Skip to content

Commit

Permalink
android: persistently store flag indicating whether VPN can be starte…
Browse files Browse the repository at this point in the history
…d by quick settings tile

This allows us to start the VPN from the quick settings tile even when the
application was previously stopped.

Updates tailscale/tailscale#11920

Signed-off-by: Percy Wegmann <percy@tailscale.com>
  • Loading branch information
oxtoacart committed May 9, 2024
1 parent 81929dd commit 9b4974a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
2 changes: 1 addition & 1 deletion android/src/main/java/com/tailscale/ipn/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class App : Application(), libtailscale.AppContext {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return
}
QuickToggleService.setReady(this, ableToStartVPN)
QuickToggleService.setAbleToStartVPN(this, ableToStartVPN)
Log.d("App", "Set Tile Ready: $ableToStartVPN")
val action =
if (ableToStartVPN) IPNReceiver.INTENT_DISCONNECT_VPN else IPNReceiver.INTENT_CONNECT_VPN
Expand Down
40 changes: 30 additions & 10 deletions android/src/main/java/com/tailscale/ipn/QuickToggleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;

public class QuickToggleService extends TileService {
// lock protects the static fields below it.
private static final Object lock = new Object();

// isRunning tracks whether the VPN is running.
private static boolean isRunning;
// Ready tracks whether the tailscale backend is
// ready to switch on/off.
private static boolean ready;

// Key for shared preference that tracks whether or not we're able to start
// the VPN (i.e. we're logged in and machine is authorized).
public static String ABLE_TO_START_VPN_KEY = "ableToStartVPN";

// currentTile tracks getQsTile while service is listening.
private static Tile currentTile;

// Request code for opening activity.
private static int reqCode = 0;

Expand All @@ -28,7 +33,7 @@ private static void updateTile(Context ctx) {
boolean act;
synchronized (lock) {
t = currentTile;
act = isRunning && ready;
act = isRunning && getAbleToStartVPN(ctx);
}
if (t == null) {
return;
Expand All @@ -41,13 +46,26 @@ private static void updateTile(Context ctx) {
t.updateTile();
}

static void setReady(Context ctx, boolean rdy) {
synchronized (lock) {
ready = rdy;
}
/*
* setAbleToStartVPN remembers whether or not we're able to start the VPN
* by storing this in a shared preference. This allows us to check this
* value without needing a fully initialized instance of the application.
*/
static void setAbleToStartVPN(Context ctx, boolean rdy) {
SharedPreferences prefs = getSharedPreferences(ctx);
prefs.edit().putBoolean(ABLE_TO_START_VPN_KEY, rdy).apply();
updateTile(ctx);
}

static boolean getAbleToStartVPN(Context ctx) {
SharedPreferences prefs = getSharedPreferences(ctx);
return prefs.getBoolean(ABLE_TO_START_VPN_KEY, false);
}

static SharedPreferences getSharedPreferences(Context ctx) {
return ctx.getSharedPreferences("quicktoggle", Context.MODE_PRIVATE);
}

static void setVPNRunning(Context ctx, boolean running) {
synchronized (lock) {
isRunning = running;
Expand All @@ -74,9 +92,11 @@ public void onStopListening() {
public void onClick() {
boolean r;
synchronized (lock) {
r = ready;
r = getAbleToStartVPN(this);
}
if (r) {
// Get the application to make sure it initializes
App.getApplication();
onTileClick();
} else {
// Start main activity.
Expand All @@ -92,7 +112,7 @@ public void onClick() {
private void onTileClick() {
boolean act;
synchronized (lock) {
act = ready && isRunning;
act = getAbleToStartVPN(this) && isRunning;
}
Intent i = new Intent(act ? IPNReceiver.INTENT_DISCONNECT_VPN : IPNReceiver.INTENT_CONNECT_VPN);
i.setPackage(getPackageName());
Expand Down

0 comments on commit 9b4974a

Please sign in to comment.