Skip to content

Commit 1d65de2

Browse files
committed
switch to alternative quicktile implementation
1 parent 4ba8794 commit 1d65de2

File tree

6 files changed

+100
-15
lines changed

6 files changed

+100
-15
lines changed

ui/src/main/AndroidManifest.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
<uses-permission android:name="android.permission.INTERNET" />
88
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
99
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
10-
<uses-permission
11-
android:name="android.permission.SYSTEM_ALERT_WINDOW"
12-
android:minSdkVersion="34" />
1310
<uses-permission
1411
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
1512
android:maxSdkVersion="28"

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package com.wireguard.android
66

77
import android.app.PendingIntent
8+
import android.content.Context
89
import android.content.Intent
910
import android.graphics.Bitmap
1011
import android.graphics.Canvas
@@ -21,6 +22,7 @@ import androidx.databinding.Observable
2122
import androidx.databinding.Observable.OnPropertyChangedCallback
2223
import com.wireguard.android.activity.MainActivity
2324
import com.wireguard.android.activity.TunnelToggleActivity
25+
import com.wireguard.android.activity.TunnelToggleActivity.Companion.SHOW_PROGRESS
2426
import com.wireguard.android.backend.Tunnel
2527
import com.wireguard.android.model.ObservableTunnel
2628
import com.wireguard.android.util.applicationScope
@@ -52,6 +54,7 @@ class QuickTileService : TileService() {
5254
}
5355

5456
override fun onClick() {
57+
updateTile()
5558
when (val tunnel = tunnel) {
5659
null -> {
5760
val intent = Intent(this, MainActivity::class.java)
@@ -70,15 +73,15 @@ class QuickTileService : TileService() {
7073
tunnel.setStateAsync(Tunnel.State.TOGGLE)
7174
updateTile()
7275
} catch (_: Throwable) {
73-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && !Settings.canDrawOverlays(this@QuickTileService)) {
74-
val permissionIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName"))
75-
permissionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
76-
startActivityAndCollapse(PendingIntent.getActivity(this@QuickTileService, 0, permissionIntent, PendingIntent.FLAG_IMMUTABLE))
77-
return@launch
76+
val intent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
77+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
78+
intent.putExtra(SHOW_PROGRESS, true)
79+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
80+
startActivityAndCollapse(PendingIntent.getActivity(this@QuickTileService, 0, intent, PendingIntent.FLAG_IMMUTABLE))
81+
} else {
82+
@Suppress("DEPRECATION")
83+
startActivity(intent)
7884
}
79-
val toggleIntent = Intent(this@QuickTileService, TunnelToggleActivity::class.java)
80-
toggleIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
81-
startActivity(toggleIntent)
8285
}
8386
}
8487
}
@@ -133,7 +136,7 @@ class QuickTileService : TileService() {
133136
isAdded = false
134137
}
135138

