Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
18 changes: 18 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,24 @@
android:value="android.service.quicksettings.CATEGORY_UTILITIES" />
</service>

<service
android:name=".services.tiles.WirelessDebugging"
android:exported="true"
android:icon="@drawable/wireless_debugging_24"
android:label="@string/tile_wifi_adb_title_short"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>

<meta-data
android:name="android.service.quicksettings.ACTION_QS_TILE_PREFERENCES"
android:value="com.sameerasw.essentials.ui.activities.QSPreferencesActivity" />
<meta-data
android:name="android.service.quicksettings.TILE_CATEGORY"
android:value="android.service.quicksettings.CATEGORY_UTILITIES" />
</service>

<provider
android:name=".external.ExternalControlProvider"
android:authorities="${applicationId}.external"
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,16 @@ sealed interface Action {
override val isConfigurable: Boolean = true
}

@Keep
data class Keyboard(
@SerializedName("inputMethodId") val inputMethodId: String? = null
) : Action {
override val title: Int = R.string.diy_set_keyboard_title
override val icon: Int = R.drawable.rounded_keyboard_24
override val permissions: List<String> = listOf("WRITE_SECURE_SETTINGS")
override val isConfigurable: Boolean = true
}

@Keep
enum class SettingsTable {
@SerializedName("SYSTEM")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,8 @@ data class AutomationSuggestion(
val smartPixelsEnabled: Boolean? = null,

@Guide(description = "Dim wallpaper amount (0.0 to 1.0) for DimWallpaper action")
val dimWallpaperAmount: Float? = null
val dimWallpaperAmount: Float? = null,

@Guide(description = "Select keyboard from the list to switch")
val keyboard: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ import android.os.Build
import android.provider.Settings
import android.view.KeyEvent
import android.widget.Toast
import com.sameerasw.essentials.R
import com.sameerasw.essentials.domain.HapticFeedbackType
import com.sameerasw.essentials.domain.diy.Action
import com.sameerasw.essentials.services.tiles.ScreenOffAccessibilityService
import com.sameerasw.essentials.utils.DeviceLockUtils
import com.sameerasw.essentials.utils.PermissionUtils
import com.sameerasw.essentials.utils.ShellUtils
import com.sameerasw.essentials.utils.performHapticFeedback
import rikka.shizuku.ShizukuBinderWrapper
Expand Down Expand Up @@ -652,6 +654,19 @@ object CombinedActionExecutor {
com.sameerasw.essentials.utils.FreezeManager.unfreezeApp(context, pkg)
}
}

is Action.Keyboard -> {
try {
if (PermissionUtils.canWriteSecureSettings(context)) {
Settings.Secure.putString(context.contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD, action.inputMethodId)
return@withContext
}
Toast.makeText(context, R.string.diy_set_keyboard_permission_required, Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(context, "Keyboard Switching Failed: ${e.message ?: ""}", Toast.LENGTH_SHORT).show()
}
}

is Action.CustomSettings -> {
val resolver = context.contentResolver
for (entry in action.entries) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,17 @@ object QsTileRegistry {
R.string.tile_essentials_on_display,
R.drawable.rounded_live_tv_24,
EssentialsOnDisplayTileService::class.java
)
),
QsTileEntry(
R.string.tile_lockdown_mode,
R.drawable.rounded_shield_lock_24,
LockdownTileService::class.java
),
QsTileEntry(
R.string.tile_wifi_adb_title_short,
R.drawable.wireless_debugging_24,
WirelessDebugging::class.java
),
)

private val tilesMapByClassName: Map<String, QsTileEntry> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ package com.sameerasw.essentials.services.tiles

import android.content.Intent
import android.graphics.drawable.Icon
import android.os.Build
import android.provider.Settings
import android.service.quicksettings.Tile
import androidx.annotation.RequiresApi
import android.util.Log
import android.widget.Toast
import com.sameerasw.essentials.FeatureSettingsActivity
import com.sameerasw.essentials.R
import com.sameerasw.essentials.data.repository.SettingsRepository
import com.sameerasw.essentials.utils.PermissionUtils

@RequiresApi(Build.VERSION_CODES.N)
class UsbDebuggingTileService : BaseTileService() {

override fun onClick() {
Expand All @@ -37,14 +37,7 @@ class UsbDebuggingTileService : BaseTileService() {
override fun getTileLabel(): String = getString(R.string.tile_usb_debugging)

override fun getTileSubtitle(): String {
val usbOn = isUsbDebuggingEnabled()
val wifiOn = isWifiDebuggingEnabled()
return when {
usbOn && wifiOn -> "USB & WiFi"
usbOn -> "USB"
wifiOn -> "WiFi"
else -> getString(R.string.off)
}
return if (isUsbDebuggingEnabled()) getString(R.string.on) else getString(R.string.off)
}

override fun hasFeaturePermission(): Boolean {
Expand All @@ -56,18 +49,11 @@ class UsbDebuggingTileService : BaseTileService() {
}

override fun getTileState(): Int {
val usbOn = isUsbDebuggingEnabled()
val wifiOn = isWifiDebuggingEnabled()
return if (usbOn && wifiOn) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
return if (isUsbDebuggingEnabled()) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
}

override fun onTileClick() {
val usbOn = isUsbDebuggingEnabled()
val wifiOn = isWifiDebuggingEnabled()

val newState = if (usbOn && wifiOn) 0 else 1
setUsbDebuggingEnabled(newState == 1)
setWifiDebuggingEnabled(newState == 1)
setUsbDebuggingEnabled(!isUsbDebuggingEnabled())
}

private fun isUsbDebuggingEnabled(): Boolean {
Expand All @@ -80,25 +66,48 @@ class UsbDebuggingTileService : BaseTileService() {

private fun setUsbDebuggingEnabled(enabled: Boolean) {
try {
Settings.Global.putInt(contentResolver, Settings.Global.ADB_ENABLED, if (enabled) 1 else 0)
if (!enabled) {
toggleShizuku(false)
}
Settings.Global.putInt(
contentResolver,
Settings.Global.ADB_ENABLED,
if (enabled) 1 else 0
)
if (enabled) {
toggleShizuku(true)
}
} catch (e: Exception) {
e.printStackTrace()
}
}

private fun isWifiDebuggingEnabled(): Boolean {
return try {
Settings.Global.getInt(contentResolver, "adb_wifi_enabled", 0) == 1
} catch (e: Exception) {
false
}
private fun getShizukuToken(): String {
return SettingsRepository(this).getShizukuAuthToken()
}

private fun setWifiDebuggingEnabled(enabled: Boolean) {
try {
Settings.Global.putInt(contentResolver, "adb_wifi_enabled", if (enabled) 1 else 0)
} catch (e: Exception) {
e.printStackTrace()
private fun toggleShizuku(enabled: Boolean) {
val token = getShizukuToken()
val action =
if (enabled) "moe.shizuku.privileged.api.START" else "moe.shizuku.privileged.api.STOP"

if (token.isEmpty()) {
Toast.makeText(
this,
this.getString(R.string.toast_enter_shizuku_token),
Toast.LENGTH_LONG
).show()
} else {
try {
val shizukuIntent = Intent(action).apply {
`package` = "moe.shizuku.privileged.api"
putExtra("auth", token)
addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
}
this.sendBroadcast(shizukuIntent)
} catch (e: Exception) {
Log.e("ShizukuActionReceiver", "Failed to restart Shizuku", e)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.sameerasw.essentials.services.tiles

import android.app.PendingIntent
import android.content.Intent
import android.graphics.drawable.Icon
import android.os.Build
import android.provider.Settings
import android.service.quicksettings.Tile
import com.sameerasw.essentials.FeatureSettingsActivity
import com.sameerasw.essentials.R
import com.sameerasw.essentials.utils.PermissionUtils

class WirelessDebugging : BaseTileService() {
override fun onClick() {
if (!hasFeaturePermission()) {
val intent = Intent(this, FeatureSettingsActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
putExtra("feature", "Quick settings tiles")
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
startActivityAndCollapse(intent)
return
}
val pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
startActivityAndCollapse(pendingIntent)
return
}
super.onClick()
}

override fun onTileClick() = setWifiDebuggingEnabled(!isWifiDebuggingEnabled())

override fun getTileLabel() = getString(R.string.tile_wifi_adb_title_short)

override fun getTileSubtitle(): String {
return if (isWifiDebuggingEnabled()) getString(R.string.on) else getString(R.string.off)
}

override fun hasFeaturePermission() = PermissionUtils.canWriteSecureSettings(this)

override fun getTileIcon(): Icon {
return Icon.createWithResource(this, R.drawable.wireless_debugging_24)
}

override fun getTileState(): Int {
return if (isWifiDebuggingEnabled()) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
}

private fun isWifiDebuggingEnabled(): Boolean {
return try {
Settings.Global.getInt(contentResolver, "adb_wifi_enabled", 0) == 1
} catch (e: Exception) {
false
}
}

private fun setWifiDebuggingEnabled(enabled: Boolean) {
try {
Settings.Global.putInt(contentResolver, "adb_wifi_enabled", if (enabled) 1 else 0)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
Loading
Loading