Skip to content

Commit

Permalink
Add Shortcuts
Browse files Browse the repository at this point in the history
  • Loading branch information
InfiniteCoder06 committed Oct 18, 2024
1 parent 681e6ce commit d34aa30
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 60 deletions.
25 changes: 25 additions & 0 deletions app/src/debug/res/xml/shortcuts.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="switch_mode"
android:enabled="true"
android:icon="@drawable/ic_outline_next_24dp"
android:shortcutShortLabel="@string/shortcut_switch_mode">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="ru.karasevm.privatednstoggle.dev"
android:targetClass="ru.karasevm.privatednstoggle.ui.SettingsDialogActivity"
android:data="myapp://switch_mode"/>
</shortcut>
<shortcut
android:shortcutId="toggle_mode"
android:enabled="true"
android:icon="@drawable/ic_play_pause_24px"
android:shortcutShortLabel="@string/shortcut_toggle_on_off">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="ru.karasevm.privatednstoggle.dev"
android:targetClass="ru.karasevm.privatednstoggle.ui.SettingsDialogActivity"
android:data="myapp://toggle_mode"/>
</shortcut>
</shortcuts>
14 changes: 12 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Transparent">
android:theme="@style/Theme.Transparent" >
<service
android:name=".service.ShortcutService"
android:enabled="true"
android:exported="true" >
</service>

<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />

<activity
android:name=".ui.MainActivity"
android:theme="@style/Theme.MyApplication"
Expand All @@ -26,8 +32,12 @@
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>

<activity
Expand All @@ -45,7 +55,7 @@
android:exported="true"
android:icon="@drawable/ic_unknown_black_24dp"
android:label="@string/tile_name"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE" >
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.drawable.Icon
import android.provider.Settings
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import androidx.core.content.ContextCompat
Expand All @@ -17,18 +16,14 @@ import kotlinx.coroutines.launch
import ru.karasevm.privatednstoggle.PrivateDNSApp
import ru.karasevm.privatednstoggle.R
import ru.karasevm.privatednstoggle.data.DnsServerRepository
import ru.karasevm.privatednstoggle.model.DnsServer
import ru.karasevm.privatednstoggle.util.PreferenceHelper
import ru.karasevm.privatednstoggle.util.PreferenceHelper.autoMode
import ru.karasevm.privatednstoggle.util.PreferenceHelper.requireUnlock
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.AUTO_MODE_OPTION_AUTO
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.AUTO_MODE_OPTION_OFF_AUTO
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.AUTO_MODE_OPTION_PRIVATE
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_AUTO
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_OFF
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_PRIVATE
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.checkForPermission
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.getNextAddress

