Skip to content
Merged
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 @@ -10,6 +10,7 @@ import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
Expand Down Expand Up @@ -164,6 +165,7 @@ class FeatureSettingsActivity : FragmentActivity() {
remember(context) { viewModel.check(context) }

val isPitchBlackThemeEnabled by viewModel.isPitchBlackThemeEnabled
val isBlurEnabled by viewModel.isBlurEnabled
val pinnedFeatureKeys by viewModel.pinnedFeatureKeys

EssentialsTheme(pitchBlackTheme = isPitchBlackThemeEnabled) {
Expand Down Expand Up @@ -318,25 +320,35 @@ class FeatureSettingsActivity : FragmentActivity() {
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainer)
.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
)
} else Modifier
)
) {
val hasScroll = featureId != "Sound mode tile" && featureId != "Quick settings tiles"
Column(
modifier = Modifier
.fillMaxSize()
.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
)
} else Modifier
)
.then(if (hasScroll) Modifier.verticalScroll(rememberScrollState()) else Modifier)
) {
// Top padding for status bar
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(statusBarHeight))
if (featureId != "Quick settings tiles") {
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(statusBarHeight))
}

if (featureId == "Watch") {
WatchSettingsUI(
Expand Down Expand Up @@ -533,8 +545,12 @@ class FeatureSettingsActivity : FragmentActivity() {

"Quick settings tiles" -> {
QuickSettingsTilesSettingsUI(
modifier = Modifier.padding(top = 16.dp),
highlightSetting = highlightSetting
modifier = Modifier.fillMaxSize(),
highlightSetting = highlightSetting,
contentPadding = PaddingValues(
top = statusBarHeight,
bottom = 150.dp
)
)
}

Expand Down Expand Up @@ -620,7 +636,9 @@ class FeatureSettingsActivity : FragmentActivity() {

}
// Bottom padding for toolbar
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(150.dp))
if (featureId != "Quick settings tiles") {
androidx.compose.foundation.layout.Spacer(modifier = Modifier.height(150.dp))
}
}

SettingsFloatingToolbar(
Expand Down
25 changes: 17 additions & 8 deletions app/src/main/java/com/sameerasw/essentials/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ class MainActivity : FragmentActivity() {
viewModel.check(this)
setContent {
val isPitchBlackThemeEnabled by viewModel.isPitchBlackThemeEnabled
val isBlurEnabled by viewModel.isBlurEnabled
EssentialsTheme(pitchBlackTheme = isPitchBlackThemeEnabled) {
androidx.compose.runtime.CompositionLocalProvider(
com.sameerasw.essentials.ui.state.LocalMenuStateManager provides remember { com.sameerasw.essentials.ui.state.MenuStateManager() }
Expand Down Expand Up @@ -451,10 +452,14 @@ class MainActivity : FragmentActivity() {
Box(
modifier = Modifier
.fillMaxSize()
.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
)
} else Modifier
)
) {
val currentTab = remember(tabs, currentPage) {
Expand Down Expand Up @@ -609,10 +614,14 @@ class MainActivity : FragmentActivity() {
modifier = Modifier
.scale(1f - (backProgress.value * 0.05f))
.alpha(1f - (backProgress.value * 0.3f))
.progressiveBlur(
blurRadius = 40f,
height = with(androidx.compose.ui.platform.LocalDensity.current) { 130.dp.toPx() },
direction = BlurDirection.BOTTOM
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = with(androidx.compose.ui.platform.LocalDensity.current) { 130.dp.toPx() },
direction = BlurDirection.BOTTOM
)
} else Modifier
),
label = "Tab Transition"
) { targetPage ->
Expand Down
33 changes: 25 additions & 8 deletions app/src/main/java/com/sameerasw/essentials/SettingsActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,20 @@ class SettingsActivity : ComponentActivity() {
}
val statusBarHeight = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()

val isBlurEnabled by viewModel.isBlurEnabled

Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainer)
.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
)
} else Modifier
)
) {
val contentPadding = androidx.compose.foundation.layout.PaddingValues(
Expand All @@ -152,10 +158,14 @@ class SettingsActivity : ComponentActivity() {
viewModel = viewModel,
contentPadding = contentPadding,
modifier = Modifier
.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
)
} else Modifier
)
)

