Add support for icon packs that have their appfilter.xml located in assets/
Close #242
This commit is contained in:
parent
7800ea5607
commit
095dc97653
@ -25,9 +25,12 @@ interface IconDao {
|
|||||||
@Query("SELECT * FROM Icons WHERE (type = 'greyscale_icon') AND componentName LIKE :query GROUP BY componentName ORDER BY drawable LIMIT :limit")
|
@Query("SELECT * FROM Icons WHERE (type = 'greyscale_icon') AND componentName LIKE :query GROUP BY componentName ORDER BY drawable LIMIT :limit")
|
||||||
suspend fun searchGreyscaleIcons(query: String, limit: Int = 100): List<IconEntity>
|
suspend fun searchGreyscaleIcons(query: String, limit: Int = 100): List<IconEntity>
|
||||||
|
|
||||||
@Query("DELETE FROM Icons WHERE iconPack = :iconPack")
|
@Query("DELETE FROM Icons WHERE iconPack = :iconPack AND type != 'greyscale_icon'")
|
||||||
fun deleteIcons(iconPack: String)
|
fun deleteIcons(iconPack: String)
|
||||||
|
|
||||||
|
@Query("DELETE FROM Icons WHERE iconPack = :iconPack AND type = 'greyscale_icon'")
|
||||||
|
fun deleteGrayscaleIcons(iconPack: String)
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
suspend fun installIconPack(iconPack: IconPackEntity, icons: List<IconEntity>) {
|
suspend fun installIconPack(iconPack: IconPackEntity, icons: List<IconEntity>) {
|
||||||
deleteIconPack(iconPack)
|
deleteIconPack(iconPack)
|
||||||
|
|||||||
@ -21,7 +21,8 @@ import kotlinx.coroutines.withContext
|
|||||||
import org.xmlpull.v1.XmlPullParser
|
import org.xmlpull.v1.XmlPullParser
|
||||||
import org.xmlpull.v1.XmlPullParserException
|
import org.xmlpull.v1.XmlPullParserException
|
||||||
import org.xmlpull.v1.XmlPullParserFactory
|
import org.xmlpull.v1.XmlPullParserFactory
|
||||||
import java.io.InputStreamReader
|
import java.io.IOException
|
||||||
|
import java.io.Reader
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
private val SUPPORTED_GRAYSCALE_MAP_PROVIDERS = arrayOf(
|
private val SUPPORTED_GRAYSCALE_MAP_PROVIDERS = arrayOf(
|
||||||
@ -91,6 +92,7 @@ class IconPackManager(
|
|||||||
} ?: TransparentLayer,
|
} ?: TransparentLayer,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
StaticLauncherIcon(
|
StaticLauncherIcon(
|
||||||
foregroundLayer = StaticIconLayer(
|
foregroundLayer = StaticIconLayer(
|
||||||
@ -308,18 +310,22 @@ class IconPackManager(
|
|||||||
i++
|
i++
|
||||||
drawable = array.getDrawable(i) as? LayerDrawable
|
drawable = array.getDrawable(i) as? LayerDrawable
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.android.launcher3.HOUR_LAYER_INDEX" -> {
|
"com.android.launcher3.HOUR_LAYER_INDEX" -> {
|
||||||
i++
|
i++
|
||||||
hourIndex = array.getInt(i, -1).takeIf { it != -1 }
|
hourIndex = array.getInt(i, -1).takeIf { it != -1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.android.launcher3.MINUTE_LAYER_INDEX" -> {
|
"com.android.launcher3.MINUTE_LAYER_INDEX" -> {
|
||||||
i++
|
i++
|
||||||
minuteIndex = array.getInt(i, -1).takeIf { it != -1 }
|
minuteIndex = array.getInt(i, -1).takeIf { it != -1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.android.launcher3.DEFAULT_HOUR" -> {
|
"com.android.launcher3.DEFAULT_HOUR" -> {
|
||||||
i++
|
i++
|
||||||
defaultHour = array.getInt(i, 0)
|
defaultHour = array.getInt(i, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.android.launcher3.DEFAULT_MINUTE" -> {
|
"com.android.launcher3.DEFAULT_MINUTE" -> {
|
||||||
i++
|
i++
|
||||||
defaultMinute = array.getInt(i, 0)
|
defaultMinute = array.getInt(i, 0)
|
||||||
@ -338,9 +344,11 @@ class IconPackManager(
|
|||||||
hourIndex -> {
|
hourIndex -> {
|
||||||
(12 - defaultHour) * 60
|
(12 - defaultHour) * 60
|
||||||
}
|
}
|
||||||
|
|
||||||
minuteIndex -> {
|
minuteIndex -> {
|
||||||
(60 - defaultMinute)
|
(60 - defaultMinute)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,21 +476,37 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
try {
|
try {
|
||||||
val res = context.packageManager.getResourcesForApplication(pkgName)
|
val res = context.packageManager.getResourcesForApplication(pkgName)
|
||||||
val parser: XmlPullParser
|
val parser: XmlPullParser
|
||||||
var inStream: InputStreamReader? = null
|
var inStream: Reader? = null
|
||||||
val xmlId = res.getIdentifier("appfilter", "xml", pkgName)
|
val xmlId = res.getIdentifier("appfilter", "xml", pkgName)
|
||||||
if (xmlId != 0) parser = res.getXml(xmlId)
|
val rawId = res.getIdentifier("appfilter", "raw", pkgName)
|
||||||
else {
|
parser = when {
|
||||||
val rawId = res.getIdentifier("appfilter", "raw", pkgName)
|
xmlId != 0 -> res.getXml(xmlId)
|
||||||
if (rawId == 0) {
|
rawId != 0 -> {
|
||||||
Log.e(
|
inStream = res.openRawResource(rawId).reader()
|
||||||
"MM20",
|
XmlPullParserFactory.newInstance().newPullParser().apply {
|
||||||
"Icon pack $pkgName has no appfilter.xml, neither in xml nor in raw"
|
setInput(inStream)
|
||||||
)
|
}
|
||||||
return@runInTransaction
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val iconPackContext = context.createPackageContext(
|
||||||
|
pkgName,
|
||||||
|
Context.CONTEXT_IGNORE_SECURITY
|
||||||
|
)
|
||||||
|
inStream = try {
|
||||||
|
iconPackContext.assets.open("appfilter.xml").reader()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
CrashReporter.logException(e)
|
||||||
|
Log.e(
|
||||||
|
"MM20",
|
||||||
|
"appfilter.xml not found in $pkgName. Searched locations: res/xml/appfilter.xml, res/raw/appfilter.xml, assets/appfilter.xml"
|
||||||
|
)
|
||||||
|
return@runInTransaction
|
||||||
|
}
|
||||||
|
XmlPullParserFactory.newInstance().newPullParser().apply {
|
||||||
|
setInput(inStream)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parser = XmlPullParserFactory.newInstance().newPullParser()
|
|
||||||
inStream = res.openRawResource(rawId).reader()
|
|
||||||
parser.setInput(inStream)
|
|
||||||
}
|
}
|
||||||
val iconDao = database.iconDao()
|
val iconDao = database.iconDao()
|
||||||
|
|
||||||
@ -513,6 +537,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
)
|
)
|
||||||
icons.add(icon)
|
icons.add(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
"calendar" -> {
|
"calendar" -> {
|
||||||
val component = parser.getAttributeValue(null, "component")
|
val component = parser.getAttributeValue(null, "component")
|
||||||
?: continue@loop
|
?: continue@loop
|
||||||
@ -534,6 +559,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
)
|
)
|
||||||
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")) {
|
||||||
@ -548,6 +574,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"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")) {
|
||||||
@ -562,6 +589,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"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")) {
|
||||||
@ -576,6 +604,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"scale" -> {
|
"scale" -> {
|
||||||
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull()
|
val scale = parser.getAttributeValue(null, "factor")?.toFloatOrNull()
|
||||||
?: continue@loop
|
?: continue@loop
|
||||||
@ -613,7 +642,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
try {
|
try {
|
||||||
val resources = context.packageManager.getResourcesForApplication(packageName)
|
val resources = context.packageManager.getResourcesForApplication(packageName)
|
||||||
val resId = resources.getIdentifier("grayscale_icon_map", "xml", packageName)
|
val resId = resources.getIdentifier("grayscale_icon_map", "xml", packageName)
|
||||||
iconDao.deleteIcons(packageName)
|
iconDao.deleteGrayscaleIcons(packageName)
|
||||||
if (resId == 0) {
|
if (resId == 0) {
|
||||||
return@runInTransaction
|
return@runInTransaction
|
||||||
}
|
}
|
||||||
@ -645,7 +674,7 @@ class UpdateIconPacksWorker(val context: Context) {
|
|||||||
iconDao.insertAll(icons.map { it.toDatabaseEntity() })
|
iconDao.insertAll(icons.map { it.toDatabaseEntity() })
|
||||||
}
|
}
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
iconDao.deleteIcons(packageName)
|
iconDao.deleteGrayscaleIcons(packageName)
|
||||||
return@runInTransaction
|
return@runInTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user