fix: switch to dynamic shortcuts

closes #365
closes #508
This commit is contained in:
Zane Schepke 2024-12-21 23:28:50 -05:00
parent 133bd6caf7
commit 7cf7817cea
8 changed files with 101 additions and 78 deletions

View File

@ -79,9 +79,6 @@
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"

View File

@ -5,6 +5,8 @@ import com.zaneschepke.logcatter.LogReader
import com.zaneschepke.logcatter.LogcatReader
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService
import com.zaneschepke.wireguardautotunnel.service.notification.WireGuardNotification
import com.zaneschepke.wireguardautotunnel.service.shortcut.DynamicShortcutManager
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -35,4 +37,10 @@ class AppModule {
fun provideNotificationService(@ApplicationContext context: Context): NotificationService {
return WireGuardNotification(context)
}
@Singleton
@Provides
fun provideShortcutManager(@ApplicationContext context: Context): ShortcutManager {
return DynamicShortcutManager(context)
}
}

View File

@ -264,7 +264,7 @@ class AutoTunnelService : LifecycleService() {
wifi.available,
mobileData.available,
false,
wifi.name
wifi.name,
)
}.distinctUntilChanged().filterNot { it.isWifiConnected && it.wifiName == null }.debounce(500L)
}

View File

@ -30,13 +30,13 @@ class WifiService
constructor(
@ApplicationContext private val context: Context,
private val settingsRepository: SettingsRepository,
@AppShell private val rootShell: Provider<RootShell>
@AppShell private val rootShell: Provider<RootShell>,
) : NetworkService {
val mutex = Mutex()
private var ssid : String? = null
private var available : Boolean = false
private var ssid: String? = null
private var available: Boolean = false
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@ -105,12 +105,12 @@ constructor(
Timber.e(it)
emit(NetworkStatus.Unavailable())
}.transform {
when(it) {
when (it) {
is NetworkStatus.Available -> mutex.withLock {
available = true
}
is NetworkStatus.CapabilitiesChanged -> mutex.withLock {
if(available) {
if (available) {
available = false
Timber.d("Getting SSID from capabilities")
ssid = getNetworkName(it.networkCapabilities)
@ -122,7 +122,7 @@ constructor(
}
private suspend fun getNetworkName(networkCapabilities: NetworkCapabilities): String? {
if(settingsRepository.getSettings().isWifiNameByShellEnabled) return rootShell.get().getCurrentWifiName()
if (settingsRepository.getSettings().isWifiNameByShellEnabled) return rootShell.get().getCurrentWifiName()
var ssid = networkCapabilities.getWifiName()
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S) {
val wifiManager =

View File

@ -0,0 +1,72 @@
package com.zaneschepke.wireguardautotunnel.service.shortcut
import android.content.Context
import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.zaneschepke.wireguardautotunnel.R
class DynamicShortcutManager(private val context: Context) : ShortcutManager {
override fun addShortcuts() {
ShortcutManagerCompat.setDynamicShortcuts(context, createShortcuts())
}
override fun removeShortcuts() {
ShortcutManagerCompat.removeDynamicShortcuts(context, createShortcuts().map { it.id })
}
private fun createShortcuts(): List<ShortcutInfoCompat> {
return listOf(
buildShortcut(
context.getString(R.string.vpn_off),
context.getString(R.string.vpn_off),
context.getString(R.string.vpn_off),
intent = Intent(context, ShortcutsActivity::class.java).apply {
putExtra("className", "WireGuardTunnelService")
action = ShortcutsActivity.Action.STOP.name
},
shortcutIcon = R.drawable.vpn_off,
),
buildShortcut(
context.getString(R.string.vpn_on),
context.getString(R.string.vpn_on),
context.getString(R.string.vpn_on),
intent = Intent(context, ShortcutsActivity::class.java).apply {
putExtra("className", "WireGuardTunnelService")
action = ShortcutsActivity.Action.START.name
},
shortcutIcon = R.drawable.vpn_on,
),
buildShortcut(
context.getString(R.string.start_auto),
context.getString(R.string.start_auto),
context.getString(R.string.start_auto),
intent = Intent(context, ShortcutsActivity::class.java).apply {
putExtra("className", "WireGuardConnectivityWatcherService")
action = ShortcutsActivity.Action.START.name
},
shortcutIcon = R.drawable.auto_play,
),
buildShortcut(
context.getString(R.string.stop_auto),
context.getString(R.string.stop_auto),
context.getString(R.string.stop_auto),
intent = Intent(context, ShortcutsActivity::class.java).apply {
putExtra("className", "WireGuardConnectivityWatcherService")
action = ShortcutsActivity.Action.STOP.name
},
shortcutIcon = R.drawable.auto_pause,
),
)
}
private fun buildShortcut(id: String, shortLabel: String, longLabel: String, intent: Intent, shortcutIcon: Int): ShortcutInfoCompat {
return ShortcutInfoCompat.Builder(context, id)
.setShortLabel(shortLabel)
.setLongLabel(longLabel)
.setIntent(intent)
.setIcon(IconCompat.createWithResource(context, shortcutIcon))
.build()
}
}

View File

@ -0,0 +1,6 @@
package com.zaneschepke.wireguardautotunnel.service.shortcut
interface ShortcutManager {
fun addShortcuts()
fun removeShortcuts()
}

View File

@ -40,6 +40,7 @@ import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.data.repository.AppStateRepository
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelService
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavBar
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavItem
@ -78,6 +79,9 @@ class MainActivity : AppCompatActivity() {
@Inject
lateinit var tunnelService: TunnelService
@Inject
lateinit var shortcutManager: ShortcutManager
@OptIn(ExperimentalLayoutApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge(
@ -119,6 +123,10 @@ class MainActivity : AppCompatActivity() {
LaunchedEffect(isAutoTunnelEnabled) {
this@MainActivity.requestAutoTunnelTileServiceUpdate()
}
LaunchedEffect(isShortcutsEnabled) {
if (!isShortcutsEnabled) return@LaunchedEffect shortcutManager.removeShortcuts()
shortcutManager.addShortcuts()
}
}
CompositionLocalProvider(LocalNavController provides navController) {

View File

@ -1,68 +0,0 @@
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/vpn_on"
android:shortcutDisabledMessage="@string/vpn_on"
android:shortcutId="defaultOn1"
android:shortcutLongLabel="@string/vpn_on"
android:shortcutShortLabel="@string/vpn_on">
<intent
android:action="START"
android:targetClass="com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsActivity"
android:targetPackage="com.zaneschepke.wireguardautotunnel">
<extra
android:name="className"
android:value="WireGuardTunnelService" />
</intent>
<capability-binding android:key="actions.intent.START" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/vpn_off"
android:shortcutDisabledMessage="@string/vpn_off"
android:shortcutId="defaultOff1"
android:shortcutLongLabel="@string/vpn_off"
android:shortcutShortLabel="@string/vpn_off">
<intent
android:action="STOP"
android:targetClass="com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsActivity"
android:targetPackage="com.zaneschepke.wireguardautotunnel">
<extra
android:name="className"
android:value="WireGuardTunnelService" />
</intent>
<capability-binding android:key="actions.intent.STOP" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/auto_play"
android:shortcutId="autoOn1"
android:shortcutLongLabel="@string/start_auto"
android:shortcutShortLabel="@string/start_auto">
<intent
android:action="START"
android:targetClass="com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsActivity"
android:targetPackage="com.zaneschepke.wireguardautotunnel">
<extra
android:name="className"
android:value="WireGuardConnectivityWatcherService" />
</intent>
<capability-binding android:key="actions.intent.STOP" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/auto_pause"
android:shortcutId="autoOff1"
android:shortcutLongLabel="@string/stop_auto"
android:shortcutShortLabel="@string/stop_auto">
<intent
android:action="STOP"
android:targetClass="com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsActivity"
android:targetPackage="com.zaneschepke.wireguardautotunnel">
<extra
android:name="className"
android:value="WireGuardConnectivityWatcherService" />
</intent>
<capability-binding android:key="actions.intent.STOP" />
</shortcut>
</shortcuts>