Improve icon search
This commit is contained in:
parent
bb8a0d4c0d
commit
9c5f1e971f
@ -79,14 +79,14 @@ sealed class CustomIcon : CustomAttribute {
|
||||
"custom_icon_pack_icon" -> {
|
||||
val legacyComponentName = payload.optString("icon").let { ComponentName.unflattenFromString(it) }
|
||||
if (legacyComponentName != null) {
|
||||
CustomIconPackIcon(
|
||||
LegacyCustomIconPackIcon(
|
||||
iconPackageName = legacyComponentName.packageName,
|
||||
iconActivityName = legacyComponentName.className,
|
||||
iconPackPackage = payload.getString("icon_pack"),
|
||||
allowThemed = payload.optBoolean("allow_themed", true),
|
||||
)
|
||||
} else {
|
||||
CustomIconPackIcon(
|
||||
LegacyCustomIconPackIcon(
|
||||
iconPackageName = payload.optString("package").takeIf { it.isNotEmpty() } ?: return null,
|
||||
iconActivityName = payload.optString("activity").takeIf { it.isNotEmpty() },
|
||||
iconPackPackage = payload.getString("icon_pack"),
|
||||
@ -94,6 +94,15 @@ sealed class CustomIcon : CustomAttribute {
|
||||
)
|
||||
}
|
||||
}
|
||||
"custom_icon_pack_icon2" -> {
|
||||
CustomIconPackIcon(
|
||||
iconPackPackage = payload.getString("icon_pack"),
|
||||
type = payload.getString("type"),
|
||||
drawable = payload.optString("drawable"),
|
||||
extras = payload.optString("extras").takeIf { it.isNotEmpty() },
|
||||
allowThemed = payload.optBoolean("allow_themed", true),
|
||||
)
|
||||
}
|
||||
"custom_themed_icon" -> {
|
||||
CustomThemedIcon(
|
||||
iconPackageName = payload.getString("icon"),
|
||||
@ -116,7 +125,8 @@ sealed class CustomIcon : CustomAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
data class CustomIconPackIcon(
|
||||
@Deprecated("Use CustomIconPackIcon instead")
|
||||
data class LegacyCustomIconPackIcon(
|
||||
val iconPackPackage: String,
|
||||
val iconPackageName: String,
|
||||
val iconActivityName: String?,
|
||||
@ -133,6 +143,28 @@ data class CustomIconPackIcon(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [type], [drawable], and [extras] correspond to the fields in [IconEntity]
|
||||
*/
|
||||
data class CustomIconPackIcon(
|
||||
val iconPackPackage: String,
|
||||
val type: String,
|
||||
val drawable: String?,
|
||||
val extras: String?,
|
||||
val allowThemed: Boolean,
|
||||
): CustomIcon() {
|
||||
override fun toDatabaseValue(): String {
|
||||
return jsonObjectOf(
|
||||
"type" to "custom_icon_pack_icon2",
|
||||
"icon_pack" to iconPackPackage,
|
||||
"type" to type,
|
||||
"drawable" to drawable,
|
||||
"extras" to extras,
|
||||
"allow_themed" to allowThemed,
|
||||
).toString()
|
||||
}
|
||||
}
|
||||
|
||||
data class AdaptifiedLegacyIcon(
|
||||
val fgScale: Float,
|
||||
/**
|
||||
@ -173,7 +205,7 @@ data class CustomThemedIcon(
|
||||
}
|
||||
}
|
||||
|
||||
object ForceThemedIcon : CustomIcon() {
|
||||
data object ForceThemedIcon : CustomIcon() {
|
||||
override fun toDatabaseValue(): String {
|
||||
return jsonObjectOf(
|
||||
"type" to "force_themed_icon"
|
||||
@ -184,19 +216,18 @@ object ForceThemedIcon : CustomIcon() {
|
||||
/**
|
||||
* Use default icon, ignore any icon pack, themed icon or force adaptive settings.
|
||||
*/
|
||||
object UnmodifiedSystemDefaultIcon: CustomIcon() {
|
||||
data object UnmodifiedSystemDefaultIcon: CustomIcon() {
|
||||
override fun toDatabaseValue(): String {
|
||||
return jsonObjectOf(
|
||||
"type" to "default_icon"
|
||||
).toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the default placeholder icon
|
||||
*/
|
||||
object DefaultPlaceholderIcon: CustomIcon() {
|
||||
data object DefaultPlaceholderIcon: CustomIcon() {
|
||||
override fun toDatabaseValue(): String {
|
||||
return jsonObjectOf(
|
||||
"type" to "default_placeholder_icon"
|
||||
|
||||
@ -13,12 +13,14 @@ interface IconDao {
|
||||
@Query("SELECT * FROM Icons WHERE packageName = :packageName AND (activityName = :activityName OR activityName IS NULL) AND iconPack = :iconPack AND type IN ('app', 'calendar', 'clock') ORDER BY type DESC LIMIT 1")
|
||||
suspend fun getIcon(packageName: String, activityName: String?, iconPack: String): IconEntity?
|
||||
|
||||
@Query("SELECT * FROM Icons WHERE drawable = :iconName AND iconPack = :iconPack ORDER BY type DESC LIMIT 1")
|
||||
suspend fun getIcon(iconName: String, iconPack: String): IconEntity?
|
||||
|
||||
@Query("SELECT * FROM Icons WHERE packageName = :packageName AND (activityName = :activityName OR activityName IS NULL) AND type IN ('app', 'calendar', 'clock')")
|
||||
suspend fun getIconsFromAllPacks(packageName: String, activityName: String): List<IconEntity>
|
||||
|
||||
@Query("SELECT * FROM Icons WHERE type IN ('app', 'calendar', 'clock') AND (drawable LIKE :drawableQuery OR packageName LIKE :componentQuery OR activityName LIKE :componentQuery OR name LIKE :nameQuery) AND (:iconPack IS NULL OR iconPack = :iconPack) GROUP BY drawable ORDER BY iconPack, drawable LIMIT :limit")
|
||||
@Query("SELECT * FROM Icons WHERE type IN ('app', 'calendar', 'clock') AND (drawable LIKE :drawableQuery OR name LIKE :nameQuery) AND (:iconPack IS NULL OR iconPack = :iconPack) GROUP BY drawable, iconPack, type ORDER BY type DESC, iconPack, drawable LIMIT :limit")
|
||||
suspend fun searchIconPackIcons(
|
||||
componentQuery: String,
|
||||
nameQuery: String,
|
||||
drawableQuery: String,
|
||||
iconPack: String?,
|
||||
|
||||
@ -11,7 +11,7 @@ sealed interface IconPackComponent {
|
||||
}
|
||||
|
||||
sealed interface IconPackAppIcon: IconPackComponent {
|
||||
val packageName: String
|
||||
val packageName: String?
|
||||
val activityName: String?
|
||||
val name: String?
|
||||
val themed: Boolean
|
||||
@ -59,9 +59,9 @@ data class IconMask(
|
||||
data class AppIcon(
|
||||
val drawable: String,
|
||||
override val iconPack: String,
|
||||
override val packageName: String,
|
||||
override val activityName: String?,
|
||||
override val name: String?,
|
||||
override val packageName: String? = null,
|
||||
override val activityName: String? = null,
|
||||
override val name: String? = null,
|
||||
override val themed: Boolean = false,
|
||||
): IconPackComponent, IconPackAppIcon {
|
||||
override fun toDatabaseEntity(): IconEntity {
|
||||
@ -80,7 +80,7 @@ data class AppIcon(
|
||||
data class CalendarIcon(
|
||||
val drawables: List<String>,
|
||||
override val iconPack: String,
|
||||
override val packageName: String,
|
||||
override val packageName: String?,
|
||||
override val activityName: String? = null,
|
||||
override val name: String? = null,
|
||||
override val themed: Boolean = false,
|
||||
@ -102,7 +102,7 @@ data class CalendarIcon(
|
||||
data class ClockIcon(
|
||||
val drawable: String,
|
||||
override val iconPack: String,
|
||||
override val packageName: String,
|
||||
override val packageName: String? = null,
|
||||
override val activityName: String? = null,
|
||||
override val name: String? = null,
|
||||
override val themed: Boolean,
|
||||
@ -146,7 +146,7 @@ fun Icon(entity: IconEntity): IconPackComponent? {
|
||||
"app" -> AppIcon(
|
||||
drawable = entity.drawable ?: return null,
|
||||
iconPack = entity.iconPack,
|
||||
packageName = entity.packageName ?: return null,
|
||||
packageName = entity.packageName,
|
||||
activityName = entity.activityName,
|
||||
themed = entity.themed,
|
||||
name = entity.name,
|
||||
@ -155,7 +155,7 @@ fun Icon(entity: IconEntity): IconPackComponent? {
|
||||
drawables = entity.drawable?.split(",") ?: return null,
|
||||
iconPack = entity.iconPack,
|
||||
themed = entity.themed,
|
||||
packageName = entity.packageName ?: return null,
|
||||
packageName = entity.packageName,
|
||||
activityName = entity.activityName,
|
||||
name = entity.name,
|
||||
)
|
||||
@ -164,7 +164,7 @@ fun Icon(entity: IconEntity): IconPackComponent? {
|
||||
ClockIcon(
|
||||
drawable = entity.drawable!!,
|
||||
iconPack = entity.iconPack,
|
||||
packageName = entity.packageName ?: return null,
|
||||
packageName = entity.packageName,
|
||||
name = entity.name,
|
||||
activityName = entity.activityName,
|
||||
themed = entity.themed,
|
||||
|
||||
@ -112,6 +112,27 @@ class IconPackManager(
|
||||
return@withContext null
|
||||
}
|
||||
|
||||
suspend fun getIcon(
|
||||
iconPack: String,
|
||||
icon: IconPackAppIcon,
|
||||
allowThemed: Boolean,
|
||||
): LauncherIcon? = withContext(Dispatchers.IO) {
|
||||
val res = try {
|
||||
context.packageManager.getResourcesForApplication(iconPack)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.e("MM20", "Icon pack package $iconPack not found!")
|
||||
return@withContext null
|
||||
}
|
||||
if (icon is CalendarIcon) {
|
||||
return@withContext getIconPackCalendarIcon(icon, res, allowThemed)
|
||||
} else if (icon is AppIcon) {
|
||||
return@withContext getIconPackStaticIcon(icon, res, allowThemed)
|
||||
} else if (icon is ClockIcon) {
|
||||
return@withContext getIconPackClockIcon(icon, res, allowThemed)
|
||||
}
|
||||
return@withContext null
|
||||
}
|
||||
|
||||
suspend fun generateIcon(
|
||||
context: Context,
|
||||
iconPack: String,
|
||||
@ -448,12 +469,11 @@ class IconPackManager(
|
||||
val drawableQuery = query.replace(" ", "_").lowercase()
|
||||
return iconDao.searchIconPackIcons(
|
||||
drawableQuery = "%$drawableQuery%",
|
||||
componentQuery = "%$query%",
|
||||
nameQuery = "%$query%",
|
||||
iconPack = iconPack?.packageName,
|
||||
).mapNotNull {
|
||||
IconPackAppIcon(it)
|
||||
}
|
||||
}.distinct()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import de.mm20.launcher2.data.customattrs.AdaptifiedLegacyIcon
|
||||
import de.mm20.launcher2.data.customattrs.CustomAttributesRepository
|
||||
import de.mm20.launcher2.data.customattrs.CustomIcon
|
||||
import de.mm20.launcher2.data.customattrs.CustomIconPackIcon
|
||||
import de.mm20.launcher2.data.customattrs.LegacyCustomIconPackIcon
|
||||
import de.mm20.launcher2.data.customattrs.CustomThemedIcon
|
||||
import de.mm20.launcher2.data.customattrs.DefaultPlaceholderIcon
|
||||
import de.mm20.launcher2.data.customattrs.ForceThemedIcon
|
||||
@ -18,6 +19,7 @@ import de.mm20.launcher2.data.customattrs.UnmodifiedSystemDefaultIcon
|
||||
import de.mm20.launcher2.icons.providers.CalendarIconProvider
|
||||
import de.mm20.launcher2.icons.providers.CompatIconProvider
|
||||
import de.mm20.launcher2.icons.providers.CustomIconPackIconProvider
|
||||
import de.mm20.launcher2.icons.providers.LegacyCustomIconPackIconProvider
|
||||
import de.mm20.launcher2.icons.providers.CustomThemedIconProvider
|
||||
import de.mm20.launcher2.icons.providers.DynamicClockIconProvider
|
||||
import de.mm20.launcher2.icons.providers.IconPackIconProvider
|
||||
@ -44,7 +46,6 @@ import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class IconService(
|
||||
@ -174,6 +175,14 @@ class IconService(
|
||||
)
|
||||
)
|
||||
}
|
||||
if (customIcon is LegacyCustomIconPackIcon) {
|
||||
return listOf(
|
||||
LegacyCustomIconPackIconProvider(
|
||||
customIcon,
|
||||
iconPackManager
|
||||
)
|
||||
)
|
||||
}
|
||||
if (customIcon is CustomThemedIcon) {
|
||||
return listOf(
|
||||
CustomThemedIconProvider(
|
||||
@ -288,11 +297,14 @@ class IconService(
|
||||
)
|
||||
|
||||
providerOptions.addAll(
|
||||
iconPackIcons.mapNotNull {
|
||||
iconPackIcons.map {
|
||||
val ent = it.toDatabaseEntity()
|
||||
CustomIconPackIcon(
|
||||
iconPackPackage = it.iconPack,
|
||||
iconActivityName = it.activityName,
|
||||
iconPackageName = it.packageName,
|
||||
type = ent.type,
|
||||
drawable = ent.drawable,
|
||||
extras = ent.extras,
|
||||
allowThemed = it.themed,
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -356,20 +368,22 @@ class IconService(
|
||||
val transformations = this.transformations.first()
|
||||
val iconPackIcons = iconPackManager.searchIconPackIcon(query, iconPack).flatMap {
|
||||
val unthemedIcon = if (it.themed) {
|
||||
iconPackManager.getIcon(it.iconPack, it.packageName, it.activityName, false)
|
||||
iconPackManager.getIcon(it.iconPack, it, false)
|
||||
?.transform(transformations)
|
||||
} else null
|
||||
val icon = iconPackManager.getIcon(it.iconPack, it.packageName, it.activityName, true)
|
||||
val icon = iconPackManager.getIcon(it.iconPack, it, true)
|
||||
?.transform(transformations)
|
||||
|
||||
buildList<CustomIconWithPreview> {
|
||||
buildList {
|
||||
val ent = it.toDatabaseEntity()
|
||||
if (icon != null) {
|
||||
add(CustomIconWithPreview(
|
||||
customIcon = CustomIconPackIcon(
|
||||
iconPackPackage = it.iconPack,
|
||||
iconActivityName = it.activityName,
|
||||
iconPackageName = it.packageName,
|
||||
allowThemed = true
|
||||
type = ent.type,
|
||||
drawable = ent.drawable,
|
||||
extras = ent.extras,
|
||||
allowThemed = true,
|
||||
),
|
||||
preview = icon
|
||||
))
|
||||
@ -378,9 +392,10 @@ class IconService(
|
||||
add(CustomIconWithPreview(
|
||||
customIcon = CustomIconPackIcon(
|
||||
iconPackPackage = it.iconPack,
|
||||
iconActivityName = it.activityName,
|
||||
iconPackageName = it.packageName,
|
||||
allowThemed = false
|
||||
type = ent.type,
|
||||
drawable = ent.drawable,
|
||||
extras = ent.extras,
|
||||
allowThemed = false,
|
||||
),
|
||||
preview = unthemedIcon
|
||||
))
|
||||
|
||||
@ -30,138 +30,181 @@ class AppFilterIconPackInstaller(
|
||||
) : IconPackInstaller(database) {
|
||||
override suspend fun IconPackInstallerScope.buildIconPack(iconPack: IconPack) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val pkgName = iconPack.packageName
|
||||
|
||||
try {
|
||||
val dynamicClocks = getDynamicClockIcons(pkgName)
|
||||
val parser = getAppfilterParser(pkgName) ?: return@withContext
|
||||
val dynamicClocks = getDynamicClockIcons(iconPack.packageName)
|
||||
|
||||
loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) continue
|
||||
when (parser.name) {
|
||||
"item" -> {
|
||||
val component = parser.getAttributeValue(null, "component")
|
||||
?: continue@loop
|
||||
val drawable = parser.getAttributeValue(null, "drawable")
|
||||
?: continue@loop
|
||||
if (component.length <= 14) continue@loop
|
||||
val componentName = ComponentName.unflattenFromString(
|
||||
component.substring(
|
||||
14,
|
||||
component.lastIndex
|
||||
)
|
||||
)
|
||||
?: continue@loop
|
||||
parseAppfilterXml(iconPack, dynamicClocks)
|
||||
parseDrawableXml(iconPack, dynamicClocks)
|
||||
|
||||
val name = parser.getAttributeValue(null, "name")
|
||||
|
||||
|
||||
val icon = if (dynamicClocks.containsKey(drawable)) {
|
||||
ClockIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
iconPack = pkgName,
|
||||
themed = iconPack.themed,
|
||||
name = name,
|
||||
drawable = drawable,
|
||||
config = dynamicClocks[drawable]!!,
|
||||
)
|
||||
} else {
|
||||
AppIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
name = name,
|
||||
themed = iconPack.themed,
|
||||
)
|
||||
}
|
||||
addIcon(icon)
|
||||
}
|
||||
|
||||
"calendar" -> {
|
||||
val component = parser.getAttributeValue(null, "component")
|
||||
?: continue@loop
|
||||
val drawable = parser.getAttributeValue(null, "prefix") ?: continue@loop
|
||||
if (component.length < 14) continue@loop
|
||||
val componentName = ComponentName.unflattenFromString(
|
||||
component.substring(
|
||||
14,
|
||||
component.lastIndex
|
||||
)
|
||||
)
|
||||
?: continue@loop
|
||||
|
||||
val name = parser.getAttributeValue(null, "name")
|
||||
|
||||
val icon = CalendarIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
drawables = (1..31).map { "$drawable$it" },
|
||||
iconPack = pkgName,
|
||||
themed = iconPack.themed,
|
||||
name = name,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
|
||||
"iconback" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconBack(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"iconupon" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconUpon(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"iconmask" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconMask(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"scale" -> {
|
||||
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull()
|
||||
?: continue@loop
|
||||
updatePackInfo { it.copy(scale = scale) }
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.close()
|
||||
|
||||
Log.d("MM20", "Icon pack $pkgName has been installed successfully")
|
||||
Log.d("MM20", "Icon pack ${iconPack.packageName} has been installed successfully")
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.e("MM20", "Could not install icon pack $pkgName: package not found.")
|
||||
Log.e(
|
||||
"MM20",
|
||||
"Could not install icon pack ${iconPack.packageName}: package not found."
|
||||
)
|
||||
} catch (e: XmlPullParserException) {
|
||||
CrashReporter.logException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun IconPackInstallerScope.parseAppfilterXml(
|
||||
iconPack: IconPack,
|
||||
dynamicClocks: Map<String, ClockIconConfig>
|
||||
) {
|
||||
val pkgName = iconPack.packageName
|
||||
val parser = getAppfilterParser(pkgName) ?: return
|
||||
|
||||
loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) continue
|
||||
when (parser.name) {
|
||||
"item" -> {
|
||||
val component = parser.getAttributeValue(null, "component")
|
||||
?: continue@loop
|
||||
val drawable = parser.getAttributeValue(null, "drawable")
|
||||
?: continue@loop
|
||||
if (component.length <= 14) continue@loop
|
||||
val componentName = ComponentName.unflattenFromString(
|
||||
component.substring(
|
||||
14,
|
||||
component.lastIndex
|
||||
)
|
||||
)
|
||||
?: continue@loop
|
||||
|
||||
val name = parser.getAttributeValue(null, "name")
|
||||
|
||||
|
||||
val icon = if (dynamicClocks.containsKey(drawable)) {
|
||||
ClockIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
iconPack = pkgName,
|
||||
themed = iconPack.themed,
|
||||
name = name,
|
||||
drawable = drawable,
|
||||
config = dynamicClocks[drawable]!!,
|
||||
)
|
||||
} else {
|
||||
AppIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
name = name,
|
||||
themed = iconPack.themed,
|
||||
)
|
||||
}
|
||||
addIcon(icon)
|
||||
}
|
||||
|
||||
"calendar" -> {
|
||||
val component = parser.getAttributeValue(null, "component")
|
||||
?: continue@loop
|
||||
val drawable = parser.getAttributeValue(null, "prefix") ?: continue@loop
|
||||
if (component.length < 14) continue@loop
|
||||
val componentName = ComponentName.unflattenFromString(
|
||||
component.substring(
|
||||
14,
|
||||
component.lastIndex
|
||||
)
|
||||
)
|
||||
?: continue@loop
|
||||
|
||||
val name = parser.getAttributeValue(null, "name")
|
||||
|
||||
val icon = CalendarIcon(
|
||||
packageName = componentName.packageName,
|
||||
activityName = componentName.shortClassName,
|
||||
drawables = (1..31).map { "$drawable$it" },
|
||||
iconPack = pkgName,
|
||||
themed = iconPack.themed,
|
||||
name = name,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
|
||||
"iconback" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconBack(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"iconupon" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconUpon(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"iconmask" -> {
|
||||
for (i in 0 until parser.attributeCount) {
|
||||
if (parser.getAttributeName(i).startsWith("img")) {
|
||||
val drawable = parser.getAttributeValue(i)
|
||||
val icon = IconMask(
|
||||
drawable = drawable,
|
||||
iconPack = pkgName,
|
||||
)
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"scale" -> {
|
||||
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull()
|
||||
?: continue@loop
|
||||
updatePackInfo { it.copy(scale = scale) }
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.close()
|
||||
}
|
||||
|
||||
private suspend fun IconPackInstallerScope.parseDrawableXml(
|
||||
iconPack: IconPack,
|
||||
dynamicClocks: Map<String, ClockIconConfig>
|
||||
) {
|
||||
val res = context.packageManager.getResourcesForApplication(iconPack.packageName)
|
||||
val xmlId = res.getIdentifier("drawable", "xml", iconPack.packageName)
|
||||
if (xmlId == 0) return
|
||||
val parser = res.getXml(xmlId)
|
||||
loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
||||
if (parser.eventType != XmlPullParser.START_TAG) continue
|
||||
if (parser.name == "item") {
|
||||
val drawable = parser.getAttributeValue(null, "drawable") ?: continue@loop
|
||||
val icon = if (dynamicClocks.containsKey(drawable)) {
|
||||
ClockIcon(
|
||||
iconPack = iconPack.packageName,
|
||||
themed = iconPack.themed,
|
||||
drawable = drawable,
|
||||
config = dynamicClocks[drawable]!!,
|
||||
)
|
||||
} else {
|
||||
AppIcon(
|
||||
drawable = drawable,
|
||||
iconPack = iconPack.packageName,
|
||||
themed = iconPack.themed,
|
||||
)
|
||||
}
|
||||
addIcon(icon)
|
||||
}
|
||||
}
|
||||
parser.close()
|
||||
}
|
||||
|
||||
private fun getDynamicClockIcons(packageName: String): Map<String, ClockIconConfig> {
|
||||
val parser = getAppfilterParser(packageName) ?: return emptyMap()
|
||||
val map = mutableMapOf<String, ClockIconConfig>()
|
||||
@ -190,6 +233,7 @@ class AppFilterIconPackInstaller(
|
||||
)
|
||||
}
|
||||
}
|
||||
parser.close()
|
||||
return map
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package de.mm20.launcher2.icons.providers
|
||||
|
||||
import android.content.ComponentName
|
||||
import de.mm20.launcher2.data.customattrs.CustomIconPackIcon
|
||||
import de.mm20.launcher2.database.entities.IconEntity
|
||||
import de.mm20.launcher2.icons.IconPackAppIcon
|
||||
import de.mm20.launcher2.icons.IconPackManager
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
@ -11,10 +12,16 @@ class CustomIconPackIconProvider(
|
||||
private val iconPackManager: IconPackManager,
|
||||
) : IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
||||
val ent = IconEntity(
|
||||
type = customIcon.type,
|
||||
drawable = customIcon.drawable,
|
||||
extras = customIcon.extras,
|
||||
iconPack = customIcon.iconPackPackage,
|
||||
)
|
||||
val icon = IconPackAppIcon(ent) ?: return null
|
||||
return iconPackManager.getIcon(
|
||||
customIcon.iconPackPackage,
|
||||
customIcon.iconPackageName,
|
||||
customIcon.iconActivityName,
|
||||
icon,
|
||||
customIcon.allowThemed,
|
||||
)
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package de.mm20.launcher2.icons.providers
|
||||
|
||||
import de.mm20.launcher2.data.customattrs.LegacyCustomIconPackIcon
|
||||
import de.mm20.launcher2.icons.IconPackManager
|
||||
import de.mm20.launcher2.icons.LauncherIcon
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
|
||||
@Deprecated("Use CustomIconPackIconProvider instead")
|
||||
class LegacyCustomIconPackIconProvider(
|
||||
private val customIcon: LegacyCustomIconPackIcon,
|
||||
private val iconPackManager: IconPackManager,
|
||||
) : IconProvider {
|
||||
override suspend fun getIcon(searchable: SavableSearchable, size: Int): LauncherIcon? {
|
||||
return iconPackManager.getIcon(
|
||||
customIcon.iconPackPackage,
|
||||
customIcon.iconPackageName,
|
||||
customIcon.iconActivityName,
|
||||
customIcon.allowThemed,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user