summaryrefslogtreecommitdiffhomepage
path: root/app/src/main/java/com/wireguard/android/QuickTileService.java
blob: ddadf29d7b203e99dcb984083c7706bb6ca4d3f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.wireguard.android;

import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;

import com.wireguard.config.Config;

@TargetApi(Build.VERSION_CODES.N)
public class QuickTileService extends TileService {
    private Config config;
    private SharedPreferences preferences;
    private VpnService service;

    @Override
    public void onClick() {
        if (service != null && config != null) {
            if (config.isEnabled())
                service.disable(config.getName());
            else
                service.enable(config.getName());
        }
    }

    @Override
    public void onCreate() {
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        service = VpnService.getInstance();
        if (service == null)
            bindService(new Intent(this, VpnService.class), new ServiceConnectionCallbacks(),
                    Context.BIND_AUTO_CREATE);
        TileService.requestListeningState(this, new ComponentName(this, getClass()));
    }

    @Override
    public void onStartListening() {
        // Since this is an active tile, this only gets called when we want to update the tile.
        final Tile tile = getQsTile();
        final String configName = preferences.getString(VpnService.KEY_PRIMARY_CONFIG, null);
        config = configName != null && service != null ? service.get(configName) : null;
        if (config != null) {
            tile.setLabel(config.getName());
            final int state = config.isEnabled() ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
            if (tile.getState() != state) {
                // The icon must be changed every time the state changes, or the color won't change.
                final Integer iconResource = (state == Tile.STATE_ACTIVE) ?
                        R.drawable.ic_tile : R.drawable.ic_tile_disabled;
                tile.setIcon(Icon.createWithResource(this, iconResource));
                tile.setState(state);
            }
        } else {
            tile.setIcon(Icon.createWithResource(this, R.drawable.ic_tile_disabled));
            tile.setLabel(getString(R.string.loading));
            tile.setState(Tile.STATE_UNAVAILABLE);
        }
        tile.updateTile();
    }

    private class ServiceConnectionCallbacks implements ServiceConnection {
        @Override
        public void onServiceConnected(final ComponentName component, final IBinder binder) {
            // We don't actually need a binding, only notification that the service is started.
            unbindService(this);
            service = VpnService.getInstance();
        }

        @Override
        public void onServiceDisconnected(final ComponentName component) {
            // This can never happen; the service runs in the same thread as this service.
            throw new IllegalStateException();
        }
    }
}