136-
private fun updateTile() {
139+
private fun updateTile(isConnecting: Boolean = false) {
137140
// Update the tunnel.
138141
val newTunnel = Application.getTunnelManager().lastUsedTunnel
139142
if (newTunnel != tunnel) {
@@ -148,6 +151,12 @@ class QuickTileService : TileService() {
148151
null -> {
149152
tile.label = getString(R.string.app_name)
150153
tile.state = Tile.STATE_INACTIVE
154+
if(isConnecting) {
155+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
156+
tile.subtitle = getString(R.string.quick_settings_tile_connecting)
157+
tile.state = Tile.STATE_ACTIVE
158+
}
159+
}
151160
tile.icon = iconOff
152161
}
153162
else -> {

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

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package com.wireguard.android.activity
77
import android.content.ComponentName
88
import android.os.Build
99
import android.os.Bundle
10+
import android.os.Handler
1011
import android.service.quicksettings.TileService
1112
import android.util.Log
1213
import android.widget.Toast
@@ -24,6 +25,9 @@ import kotlinx.coroutines.launch
2425

2526
@RequiresApi(Build.VERSION_CODES.N)
2627
class TunnelToggleActivity : AppCompatActivity() {
28+
29+
private var mIsVisible = false
30+
2731
private val permissionActivityResultLauncher =
2832
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { toggleTunnelWithPermissionsResult() }
2933

@@ -38,16 +42,23 @@ class TunnelToggleActivity : AppCompatActivity() {
3842
val message = getString(R.string.toggle_error, error)
3943
Log.e(TAG, message, e)
4044
Toast.makeText(this@TunnelToggleActivity, message, Toast.LENGTH_LONG).show()
41-
finishAffinity()
45+
exitActivity()
4246
return@launch
4347
}
4448
TileService.requestListeningState(this@TunnelToggleActivity, ComponentName(this@TunnelToggleActivity, QuickTileService::class.java))
45-
finishAffinity()
49+
exitActivity()
4650
}
4751
}
4852

4953
override fun onCreate(savedInstanceState: Bundle?) {
5054
super.onCreate(savedInstanceState)
55+
56+
if(intent.getBooleanExtra(SHOW_PROGRESS, false)) {
57+
mIsVisible = true
58+
title = "" // Otherwise the apptitle will be shown above the spinner.
59+
setContentView(R.layout.loading_activity)
60+
}
61+
5162
lifecycleScope.launch {
5263
if (Application.getBackend() is GoBackend) {
5364
val intent = GoBackend.VpnService.prepare(this@TunnelToggleActivity)
@@ -58,9 +69,29 @@ class TunnelToggleActivity : AppCompatActivity() {
5869
}
5970
toggleTunnelWithPermissionsResult()
6071
}
72+
exitActivity()
73+
}
74+
75+
private fun exitActivity() {
76+
/*
77+
We add this delay, so that the user gets the impression we are actually doing something.
78+
This is to make the transition of the closing quicktile-menu more palatable,
79+
because startActivityAndCollapse() will immediately close that menu.
80+
This can be jarring, so we show this placeholder spinner and close it after a second.
81+
*/
82+
83+
if(mIsVisible) {
84+
Handler().postDelayed({
85+
finishAffinity()
86+
}, 1000L)
87+
} else {
88+
finishAffinity()
89+
}
90+
6191
}
6292

6393
companion object {
6494
private const val TAG = "WireGuard/TunnelToggleActivity"
95+
const val SHOW_PROGRESS = "ShowLoadingbar"
6596
}
6697
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
xmlns:tools="http://schemas.android.com/tools">
5+
6+
<androidx.constraintlayout.widget.ConstraintLayout
7+
android:layout_width="match_parent"
8+
android:layout_height="match_parent">
9+
10+
11+
<com.google.android.material.card.MaterialCardView
12+
android:layout_width="wrap_content"
13+
android:layout_height="wrap_content"
14+
android:checkable="true"
15+
android:focusable="true"
16+
app:contentPadding="32dp"
17+
app:layout_constraintBottom_toBottomOf="parent"
18+
app:layout_constraintEnd_toEndOf="parent"
19+
app:layout_constraintStart_toStartOf="parent"
20+
app:layout_constraintTop_toTopOf="parent">
21+
22+
<LinearLayout
23+
android:layout_width="match_parent"
24+
android:layout_height="match_parent"
25+
android:orientation="vertical">
26+
27+
<TextView
28+
android:id="@+id/textView"
29+
android:layout_width="wrap_content"
30+
android:layout_height="wrap_content"
31+
android:layout_marginBottom="24dp"
32+
android:text="Preparing Tunnel..." />
33+
34+
<ProgressBar
35+
android:id="@+id/progressBar"
36+
style="?android:attr/progressBarStyle"
37+
android:layout_width="match_parent"
38+
android:layout_height="match_parent" />
39+
</LinearLayout>
40+
41+
</com.google.android.material.card.MaterialCardView>
42+
43+
</androidx.constraintlayout.widget.ConstraintLayout>
44+
</layout>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,5 @@
257257
<string name="biometric_prompt_private_key_title">Authenticate to view private key</string>
258258
<string name="biometric_auth_error">Authentication failure</string>
259259
<string name="biometric_auth_error_reason">Authentication failure: %s</string>
260+
<string name="quick_settings_tile_connecting">Connecting…</string>
260261
</resources>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@
3333
<item name="android:windowBackground">@android:color/transparent</item>
3434
<item name="android:background">@android:color/transparent</item>
3535
<item name="colorPrimaryDark">@android:color/transparent</item>
36-
<item name="android:backgroundDimEnabled">true</item>
36+
<item name="android:backgroundDimEnabled">false</item>
3737
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
3838
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
39+
<item name="android:windowIsFloating">true</item>
40+
<item name="android:colorBackgroundCacheHint">@null</item>
41+
3942
</style>
4043

4144
<style name="TvTheme" parent="AppTheme">

0 commit comments

Comments
 (0)