com/tailscale/ipn,cmd/tailscale: handle quick tile clicks while signed out

Specifically, start the main activity to prompt the user to sign in or
be notified of a pending machine auth.

Fixes tailscale/tailscale#1225

Signed-off-by: Elias Naur <mail@eliasnaur.com>
pull/7/head
Elias Naur 3 years ago
parent 71a9bd537c
commit 07b2373e6b

@ -98,11 +98,18 @@ public class App extends Application {
);
}
void setTileStatus(boolean wantRunning) {
void setTileReady(boolean ready) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return;
}
QuickToggleService.setStatus(this, wantRunning);
QuickToggleService.setReady(this, ready);
}
void setTileStatus(boolean status) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return;
}
QuickToggleService.setStatus(this, status);
}
String getHostname() {

@ -6,6 +6,7 @@ package com.tailscale.ipn;
import android.content.Context;
import android.content.ComponentName;
import android.content.Intent;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
@ -13,33 +14,68 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicBoolean;
public class QuickToggleService extends TileService {
private static AtomicBoolean active = new AtomicBoolean();
private static AtomicReference<Tile> currentTile = new AtomicReference<Tile>();
// lock protects the static fields below it.
private static Object lock = new Object();
// Active tracks whether the VPN is active.
private static boolean active;
// Ready tracks whether the tailscale backend is
// ready to switch on/off.
private static boolean ready;
// currentTile tracks getQsTile while service is listening.
private static Tile currentTile;
@Override public void onStartListening() {
currentTile.set(getQsTile());
synchronized (lock) {
currentTile = getQsTile();
}
updateTile();
}
@Override public void onStopListening() {
currentTile.set(null);
synchronized (lock) {
currentTile = null;
}
}
@Override public void onClick() {
onTileClick();
boolean r;
synchronized (lock) {
r = ready;
}
if (r) {
onTileClick();
} else {
// Start main activity.
Intent i = getPackageManager().getLaunchIntentForPackage(getPackageName());
startActivityAndCollapse(i);
}
}
private static void updateTile() {
Tile t = currentTile.get();
Tile t;
boolean act;
synchronized (lock) {
t = currentTile;
act = active && ready;
}
if (t == null) {
return;
}
t.setState(active.get() ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
t.setState(act ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
t.updateTile();
}
static void setStatus(Context ctx, boolean wantRunning) {
active.set(wantRunning);
static void setReady(Context ctx, boolean rdy) {
synchronized (lock) {
ready = rdy;
}
updateTile();
}
static void setStatus(Context ctx, boolean act) {
synchronized (lock) {
active = act;
}
updateTile();
}

@ -468,6 +468,13 @@ func (a *App) notify(state BackendState) {
case a.updates <- struct{}{}:
default:
}
ready := jni.False
if state.State >= ipn.Stopped {
ready = jni.True
}
if err := a.callVoidMethod(a.appCtx, "setTileReady", "(Z)V", jni.Value(ready)); err != nil {
fatalErr(err)
}
}
func (a *App) setPrefs(prefs *ipn.Prefs) {

Loading…
Cancel
Save