class DnsTileService : TileService() {

Expand All @@ -50,36 +45,11 @@ class DnsTileService : TileService() {
* Set's the state of the tile and system settings to the next state
*/
private fun cycleState() {
val dnsMode = Settings.Global.getString(contentResolver, "private_dns_mode")
val dnsProvider = Settings.Global.getString(contentResolver, "private_dns_specifier")

val sharedPrefs = PreferenceHelper.defaultPreference(this)
if (dnsMode.equals(DNS_MODE_OFF, ignoreCase = true)) {
if (sharedPrefs.autoMode == AUTO_MODE_OPTION_AUTO || sharedPrefs.autoMode == AUTO_MODE_OPTION_OFF_AUTO) {
changeDNSServer(DNS_MODE_AUTO, dnsProvider)
} else {
changeDNSServer(DNS_MODE_PRIVATE, dnsProvider)
}

} else if (dnsMode == null || dnsMode.equals(DNS_MODE_AUTO, ignoreCase = true)) {
changeDNSServer(DNS_MODE_PRIVATE, null)
} else if (dnsMode.equals(DNS_MODE_PRIVATE, ignoreCase = true)) {
scope.launch {
if (getNextAddress(dnsProvider) == null) {
if (sharedPrefs.autoMode == AUTO_MODE_OPTION_PRIVATE) {
changeDNSServer(DNS_MODE_PRIVATE, null)
} else {
if (sharedPrefs.autoMode == AUTO_MODE_OPTION_AUTO) {
changeDNSServer(DNS_MODE_AUTO, dnsProvider)
} else {
changeDNSServer(DNS_MODE_OFF, dnsProvider)
}
}
} else {
changeDNSServer(DNS_MODE_PRIVATE, dnsProvider)
}
}
}
PrivateDNSUtils.getNextProvider(sharedPrefs, scope, repository, contentResolver, onNext = { mode, provider ->
changeDNSServer(mode, provider)
})
}

/**
Expand Down Expand Up @@ -113,15 +83,15 @@ class DnsTileService : TileService() {

DNS_MODE_PRIVATE -> {
scope.launch {
val nextDnsServer = getNextAddress(dnsProvider)
val nextDnsServer = getNextAddress(repository, dnsProvider)
if (nextDnsServer != null) {
changeTileState(
qsTile,
Tile.STATE_ACTIVE,
nextDnsServer.label.ifEmpty { nextDnsServer.server },
R.drawable.ic_private_black_24dp,
DNS_MODE_PRIVATE,
getNextAddress(dnsProvider)?.server
getNextAddress(repository, dnsProvider)?.server
)
}
}
Expand Down Expand Up @@ -151,7 +121,7 @@ class DnsTileService : TileService() {
* Refreshes the state of the tile
*/
private fun refreshTile() {
val dnsMode = Settings.Global.getString(contentResolver, "private_dns_mode")
val dnsMode = PrivateDNSUtils.getPrivateMode(contentResolver)
when (dnsMode?.lowercase()) {
DNS_MODE_OFF -> {
setTile(
Expand All @@ -174,8 +144,8 @@ class DnsTileService : TileService() {
DNS_MODE_PRIVATE -> {
scope.launch {
val activeAddress =
Settings.Global.getString(contentResolver, "private_dns_specifier")
val dnsServer = repository.getFirstByServer(activeAddress)
PrivateDNSUtils.getPrivateProvider(contentResolver)
val dnsServer = repository.getFirstByServer(activeAddress!!)
setTile(
qsTile,
Tile.STATE_ACTIVE,
Expand Down Expand Up @@ -277,19 +247,4 @@ class DnsTileService : TileService() {
PrivateDNSUtils.setPrivateProvider(contentResolver, dnsProvider)
tile.updateTile()
}

/**
* Gets next dns address from the database,
* if current address is last or unknown returns null
*
* @param currentAddress currently set address
* @return next address
*/
private suspend fun getNextAddress(currentAddress: String?): DnsServer? {
return if (currentAddress.isNullOrEmpty()) {
repository.getFirstEnabled()
} else {
repository.getNextByServer(currentAddress)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package ru.karasevm.privatednstoggle.service

import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import ru.karasevm.privatednstoggle.PrivateDNSApp
import ru.karasevm.privatednstoggle.data.DnsServerRepository
import ru.karasevm.privatednstoggle.util.PreferenceHelper
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_AUTO
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_OFF
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.DNS_MODE_PRIVATE
import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.checkForPermission

class ShortcutService : Service() {

private val repository: DnsServerRepository by lazy { (application as PrivateDNSApp).repository }
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job)

companion object {
private const val ACTION_SWITCH_MODE = "myapp://switch_mode"
private const val ACTION_TOGGLE_MODE = "myapp://toggle_mode"
}

private fun setDnsModeAndShowToast(dnsMode: String) {
PrivateDNSUtils.setPrivateMode(contentResolver, dnsMode)
val text = when (dnsMode) {
DNS_MODE_OFF -> "DNS set to Off"
DNS_MODE_AUTO -> "DNS set to Auto"
DNS_MODE_PRIVATE -> "DNS set to Private Provider"
else -> "Unknown"
}
scope.launch {
launch(Dispatchers.Main) {
Toast.makeText(applicationContext, text, Toast.LENGTH_SHORT).show()
}
}
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val data = intent?.data.toString()
val sharedPrefs = PreferenceHelper.defaultPreference(this)
if(checkForPermission(this)) {
if (data == ACTION_SWITCH_MODE) {
PrivateDNSUtils.getNextProvider(
sharedPrefs,
scope,
repository,
contentResolver,
skipProvider = true,
onNext = { dnsMode, _ ->
setDnsModeAndShowToast(dnsMode)
})
} else if(data == ACTION_TOGGLE_MODE) {
val dnsMode = PrivateDNSUtils.getPrivateMode(contentResolver)
when (dnsMode) {
DNS_MODE_OFF -> {
PrivateDNSUtils.getNextProvider(
sharedPrefs,
scope,
repository,
contentResolver,
skipProvider = true,
onNext = { dnsMode, _ ->
setDnsModeAndShowToast(dnsMode)
})
}
else -> {
PrivateDNSUtils.setPrivateMode(contentResolver, DNS_MODE_OFF)
}
}
}
}
return START_NOT_STICKY
}

override fun onBind(intent: Intent): IBinder? {
return null
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package ru.karasevm.privatednstoggle.ui

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import ru.karasevm.privatednstoggle.service.ShortcutService

class SettingsDialogActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val newFragment = DNSServerDialogFragment()
newFragment.show(supportFragmentManager, DNSServerDialogFragment.TAG)

if (intent != null && intent.data != null) {
// Start the service when the shortcut is clicked
val serviceIntent = Intent(this, ShortcutService::class.java)
serviceIntent.data = intent.data
startService(serviceIntent)
finish()
} else {
val newFragment = DNSServerDialogFragment()
newFragment.show(supportFragmentManager, DNSServerDialogFragment.TAG)
}
}
}
Loading

0 comments on commit d34aa30

Please sign in to comment.