Fix crash

This commit is contained in:
MM20 2022-08-23 16:37:50 +02:00
parent b6acafb54e
commit 73fda4e8ab
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 164 additions and 153 deletions

View File

@ -29,7 +29,7 @@ interface IconDao {
fun deleteIcons(iconPack: String) fun deleteIcons(iconPack: String)
@Transaction @Transaction
fun installIconPack(iconPack: IconPackEntity, icons: List<IconEntity>) { suspend fun installIconPack(iconPack: IconPackEntity, icons: List<IconEntity>) {
deleteIconPack(iconPack) deleteIconPack(iconPack)
deleteIcons(iconPack.packageName) deleteIcons(iconPack.packageName)
insertAll(icons) insertAll(icons)
@ -37,7 +37,7 @@ interface IconDao {
} }
@Transaction @Transaction
fun installGrayscaleIconMap(packageName: String, icons: List<IconEntity>) { suspend fun installGrayscaleIconMap(packageName: String, icons: List<IconEntity>) {
deleteIcons(packageName) deleteIcons(packageName)
insertAll(icons) insertAll(icons)
} }

View File

@ -13,7 +13,6 @@ import android.util.Log
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import de.mm20.launcher2.crashreporter.CrashReporter import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.customattrs.CustomIconPackIcon
import de.mm20.launcher2.database.AppDatabase import de.mm20.launcher2.database.AppDatabase
import de.mm20.launcher2.ktx.obtainTypedArrayOrNull import de.mm20.launcher2.ktx.obtainTypedArrayOrNull
import de.mm20.launcher2.ktx.randomElementOrNull import de.mm20.launcher2.ktx.randomElementOrNull
@ -269,8 +268,6 @@ class IconPackManager(
} }
suspend fun getGreyscaleIcon(packageName: String): IconPackIcon? { suspend fun getGreyscaleIcon(packageName: String): IconPackIcon? {
val iconDao = AppDatabase.getInstance(context).iconDao() val iconDao = AppDatabase.getInstance(context).iconDao()
return iconDao.getGreyscaleIcon(ComponentName(packageName, packageName).flattenToString()) return iconDao.getGreyscaleIcon(ComponentName(packageName, packageName).flattenToString())
@ -332,7 +329,7 @@ class IconPackManager(
return StaticLauncherIcon( return StaticLauncherIcon(
foregroundLayer = TintedClockLayer( foregroundLayer = TintedClockLayer(
sublayers = (0 until drawable.numberOfLayers).map { sublayers = (0 until drawable.numberOfLayers).map {
val drw = drawable.getDrawable(it) val drw = drawable.getDrawable(it)
if (drw is RotateDrawable) { if (drw is RotateDrawable) {
drw.level = when (it) { drw.level = when (it) {
hourIndex -> { hourIndex -> {
@ -461,180 +458,194 @@ class UpdateIconPacksWorker(val context: Context) {
private fun installIconPack(iconPack: IconPack) { private fun installIconPack(iconPack: IconPack) {
val pkgName = iconPack.packageName val pkgName = iconPack.packageName
try {
val res = context.packageManager.getResourcesForApplication(pkgName) val icons = mutableListOf<IconPackIcon>()
val parser: XmlPullParser val database = AppDatabase.getInstance(context)
var inStream: InputStreamReader? = null database.runInTransaction {
val xmlId = res.getIdentifier("appfilter", "xml", pkgName) try {
if (xmlId != 0) parser = res.getXml(xmlId) val res = context.packageManager.getResourcesForApplication(pkgName)
else { val parser: XmlPullParser
val rawId = res.getIdentifier("appfilter", "raw", pkgName) var inStream: InputStreamReader? = null
if (rawId == 0) { val xmlId = res.getIdentifier("appfilter", "xml", pkgName)
Log.e( if (xmlId != 0) parser = res.getXml(xmlId)
"MM20", else {
"Icon pack $pkgName has no appfilter.xml, neither in xml nor in raw" val rawId = res.getIdentifier("appfilter", "raw", pkgName)
) if (rawId == 0) {
return Log.e(
"MM20",
"Icon pack $pkgName has no appfilter.xml, neither in xml nor in raw"
)
return@runInTransaction
}
parser = XmlPullParserFactory.newInstance().newPullParser()
inStream = res.openRawResource(rawId).reader()
parser.setInput(inStream)
} }
parser = XmlPullParserFactory.newInstance().newPullParser() val iconDao = database.iconDao()
inStream = res.openRawResource(rawId).reader()
parser.setInput(inStream)
}
val icons = mutableListOf<IconPackIcon>() iconDao.deleteIconPack(iconPack.toDatabaseEntity())
val iconDao = AppDatabase.getInstance(context).iconDao() iconDao.deleteIcons(iconPack.packageName)
iconDao.deleteIconPack(iconPack.toDatabaseEntity()) loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) {
iconDao.deleteIcons(iconPack.packageName) if (parser.eventType != XmlPullParser.START_TAG) continue
when (parser.name) {
loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) { "item" -> {
if (parser.eventType != XmlPullParser.START_TAG) continue val component = parser.getAttributeValue(null, "component")
when (parser.name) { ?: continue@loop
"item" -> { val drawable = parser.getAttributeValue(null, "drawable")
val component = parser.getAttributeValue(null, "component") ?: continue@loop
?: continue@loop if (component.length <= 14) continue@loop
val drawable = parser.getAttributeValue(null, "drawable") val componentName = ComponentName.unflattenFromString(
?: continue@loop component.substring(
if (component.length <= 14) continue@loop 14,
val componentName = ComponentName.unflattenFromString( component.lastIndex
component.substring( )
14,
component.lastIndex
) )
) ?: continue@loop
?: continue@loop val icon = IconPackIcon(
val icon = IconPackIcon( componentName = componentName,
componentName = componentName, drawable = drawable,
drawable = drawable, iconPack = pkgName,
iconPack = pkgName, type = "app"
type = "app"
)
icons.add(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
) )
) icons.add(icon)
?: continue@loop }
"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 icon = IconPackIcon( val icon = IconPackIcon(
componentName = componentName, componentName = componentName,
drawable = drawable, drawable = drawable,
iconPack = pkgName, iconPack = pkgName,
type = "calendar" type = "calendar"
) )
icons.add(icon) icons.add(icon)
} }
"iconback" -> { "iconback" -> {
for (i in 0 until parser.attributeCount) { for (i in 0 until parser.attributeCount) {
if (parser.getAttributeName(i).startsWith("img")) { if (parser.getAttributeName(i).startsWith("img")) {
val drawable = parser.getAttributeValue(i) val drawable = parser.getAttributeValue(i)
val icon = IconPackIcon( val icon = IconPackIcon(
componentName = null, componentName = null,
drawable = drawable, drawable = drawable,
iconPack = pkgName, iconPack = pkgName,
type = "iconback" type = "iconback"
) )
icons.add(icon) icons.add(icon)
}
} }
} }
} "iconupon" -> {
"iconupon" -> { for (i in 0 until parser.attributeCount) {
for (i in 0 until parser.attributeCount) { if (parser.getAttributeName(i).startsWith("img")) {
if (parser.getAttributeName(i).startsWith("img")) { val drawable = parser.getAttributeValue(i)
val drawable = parser.getAttributeValue(i) val icon = IconPackIcon(
val icon = IconPackIcon( componentName = null,
componentName = null, drawable = drawable,
drawable = drawable, iconPack = pkgName,
iconPack = pkgName, type = "iconupon"
type = "iconupon" )
) icons.add(icon)
icons.add(icon) }
} }
} }
} "iconmask" -> {
"iconmask" -> { for (i in 0 until parser.attributeCount) {
for (i in 0 until parser.attributeCount) { if (parser.getAttributeName(i).startsWith("img")) {
if (parser.getAttributeName(i).startsWith("img")) { val drawable = parser.getAttributeValue(i)
val drawable = parser.getAttributeValue(i) val icon = IconPackIcon(
val icon = IconPackIcon( componentName = null,
componentName = null, drawable = drawable,
drawable = drawable, iconPack = pkgName,
iconPack = pkgName, type = "iconmask"
type = "iconmask" )
) icons.add(icon)
icons.add(icon) }
} }
} }
"scale" -> {
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull()
?: continue@loop
iconPack.scale = scale
}
} }
"scale" -> { if (icons.size >= 100) {
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull() iconDao.insertAll(icons.map { it.toDatabaseEntity() })
?: continue@loop icons.clear()
iconPack.scale = scale
} }
} }
if (icons.size >= 100) {
if (icons.isNotEmpty()) {
iconDao.insertAll(icons.map { it.toDatabaseEntity() }) iconDao.insertAll(icons.map { it.toDatabaseEntity() })
icons.clear()
} }
iconDao.installIconPack(iconPack.toDatabaseEntity())
(parser as? XmlResourceParser)?.close()
inStream?.close()
Log.d("MM20", "Icon pack has been installed successfully")
} catch (e: PackageManager.NameNotFoundException) {
Log.e("MM20", "Could not install icon pack $pkgName: package not found.")
} catch (e: XmlPullParserException) {
CrashReporter.logException(e)
} }
if (icons.isNotEmpty()) {
iconDao.insertAll(icons.map { it.toDatabaseEntity() })
}
iconDao.installIconPack(iconPack.toDatabaseEntity())
(parser as? XmlResourceParser)?.close()
inStream?.close()
Log.d("MM20", "Icon pack has been installed successfully")
} catch (e: PackageManager.NameNotFoundException) {
Log.e("MM20", "Could not install icon pack $pkgName: package not found.")
} catch (e: XmlPullParserException) {
CrashReporter.logException(e)
} }
} }
private fun installGrayscaleIconMap(packageName: String) { private fun installGrayscaleIconMap(packageName: String) {
val iconDao = AppDatabase.getInstance(context).iconDao() val database = AppDatabase.getInstance(context)
try { database.runInTransaction {
val resources = context.packageManager.getResourcesForApplication(packageName) val iconDao = database.iconDao()
val resId = resources.getIdentifier("grayscale_icon_map", "xml", packageName) try {
if (resId == 0) { val resources = context.packageManager.getResourcesForApplication(packageName)
val resId = resources.getIdentifier("grayscale_icon_map", "xml", packageName)
iconDao.deleteIcons(packageName) iconDao.deleteIcons(packageName)
return if (resId == 0) {
} return@runInTransaction
val icons = mutableListOf<IconPackIcon>() }
val parser = resources.getXml(resId) val icons = mutableListOf<IconPackIcon>()
loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) { val parser = resources.getXml(resId)
if (parser.eventType != XmlPullParser.START_TAG) continue loop@ while (parser.next() != XmlPullParser.END_DOCUMENT) {
when (parser.name) { if (parser.eventType != XmlPullParser.START_TAG) continue
"icon" -> { when (parser.name) {
val drawable = "icon" -> {
parser.getAttributeResourceValue(null, "drawable", 0).toString() val drawable =
val pkg = parser.getAttributeValue(null, "package") parser.getAttributeResourceValue(null, "drawable", 0).toString()
val componentName = ComponentName(pkg, pkg) val pkg = parser.getAttributeValue(null, "package")
val icon = IconPackIcon( val componentName = ComponentName(pkg, pkg)
drawable = drawable, val icon = IconPackIcon(
componentName = componentName, drawable = drawable,
iconPack = packageName, componentName = componentName,
type = "greyscale_icon" iconPack = packageName,
) type = "greyscale_icon"
icons.add(icon) )
icons.add(icon)
}
}
if (icons.size >= 100) {
iconDao.insertAll(icons.map { it.toDatabaseEntity() })
icons.clear()
} }
} }
if (icons.isNotEmpty()) {
iconDao.insertAll(icons.map { it.toDatabaseEntity() })
}
} catch (e: PackageManager.NameNotFoundException) {
iconDao.deleteIcons(packageName)
return@runInTransaction
} }
iconDao.installGrayscaleIconMap(packageName, icons.map { it.toDatabaseEntity() })
} catch (e: PackageManager.NameNotFoundException) {
iconDao.deleteIcons(packageName)
return
} }
} }
} }