Skip to content

Commit 70f8e5a

Browse files
committed
ui: add shortcut for adding quick settings tile
Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent e53a8d7 commit 70f8e5a

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

ui/src/main/java/com/wireguard/android/QuickTileService.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class QuickTileService : TileService() {
7575
}
7676

7777
override fun onCreate() {
78+
isAdded = true
7879
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
7980
iconOn = Icon.createWithResource(this, R.drawable.ic_tile)
8081
iconOff = iconOn
@@ -98,6 +99,11 @@ class QuickTileService : TileService() {
9899
iconOff = Icon.createWithBitmap(b)
99100
}
100101

102+
override fun onDestroy() {
103+
super.onDestroy()
104+
isAdded = false
105+
}
106+
101107
override fun onStartListening() {
102108
Application.getTunnelManager().addOnPropertyChangedCallback(onTunnelChangedCallback)
103109
if (tunnel != null) tunnel!!.addOnPropertyChangedCallback(onStateChangedCallback)
@@ -109,6 +115,14 @@ class QuickTileService : TileService() {
109115
Application.getTunnelManager().removeOnPropertyChangedCallback(onTunnelChangedCallback)
110116
}
111117

118+
override fun onTileAdded() {
119+
isAdded = true
120+
}
121+
122+
override fun onTileRemoved() {
123+
isAdded = false
124+
}
125+
112126
private fun updateTile() {
113127
// Update the tunnel.
114128
val newTunnel = Application.getTunnelManager().lastUsedTunnel
@@ -157,5 +171,7 @@ class QuickTileService : TileService() {
157171

158172
companion object {
159173
private const val TAG = "WireGuard/QuickTileService"
174+
var isAdded: Boolean = false
175+
private set
160176
}
161177
}

ui/src/main/java/com/wireguard/android/activity/SettingsActivity.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@
44
*/
55
package com.wireguard.android.activity
66

7+
import android.content.ComponentName
78
import android.content.Intent
89
import android.os.Build
910
import android.os.Bundle
11+
import android.service.quicksettings.TileService
1012
import android.view.MenuItem
1113
import androidx.appcompat.app.AppCompatActivity
1214
import androidx.fragment.app.commit
1315
import androidx.lifecycle.lifecycleScope
1416
import androidx.preference.Preference
1517
import androidx.preference.PreferenceFragmentCompat
1618
import com.wireguard.android.Application
19+
import com.wireguard.android.QuickTileService
1720
import com.wireguard.android.R
1821
import com.wireguard.android.backend.WgQuickBackend
1922
import com.wireguard.android.preference.PreferencesPreferenceDataStore
@@ -47,7 +50,13 @@ class SettingsActivity : AppCompatActivity() {
4750
override fun onCreatePreferences(savedInstanceState: Bundle?, key: String?) {
4851
preferenceManager.preferenceDataStore = PreferencesPreferenceDataStore(lifecycleScope, Application.getPreferencesDataStore())
4952
addPreferencesFromResource(R.xml.preferences)
50-
preferenceScreen.initialExpandedChildrenCount = 4
53+
preferenceScreen.initialExpandedChildrenCount = 5
54+
55+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || QuickTileService.isAdded) {
56+
val quickTile = preferenceManager.findPreference<Preference>("quick_tile")
57+
quickTile?.parent?.removePreference(quickTile)
58+
--preferenceScreen.initialExpandedChildrenCount
59+
}
5160
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
5261
val darkTheme = preferenceManager.findPreference<Preference>("dark_theme")
5362
darkTheme?.parent?.removePreference(darkTheme)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright © 2017-2023 WireGuard LLC. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package com.wireguard.android.preference
7+
8+
import android.app.StatusBarManager
9+
import android.content.ComponentName
10+
import android.content.Context
11+
import android.graphics.drawable.Icon
12+
import android.os.Build
13+
import android.util.AttributeSet
14+
import android.widget.Toast
15+
import androidx.annotation.RequiresApi
16+
import androidx.preference.Preference
17+
import com.wireguard.android.QuickTileService
18+
import com.wireguard.android.R
19+
20+
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
21+
class QuickTilePreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) {
22+
override fun getSummary() = context.getString(R.string.quick_settings_tile_add_summary)
23+
24+
override fun getTitle() = context.getString(R.string.quick_settings_tile_add_title)
25+
26+
override fun onClick() {
27+
val statusBarManager = context.getSystemService(StatusBarManager::class.java)
28+
statusBarManager.requestAddTileService(
29+
ComponentName(context, QuickTileService::class.java),
30+
context.getString(R.string.quick_settings_tile_action),
31+
Icon.createWithResource(context, R.drawable.ic_tile),
32+
context.mainExecutor
33+
) {
34+
when (it) {
35+
StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED,
36+
StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED -> {
37+
parent?.removePreference(this)
38+
--preferenceManager.preferenceScreen.initialExpandedChildrenCount
39+
}
40+
StatusBarManager.TILE_ADD_REQUEST_ERROR_MISMATCHED_PACKAGE,
41+
StatusBarManager.TILE_ADD_REQUEST_ERROR_REQUEST_IN_PROGRESS,
42+
StatusBarManager.TILE_ADD_REQUEST_ERROR_BAD_COMPONENT,
43+
StatusBarManager.TILE_ADD_REQUEST_ERROR_NOT_CURRENT_USER,
44+
StatusBarManager.TILE_ADD_REQUEST_ERROR_APP_NOT_IN_FOREGROUND,
45+
StatusBarManager.TILE_ADD_REQUEST_ERROR_NO_STATUS_BAR_SERVICE ->
46+
Toast.makeText(context, context.getString(R.string.quick_settings_tile_add_failure, it), Toast.LENGTH_SHORT).show()
47+
}
48+
}
49+
}
50+
}

ui/src/main/res/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@
185185
<string name="private_key">Private key</string>
186186
<string name="public_key">Public key</string>
187187
<string name="qr_code_hint">Tip: generate with `qrencode -t ansiutf8 &lt; tunnel.conf`.</string>
188+
<string name="quick_settings_tile_add_title">Add tile to quick settings panel</string>
189+
<string name="quick_settings_tile_add_summary">The shortcut tile toggles the most recent tunnel</string>
190+
<string name="quick_settings_tile_add_failure">Unable to add shortcut tile: error %d</string>
191+
<string name="quick_settings_tile_action">Toggle tunnel</string>
188192
<string name="restore_on_boot_summary_off">Will not bring up enabled tunnels at boot</string>
189193
<string name="restore_on_boot_summary_on">Will bring up enabled tunnels at boot</string>
190194
<string name="restore_on_boot_title">Restore on boot</string>

ui/src/main/res/xml/preferences.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:summaryOn="@string/restore_on_boot_summary_on"
1313
android:title="@string/restore_on_boot_title" />
1414
<com.wireguard.android.preference.ZipExporterPreference android:key="zip_exporter" />
15+
<com.wireguard.android.preference.QuickTilePreference android:key="quick_tile" />
1516
<Preference
1617
android:key="log_viewer"
1718
android:singleLineTitle="false"

0 commit comments

Comments
 (0)