Expand Down Expand Up @@ -342,6 +352,13 @@ fun SettingsContent(
isChecked = viewModel.isPitchBlackThemeEnabled.value,
onCheckedChange = { viewModel.setPitchBlackThemeEnabled(it, context) }
)
IconToggleItem(
iconRes = R.drawable.rounded_blur_on_24,
title = "Use blur",
description = "Enable progressive blur elements across the UI",
isChecked = viewModel.isBlurEnabled.value,
onCheckedChange = { viewModel.setBlurEnabled(it, context) }
)
IconToggleItem(
iconRes = R.drawable.rounded_numbers_24,
title = stringResource(R.string.setting_use_root_title),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class SettingsRepository(private val context: Context) {
const val KEY_NOTIFICATION_GLANCE_SELECTED_APPS = "notification_glance_selected_apps"
const val KEY_AOD_FORCE_TURN_OFF_ENABLED = "aod_force_turn_off_enabled"
const val KEY_AUTO_ACCESSIBILITY_ENABLED = "auto_accessibility_enabled"
const val KEY_USE_BLUR = "use_blur"
}

// Observe changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.service.quicksettings.Tile
import androidx.annotation.RequiresApi
import com.sameerasw.essentials.R
import com.sameerasw.essentials.data.repository.SettingsRepository
import com.sameerasw.essentials.utils.ShellUtils

@RequiresApi(Build.VERSION_CODES.N)
class AlwaysOnDisplayTileService : BaseTileService() {
Expand All @@ -24,7 +25,8 @@ class AlwaysOnDisplayTileService : BaseTileService() {
}

override fun hasFeaturePermission(): Boolean {
return checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED
return com.sameerasw.essentials.utils.PermissionUtils.canWriteSecureSettings(this) ||
(ShellUtils.isAvailable(this) && ShellUtils.hasPermission(this))
}

override fun getTileIcon(): Icon? {
Expand Down Expand Up @@ -60,11 +62,11 @@ class AlwaysOnDisplayTileService : BaseTileService() {
}

private fun isAodEnabled(): Boolean {
return Settings.Secure.getInt(contentResolver, "doze_always_on", 0) == 1
return getSecureInt("doze_always_on", 0) == 1
}

private fun setAodEnabled(enabled: Boolean) {
Settings.Secure.putInt(contentResolver, "doze_always_on", if (enabled) 1 else 0)
putSecureInt("doze_always_on", if (enabled) 1 else 0)
}

private fun isGlanceEnabled(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.annotation.RequiresApi
import com.sameerasw.essentials.FeatureSettingsActivity
import com.sameerasw.essentials.R
import com.sameerasw.essentials.utils.PermissionUtils
import com.sameerasw.essentials.utils.ShellUtils

@RequiresApi(Build.VERSION_CODES.N)
class ChargeQuickTileService : BaseTileService() {
Expand Down Expand Up @@ -77,9 +78,7 @@ class ChargeQuickTileService : BaseTileService() {
}

override fun hasFeaturePermission(): Boolean {
return PermissionUtils.canWriteSecureSettings(this) &&
com.sameerasw.essentials.utils.ShellUtils.hasPermission(this) &&
com.sameerasw.essentials.utils.ShellUtils.isAvailable(this)
return ShellUtils.isAvailable(this) && ShellUtils.hasPermission(this)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ class MonoAudioTileService : BaseTileService() {
}

override fun hasFeaturePermission(): Boolean {
// Private secure settings can only be modified by ADB, system apps, or
// apps with a target sdk of Android 5.1 and lower.
return com.sameerasw.essentials.utils.ShellUtils.hasPermission(this) && com.sameerasw.essentials.utils.ShellUtils.isAvailable(
this
)
return com.sameerasw.essentials.utils.PermissionUtils.canWriteSecureSettings(this) ||
(com.sameerasw.essentials.utils.ShellUtils.isAvailable(this) &&
com.sameerasw.essentials.utils.ShellUtils.hasPermission(this))
}

override fun getTileIcon(): Icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.os.Build
import android.service.quicksettings.Tile
import androidx.annotation.RequiresApi
import com.sameerasw.essentials.R
import com.sameerasw.essentials.utils.ShellUtils
import java.lang.reflect.Method

@RequiresApi(Build.VERSION_CODES.N)
Expand Down Expand Up @@ -55,8 +56,8 @@ class NfcTileService : BaseTileService() {
}

override fun hasFeaturePermission(): Boolean {
// We need WRITE_SECURE_SETTINGS to toggle NFC via reflection
return checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) == android.content.pm.PackageManager.PERMISSION_GRANTED
return com.sameerasw.essentials.utils.PermissionUtils.canWriteSecureSettings(this) ||
(ShellUtils.isAvailable(this) && ShellUtils.hasPermission(this))
}

override fun getTileIcon(): Icon {
Expand All @@ -80,8 +81,10 @@ class NfcTileService : BaseTileService() {
val method: Method = nfcAdapter.javaClass.getMethod(methodName)
method.invoke(nfcAdapter) as Boolean
} catch (e: Exception) {
e.printStackTrace()
false
// Fallback to shell if reflection fails
val command = if (enable) "svc nfc enable" else "svc nfc disable"
ShellUtils.runCommand(context, command)
true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class YourAndroidActivity : ComponentActivity() {
setContent {
val mainViewModel: com.sameerasw.essentials.viewmodels.MainViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
val isPitchBlackThemeEnabled by mainViewModel.isPitchBlackThemeEnabled
val isBlurEnabled by mainViewModel.isBlurEnabled

val viewModel: YourAndroidViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
val deviceSpecs by viewModel.deviceSpecs.collectAsState()
Expand All @@ -143,10 +144,14 @@ class YourAndroidActivity : ComponentActivity() {
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainer)
.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = statusBarHeightPx * 1.15f,
direction = BlurDirection.TOP
)
} else Modifier
)
) {
YourAndroidContent(
Expand Down Expand Up @@ -191,9 +196,11 @@ fun YourAndroidContent(
}
}

val mainViewModel: com.sameerasw.essentials.viewmodels.MainViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
val configuration = LocalConfiguration.current
val screenHeight = configuration.screenHeightDp.dp
val initialImageOffset = (screenHeight / 2) - 240.dp - 64.dp
val isBlurEnabled by mainViewModel.isBlurEnabled

val imageOffsetState = animateDpAsState(
targetValue = if (isStartupAnimationRunning) 0.dp else initialImageOffset,
Expand All @@ -220,10 +227,14 @@ fun YourAndroidContent(
Column(
modifier = modifier
.fillMaxSize()
.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
.then(
if (isBlurEnabled) {
Modifier.progressiveBlur(
blurRadius = 40f,
height = with(LocalDensity.current) { 150.dp.toPx() },
direction = BlurDirection.BOTTOM
)
} else Modifier
)
.verticalScroll(rememberScrollState())
.padding(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import com.sameerasw.essentials.ui.components.menus.SegmentedDropdownMenu
import com.sameerasw.essentials.ui.components.menus.SegmentedDropdownMenuItem
import androidx.compose.foundation.layout.RowScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalView
import com.sameerasw.essentials.utils.HapticUtil

@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
Expand All @@ -42,6 +44,7 @@ fun SettingsFloatingToolbar(
menuContent: (@Composable SettingsMenuScope.() -> Unit)? = null
) {
var menuExpanded by remember { mutableStateOf(false) }
val view = LocalView.current

if (menuContent != null) {
HorizontalFloatingToolbar(
Expand All @@ -52,7 +55,10 @@ fun SettingsFloatingToolbar(
floatingActionButton = {
Box {
FloatingActionButton(
onClick = { menuExpanded = true },
onClick = {
HapticUtil.performVirtualKeyHaptic(view)
menuExpanded = true
},
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
shape = MaterialTheme.shapes.large,
Expand Down Expand Up @@ -104,8 +110,12 @@ private fun RowScope.ToolbarContent(
title: String,
onBackClick: () -> Unit
) {
val view = LocalView.current
IconButton(
onClick = onBackClick,
onClick = {
HapticUtil.performVirtualKeyHaptic(view)
onBackClick()
},
modifier = Modifier.align(Alignment.CenterVertically),
colors = IconButtonDefaults.filledIconButtonColors(
contentColor = MaterialTheme.colorScheme.primary,
Expand Down
Loading