Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
69 changes: 66 additions & 3 deletions app/src/main/java/com/sameerasw/essentials/domain/diy/Action.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ sealed interface Action {
) : Action {
override val title: Int get() = R.string.diy_action_dim_wallpaper
override val icon: Int get() = R.drawable.rounded_mobile_screensaver_24
override val permissions: List<String> = listOf("shizuku", "root")
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
override val isConfigurable: Boolean = true
}

Expand All @@ -74,7 +74,7 @@ sealed interface Action {
) : Action {
override val title: Int get() = R.string.diy_action_device_effects
override val icon: Int get() = R.drawable.rounded_bed_24
override val permissions: List<String> = listOf("notification_policy")
override val permissions: List<String> = listOf("NOTIFICATION_POLICY")
override val isConfigurable: Boolean = true
}

Expand All @@ -101,7 +101,7 @@ sealed interface Action {
SoundModeType.VIBRATE -> R.drawable.rounded_mobile_vibrate_24
SoundModeType.SILENT -> R.drawable.rounded_volume_off_24
}
override val permissions: List<String> = listOf("notification_policy")
override val permissions: List<String> = listOf("NOTIFICATION_POLICY")
override val isConfigurable: Boolean = true
}

Expand All @@ -116,4 +116,67 @@ sealed interface Action {
override val title: Int = R.string.diy_action_low_power_off
override val icon: Int = R.drawable.rounded_battery_android_frame_shield_24
}

@Keep
data object TurnOnWifi : Action {
override val title: Int = R.string.diy_action_wifi_on
override val icon: Int = R.drawable.rounded_android_wifi_4_bar_plus_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
}

@Keep
data object TurnOffWifi : Action {
override val title: Int = R.string.diy_action_wifi_off
override val icon: Int = R.drawable.rounded_android_wifi_4_bar_plus_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
}

@Keep
data object TurnOnCellularData : Action {
override val title: Int = R.string.diy_action_cellular_on
override val icon: Int = R.drawable.rounded_signal_cellular_alt_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
}

@Keep
data object TurnOffCellularData : Action {
override val title: Int = R.string.diy_action_cellular_off
override val icon: Int = R.drawable.rounded_signal_cellular_alt_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
}

@Keep
data object TurnOnAutoBrightness : Action {
override val title: Int = R.string.diy_action_auto_brightness_on
override val icon: Int = R.drawable.rounded_brightness_auto_24
override val permissions: List<String> = listOf("WRITE_SETTINGS")
}

@Keep
data object TurnOffAutoBrightness : Action {
override val title: Int = R.string.diy_action_auto_brightness_off
override val icon: Int = R.drawable.rounded_brightness_auto_24
override val permissions: List<String> = listOf("WRITE_SETTINGS")
}

@Keep
data class FreezeApps(
@SerializedName("packageNames") val packageNames: List<String> = emptyList()
) : Action {
override val title: Int get() = R.string.diy_action_freeze_apps
override val icon: Int get() = R.drawable.rounded_mode_cool_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
override val isConfigurable: Boolean = true
}

@Keep
data class UnfreezeApps(
@SerializedName("packageNames") val packageNames: List<String> = emptyList()
) : Action {
override val title: Int get() = R.string.diy_action_unfreeze_apps
override val icon: Int get() = R.drawable.rounded_mode_cool_off_24
override val permissions: List<String> = listOf("SHIZUKU", "ROOT")
override val isConfigurable: Boolean = true
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,25 @@ object CombinedActionExecutor {
e.printStackTrace()
}
}

is Action.TurnOnWifi -> setWifiEnabled(context, true)
is Action.TurnOffWifi -> setWifiEnabled(context, false)
is Action.TurnOnCellularData -> setCellularDataEnabled(context, true)
is Action.TurnOffCellularData -> setCellularDataEnabled(context, false)
is Action.TurnOnAutoBrightness -> setAutoBrightnessEnabled(context, true)
is Action.TurnOffAutoBrightness -> setAutoBrightnessEnabled(context, false)
is Action.FreezeApps -> {
action.packageNames.forEach { pkg ->
com.sameerasw.essentials.utils.FreezeManager.freezeApp(context, pkg)
}
}
is Action.UnfreezeApps -> {
action.packageNames.forEach { pkg ->
com.sameerasw.essentials.utils.FreezeManager.unfreezeApp(context, pkg)
}
}
}

}
}

Expand All @@ -217,4 +235,30 @@ object CombinedActionExecutor {
e.printStackTrace()
}
}

private fun setWifiEnabled(context: Context, enabled: Boolean) {
val state = if (enabled) "enable" else "disable"
com.sameerasw.essentials.utils.ShellUtils.runCommand(context, "svc wifi $state")
}

private fun setCellularDataEnabled(context: Context, enabled: Boolean) {
val state = if (enabled) "enable" else "disable"
com.sameerasw.essentials.utils.ShellUtils.runCommand(context, "svc data $state")
}

private fun setAutoBrightnessEnabled(context: Context, enabled: Boolean) {
val value = if (enabled) 1 else 0
try {
android.provider.Settings.System.putInt(
context.contentResolver,
android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE,
value
)
} catch (e: Exception) {
com.sameerasw.essentials.utils.ShellUtils.runCommand(
context,
"settings put system screen_brightness_mode $value"
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.os.Looper
import android.provider.Settings
import android.util.Log
import androidx.core.app.NotificationCompat
import android.view.inputmethod.InputMethodManager
import com.google.gson.Gson
import com.sameerasw.essentials.domain.diy.Automation
import com.sameerasw.essentials.domain.diy.DIYRepository
Expand Down Expand Up @@ -92,10 +93,28 @@ class AppFlowHandler(
"com.google.android.inputmethod.latin"
)

private fun isSystemOrIme(packageName: String): Boolean {
if (ignoredSystemPackages.contains(packageName)) return true
return try {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
val ims = imm?.enabledInputMethodList
ims?.any { it.packageName == packageName } == true
} catch (_: Exception) {
false
}
}

fun onPackageChanged(packageName: String, isFromUsageStats: Boolean = false) {
val prefs = context.getSharedPreferences("essentials_prefs", Context.MODE_PRIVATE)
val useUsageAccess = prefs.getBoolean("use_usage_access", false)

// If the new foreground window belongs to a system overlay (status bar, quick settings,
// notifications) or a keyboard (IME), completely ignore it. We do NOT update currentPackage
// so that state-dependent features (app lock timing, automation tracking) remain stable.
if (isSystemOrIme(packageName)) {
Log.d("AppFlowHandler", "onPackageChanged: Ignoring system/IME package $packageName")
return
}
val oldPackage = currentPackage
currentPackage = packageName

Expand Down Expand Up @@ -203,7 +222,7 @@ class AppFlowHandler(

pendingNLRunnable?.let { handler.removeCallbacks(it) }

if (ignoredSystemPackages.contains(packageName)) {
if (isSystemOrIme(packageName)) {
Log.d("NightLight", "Ignoring system package $packageName")
return
}
Expand Down Expand Up @@ -275,6 +294,10 @@ class AppFlowHandler(
}

private fun checkAppAutomations(packageName: String) {
if (isSystemOrIme(packageName)) {
Log.d("AppFlowHandler", "checkAppAutomations: Ignoring system/IME package $packageName")
return
}
scope.launch {
val automations = DIYRepository.automations.value
val appAutomations =
Expand Down
Loading