Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Shortcuts #37

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
InfiniteCoder06 marked this conversation as resolved.
Show resolved Hide resolved
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)
InfiniteCoder06 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
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