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
11 changes: 3 additions & 8 deletions app/src/main/kotlin/com/dev/debloater/AppDetailsScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.ui.graphics.asImageBitmap
import androidx.core.graphics.drawable.toBitmap

private fun SafetyLevel.badgeColorScheme(): Pair<Color, Color> =
when (this) {
Expand Down Expand Up @@ -48,10 +46,7 @@ fun AppDetailsScreen(
var isDisabling by remember { mutableStateOf(false) }
var isUninstalling by remember { mutableStateOf(false) }
var isRestoring by remember { mutableStateOf(false) }
val appIconBitmap = remember(appData.icon) {
appData.icon?.toBitmap(width = 240, height = 240)?.asImageBitmap()
}


Scaffold(
topBar = {
TopAppBar(
Expand All @@ -78,9 +73,9 @@ fun AppDetailsScreen(
.background(MaterialTheme.colorScheme.surfaceVariant),
contentAlignment = Alignment.Center
) {
if (appIconBitmap != null) {
if (appData.icon != null) {
Image(
bitmap = appIconBitmap,
bitmap = appData.icon,
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Fit
Expand Down
108 changes: 52 additions & 56 deletions app/src/main/kotlin/com/dev/debloater/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import android.app.Activity
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
Expand Down Expand Up @@ -41,6 +40,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
Expand All @@ -50,7 +50,6 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.key
import androidx.core.graphics.drawable.toBitmap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -98,11 +97,10 @@ fun DebloaterTheme(
MaterialTheme(colorScheme = scheme, content = content)
}

@Immutable
data class AppData(
val packageName: String,
val appName: String,
val icon: Drawable?,
val icon: ImageBitmap?,
val isSystem: Boolean,
val isInstalled: Boolean,
val isDisabled: Boolean,
Expand Down Expand Up @@ -287,53 +285,51 @@ fun DebloaterScreen(snackbarHostState: SnackbarHostState) {
key = { it.packageName },
contentType = { "app_item" }
) { appData ->
key(appData.packageName) {
AppListItem(
appData = appData,
onClick = {
selectedApp = appData
currentScreen = "details"
},
onToggle = { appData, isDisabled ->
if (!isDisabled && appData.safetyLevel == SafetyLevel.RISKY) {
riskyOverrideAction = ConfirmAction(
action = "disable",
packageName = appData.packageName,
appName = appData.appName
)
} else {
confirmAction =
if (isDisabled) {
ConfirmAction(
action = "enable",
packageName = appData.packageName,
appName = appData.appName
)
} else {
ConfirmAction(
action = "disable",
packageName = appData.packageName,
appName = appData.appName
)
}
}
},
onUninstall = { appDataToRemove ->
confirmAction = ConfirmAction(
action = "uninstall",
packageName = appDataToRemove.packageName,
appName = appDataToRemove.appName
)
},
onRestore = { appDataToRestore ->
confirmAction = ConfirmAction(
action = "restore",
packageName = appDataToRestore.packageName,
appName = appDataToRestore.appName
AppListItem(
appData = appData,
onClick = {
selectedApp = appData
currentScreen = "details"
},
onToggle = { appData, isDisabled ->
if (!isDisabled && appData.safetyLevel == SafetyLevel.RISKY) {
riskyOverrideAction = ConfirmAction(
action = "disable",
packageName = appData.packageName,
appName = appData.appName
)
} else {
confirmAction =
if (isDisabled) {
ConfirmAction(
action = "enable",
packageName = appData.packageName,
appName = appData.appName
)
} else {
ConfirmAction(
action = "disable",
packageName = appData.packageName,
appName = appData.appName
)
}
}
)
}
},
onUninstall = { appDataToRemove ->
confirmAction = ConfirmAction(
action = "uninstall",
packageName = appDataToRemove.packageName,
appName = appDataToRemove.appName
)
},
onRestore = { appDataToRestore ->
confirmAction = ConfirmAction(
action = "restore",
packageName = appDataToRestore.packageName,
appName = appDataToRestore.appName
)
}
)
}
}
}
Expand Down Expand Up @@ -792,9 +788,6 @@ fun AppListItem(
onUninstall: (AppData) -> Unit,
onRestore: (AppData) -> Unit
) {
val appIconBitmap = remember(appData.icon) {
appData.icon?.toBitmap(width = 80, height = 80)?.asImageBitmap()
}
Surface(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -813,9 +806,9 @@ fun AppListItem(
modifier = Modifier.size(40.dp),
contentAlignment = Alignment.Center
) {
if (appIconBitmap != null) {
if (appData.icon != null) {
Image(
bitmap = appIconBitmap,
bitmap = appData.icon,
contentDescription = null,
modifier = Modifier.size(40.dp),
contentScale = ContentScale.Fit
Expand Down Expand Up @@ -1008,8 +1001,11 @@ private suspend fun loadAllAppDataWithIcons(
appName = appInfo?.let {
runCatching { it.loadLabel(pm).toString() }.getOrNull()
} ?: pkg.packageName,
icon = runCatching { appInfo?.loadIcon(pm) ?: pm.getApplicationIcon(pkg.packageName) }
.getOrNull(),
icon = runCatching {
(appInfo?.loadIcon(pm) ?: pm.getApplicationIcon(pkg.packageName))
.toBitmap(width = 80, height = 80)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode detail icons at display resolution

loadAllAppDataWithIcons now always rasterizes app icons to 80x80, but AppDetailsScreen renders that same bitmap in a 120.dp avatar (larger than 80 physical pixels on most devices), so icons are upscaled and visibly blurry in the details view. This is a regression from the previous details-specific conversion path and affects all high-density screens; decode a larger bitmap for detail usage (or keep separate sizes) to avoid quality loss.

Useful? React with 👍 / 👎.

.asImageBitmap()
}.getOrNull(),
isSystem = appInfo?.let {
it.flags and ApplicationInfo.FLAG_SYSTEM != 0 ||
it.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP != 0
Expand Down
Loading