Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ object FeatureRegistry {
override fun isEnabled(viewModel: MainViewModel) = viewModel.isPocketModeEnabled.value

override fun onToggle(viewModel: MainViewModel, context: Context, enabled: Boolean) =
viewModel.setPocketModeEnabled(enabled)
viewModel.setPocketModeEnabled(enabled, context)

override fun isDeviceSupported(context: Context) = !DeviceUtils.isGoogleDevice()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ class AppFlowHandler(
private val handler = Handler(Looper.getMainLooper())
private val scope = CoroutineScope(Dispatchers.Main)

private val authenticatedPackages = mutableSetOf<String>()
private val lastLeaveTimes = mutableMapOf<String, Long>()
private val activeCountdowns = mutableMapOf<String, Job>()

private val shutUpReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Expand Down Expand Up @@ -86,21 +83,11 @@ class AppFlowHandler(
}
}

// App Lock State
private var lockingPackage: String? = null
private var lastLockRequestTime: Long = 0
var currentPackage: String? = null
private set
private var currentUsageStatsPackage: String? = null
private val nlDebounceDelay = 500L

// App Automation State
private val activeAppAutomationIds = mutableSetOf<String>()
val currentPackage: String?
get() = Companion.currentPackage

// Night Light State
private var wasNightLightOnBeforeAutoToggle = false
private var isNightLightAutoToggledOff = false
private var pendingNLRunnable: Runnable? = null
private val nlDebounceDelay = 500L

private val ignoredSystemPackages = listOf(
"android",
Expand All @@ -114,7 +101,7 @@ class AppFlowHandler(

val oldPackage = currentPackage
if (isFromUsageStats == useUsageAccess) {
currentPackage = packageName
Companion.currentPackage = packageName
if (oldPackage != null && oldPackage != packageName) {
lastLeaveTimes[oldPackage] = System.currentTimeMillis()
checkShutUpRestore(oldPackage, packageName)
Expand All @@ -126,6 +113,12 @@ class AppFlowHandler(
checkHighlightNightLight(packageName)
checkAppAutomations(packageName)
checkGestureBarAutomation(packageName)

// Dismiss pocket mode if the new foreground package is bypassed/excluded
val serviceInstance = com.sameerasw.essentials.services.tiles.ScreenOffAccessibilityService.instance
if (serviceInstance != null && serviceInstance.isAppBypassedForPocketMode(packageName)) {
serviceInstance.dismissPocketMode()
}
}
}

Expand Down Expand Up @@ -840,5 +833,19 @@ class AppFlowHandler(
const val EXTRA_PACKAGE_NAME = "package_name"
const val EXTRA_AUTO_ARCHIVE_PACKAGE = "auto_archive_package"
const val NOTIFICATION_ID_SHUTUP_RESTORE = 9999

// Shared State
internal val authenticatedPackages = mutableSetOf<String>()
internal val lastLeaveTimes = mutableMapOf<String, Long>()
internal val activeCountdowns = mutableMapOf<String, Job>()
internal var lockingPackage: String? = null
internal var lastLockRequestTime: Long = 0
var currentPackage: String? = null
internal set
internal var currentUsageStatsPackage: String? = null
internal val activeAppAutomationIds = mutableSetOf<String>()
internal var wasNightLightOnBeforeAutoToggle = false
internal var isNightLightAutoToggledOff = false
internal var pendingNLRunnable: Runnable? = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,10 @@ class ScreenOffAccessibilityService : AccessibilityService(), SensorEventListene
statusBarIconHandler.updateAll()
} else if (key == "pocket_mode_enabled" || key == "pocket_mode_use_light_sensor") {
updatePocketModeSensors()
com.sameerasw.essentials.utils.ServiceUtils.startRequiredServices(this)
} else if (key == "pocket_mode_excluded_apps") {
updatePocketModeExcludedAppsSet()
com.sameerasw.essentials.utils.ServiceUtils.startRequiredServices(this)
}
}

Expand Down Expand Up @@ -389,6 +391,22 @@ class ScreenOffAccessibilityService : AccessibilityService(), SensorEventListene

override fun onInterrupt() {}

fun isAppBypassedForPocketMode(packageName: String?): Boolean {
val prefs = getSharedPreferences("essentials_prefs", MODE_PRIVATE)
val lockScreenOnly = prefs.getBoolean("pocket_mode_lock_screen_only", false)
val isExcluded = packageName != null && (
pocketModeExcludedAppsSet.contains(packageName) ||
isGameOrVideoApp(packageName) ||
hasActiveMediaSession(packageName)
)
val isKeyguardBypassed = lockScreenOnly && !keyguardManager.isKeyguardLocked
return isExcluded || isKeyguardBypassed
}

fun dismissPocketMode() {
pocketModeHandler.onScreenOff()
}

private fun updatePocketModeSensors() {
val prefs = getSharedPreferences("essentials_prefs", MODE_PRIVATE)
val pocketModeEnabled = prefs.getBoolean("pocket_mode_enabled", false)
Expand Down Expand Up @@ -434,15 +452,12 @@ class ScreenOffAccessibilityService : AccessibilityService(), SensorEventListene
val pocketModeEnabled = prefs.getBoolean("pocket_mode_enabled", false)
val useLightSensor = prefs.getBoolean("pocket_mode_use_light_sensor", false)
val triggerDelayMs = (prefs.getFloat("pocket_mode_trigger_delay", 3f) * 1000).toLong()
val lockScreenOnly = prefs.getBoolean("pocket_mode_lock_screen_only", false)
if (pocketModeEnabled && !pocketModeHandler.isBypassed) {
val currentApp = appFlowHandler.currentPackage
val shouldBypass = (currentApp != null && (
pocketModeExcludedAppsSet.contains(currentApp) ||
isGameOrVideoApp(currentApp) ||
hasActiveMediaSession(currentApp)
)) || (lockScreenOnly && !keyguardManager.isKeyguardLocked)
if (!shouldBypass) {
val shouldBypass = isAppBypassedForPocketMode(currentApp)
if (shouldBypass) {
pocketModeHandler.onScreenOff()
} else {
pocketModeHandler.onProximityChanged(
isBlocked = flashlightHandler.isProximityBlocked,
isLightDark = lightSensorLux <= 3f,
Expand Down Expand Up @@ -470,15 +485,12 @@ class ScreenOffAccessibilityService : AccessibilityService(), SensorEventListene
val pocketModeEnabled = prefs.getBoolean("pocket_mode_enabled", false)
val useLightSensor = prefs.getBoolean("pocket_mode_use_light_sensor", false)
val triggerDelayMs = (prefs.getFloat("pocket_mode_trigger_delay", 3f) * 1000).toLong()
val lockScreenOnly = prefs.getBoolean("pocket_mode_lock_screen_only", false)
if (pocketModeEnabled && !pocketModeHandler.isBypassed) {
val currentApp = appFlowHandler.currentPackage
val shouldBypass = (currentApp != null && (
pocketModeExcludedAppsSet.contains(currentApp) ||
isGameOrVideoApp(currentApp) ||
hasActiveMediaSession(currentApp)
)) || (lockScreenOnly && !keyguardManager.isKeyguardLocked)
if (!shouldBypass) {
val shouldBypass = isAppBypassedForPocketMode(currentApp)
if (shouldBypass) {
pocketModeHandler.onScreenOff()
} else {
pocketModeHandler.onProximityChanged(
isBlocked = isBlocked,
isLightDark = lightSensorLux <= 3f,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fun PocketModeSettingsUI(
description = stringResource(R.string.feat_pocket_mode_desc),
isChecked = viewModel.isPocketModeEnabled.value,
onCheckedChange = { isChecked ->
viewModel.setPocketModeEnabled(isChecked)
viewModel.setPocketModeEnabled(isChecked, context)
},
enabled = true,
iconRes = R.drawable.ic_pocket_mode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ object ServiceUtils {
val isUseUsageAccess =
settingsRepository.getBoolean(SettingsRepository.KEY_USE_USAGE_ACCESS)

val isPocketModeEnabled =
settingsRepository.getBoolean(SettingsRepository.KEY_POCKET_MODE_ENABLED)
val pocketModeExcludedApps = settingsRepository.loadPocketModeExcludedApps()
val hasPocketModeExcludedApps = isPocketModeEnabled && pocketModeExcludedApps.any { it.isEnabled }

val hasAppAutomations = DIYRepository.automations.value.any {
it.isEnabled && it.type == Automation.Type.APP
}
Expand All @@ -39,7 +44,7 @@ object ServiceUtils {
val hasShutUpApps = shutUpConfigs.any { it.isEnabled }

val shouldRun =
(isUseUsageAccess && (isAppLockEnabled || isDynamicNightLightEnabled || isHideGestureBarOnLauncherEnabled || hasAppAutomations)) || hasShutUpApps
(isUseUsageAccess && (isAppLockEnabled || isDynamicNightLightEnabled || isHideGestureBarOnLauncherEnabled || hasAppAutomations || hasPocketModeExcludedApps)) || hasShutUpApps

val intent = Intent(context, AppDetectionService::class.java)
if (shouldRun) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4015,9 +4015,10 @@ class MainViewModel : ViewModel() {
isAodForceTurnOffEnabled.value = enabled
}

fun setPocketModeEnabled(enabled: Boolean) {
fun setPocketModeEnabled(enabled: Boolean, context: Context) {
settingsRepository.putBoolean(SettingsRepository.KEY_POCKET_MODE_ENABLED, enabled)
isPocketModeEnabled.value = enabled
updateAppDetectionService(context)
}

fun setPocketModeUseLightSensor(enabled: Boolean) {
Expand Down Expand Up @@ -4065,6 +4066,7 @@ class MainViewModel : ViewModel() {

fun savePocketModeExcludedApps(context: Context, apps: List<AppSelection>) {
settingsRepository.savePocketModeExcludedApps(apps)
updateAppDetectionService(context)
}

fun updatePocketModeExcludedAppEnabled(
Expand All @@ -4073,6 +4075,7 @@ class MainViewModel : ViewModel() {
enabled: Boolean
) {
settingsRepository.updatePocketModeExcludedAppSelection(packageName, enabled)
updateAppDetectionService(context)
}

override fun onCleared() {
Expand Down