From 57449d4fce5501588840d775b9328230150d4f27 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 4 Sep 2022 11:53:27 +0200 Subject: [PATCH] Add support for Android 13 themed icons --- .../mm20/launcher2/search/data/AppInstallation.kt | 1 + .../de/mm20/launcher2/search/data/LauncherApp.kt | 14 ++++++++++++-- .../de/mm20/launcher2/search/data/AppShortcut.kt | 11 +++++++++++ .../java/de/mm20/launcher2/search/data/Contact.kt | 1 + .../de/mm20/launcher2/search/data/LocalFile.kt | 1 + .../java/de/mm20/launcher2/icons/IconRepository.kt | 4 ++-- .../icons/providers/SystemIconProvider.kt | 5 +++-- .../de/mm20/launcher2/search/data/Searchable.kt | 1 + .../java/de/mm20/launcher2/search/data/Website.kt | 1 + 9 files changed, 33 insertions(+), 6 deletions(-) diff --git a/applications/src/main/java/de/mm20/launcher2/search/data/AppInstallation.kt b/applications/src/main/java/de/mm20/launcher2/search/data/AppInstallation.kt index 674d74a1..a6c10327 100644 --- a/applications/src/main/java/de/mm20/launcher2/search/data/AppInstallation.kt +++ b/applications/src/main/java/de/mm20/launcher2/search/data/AppInstallation.kt @@ -41,6 +41,7 @@ class AppInstallation( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon { val icon = session.appIcon ?: return getPlaceholderIcon(context) val foreground = BitmapDrawable(context.resources, icon) diff --git a/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt b/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt index 97c5217e..b96f3a96 100644 --- a/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt +++ b/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt @@ -13,9 +13,9 @@ import android.os.UserHandle import androidx.core.content.getSystemService import de.mm20.launcher2.icons.* import de.mm20.launcher2.ktx.getSerialNumber +import de.mm20.launcher2.ktx.isAtLeastApiLevel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.koin.core.component.KoinComponent /** * An [Application] based on an [android.content.pm.LauncherActivityInfo] @@ -29,7 +29,7 @@ class LauncherApp( activity = launcherActivityInfo.name, flags = launcherActivityInfo.applicationInfo.flags, version = getPackageVersionName(context, launcherActivityInfo.applicationInfo.packageName), -), KoinComponent { +) { internal val userSerialNumber: Long = launcherActivityInfo.user.getSerialNumber(context) val isMainProfile = launcherActivityInfo.user == Process.myUserHandle() @@ -44,6 +44,7 @@ class LauncherApp( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? { try { val icon = @@ -52,6 +53,15 @@ class LauncherApp( } ?: return null if (icon is AdaptiveIconDrawable) { + if (themed && isAtLeastApiLevel(33) && icon.monochrome != null) { + return StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + scale = 1f, + icon = icon.monochrome!!, + ), + backgroundLayer = ColorLayer() + ) + } return StaticLauncherIcon( foregroundLayer = icon.foreground?.let { StaticIconLayer( diff --git a/appshortcuts/src/main/java/de/mm20/launcher2/search/data/AppShortcut.kt b/appshortcuts/src/main/java/de/mm20/launcher2/search/data/AppShortcut.kt index 7838ccc0..5abde3da 100644 --- a/appshortcuts/src/main/java/de/mm20/launcher2/search/data/AppShortcut.kt +++ b/appshortcuts/src/main/java/de/mm20/launcher2/search/data/AppShortcut.kt @@ -15,6 +15,7 @@ import androidx.core.content.getSystemService import de.mm20.launcher2.appshortcuts.R import de.mm20.launcher2.icons.* import de.mm20.launcher2.ktx.getSerialNumber +import de.mm20.launcher2.ktx.isAtLeastApiLevel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -68,6 +69,7 @@ class AppShortcut( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? { val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps val icon = withContext(Dispatchers.IO) { @@ -77,6 +79,15 @@ class AppShortcut( ) } ?: return null if (icon is AdaptiveIconDrawable) { + if (themed && isAtLeastApiLevel(33) && icon.monochrome != null) { + return StaticLauncherIcon( + foregroundLayer = TintedIconLayer( + scale = 1f, + icon = icon.monochrome!!, + ), + backgroundLayer = ColorLayer() + ) + } return StaticLauncherIcon( foregroundLayer = icon.foreground?.let { StaticIconLayer( diff --git a/contacts/src/main/java/de/mm20/launcher2/search/data/Contact.kt b/contacts/src/main/java/de/mm20/launcher2/search/data/Contact.kt index b6d1b81d..e1a047d6 100644 --- a/contacts/src/main/java/de/mm20/launcher2/search/data/Contact.kt +++ b/contacts/src/main/java/de/mm20/launcher2/search/data/Contact.kt @@ -51,6 +51,7 @@ class Contact( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? { val contentResolver = context.contentResolver val bmp = withContext(Dispatchers.IO) { diff --git a/files/src/main/java/de/mm20/launcher2/search/data/LocalFile.kt b/files/src/main/java/de/mm20/launcher2/search/data/LocalFile.kt index 5c85322c..29e3d734 100644 --- a/files/src/main/java/de/mm20/launcher2/search/data/LocalFile.kt +++ b/files/src/main/java/de/mm20/launcher2/search/data/LocalFile.kt @@ -42,6 +42,7 @@ open class LocalFile( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? { if (!JavaIOFile(path).exists()) return null when { diff --git a/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt b/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt index 8680869e..c54a4c4e 100644 --- a/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt +++ b/icons/src/main/java/de/mm20/launcher2/icons/IconRepository.kt @@ -81,7 +81,7 @@ class IconRepository( } providers.add(GoogleClockIconProvider(context)) providers.add(CalendarIconProvider(context)) - providers.add(SystemIconProvider(context)) + providers.add(SystemIconProvider(context, settings.themedIcons)) providers.add(placeholderProvider) cache.evictAll() @@ -131,7 +131,7 @@ class IconRepository( private fun getProviders(customIcon: CustomIcon?): List { if (customIcon is UnmodifiedSystemDefaultIcon) { return listOf( - SystemIconProvider(context) + SystemIconProvider(context, false) ) } if (customIcon is CustomIconPackIcon) { diff --git a/icons/src/main/java/de/mm20/launcher2/icons/providers/SystemIconProvider.kt b/icons/src/main/java/de/mm20/launcher2/icons/providers/SystemIconProvider.kt index 431dc2ae..06edc24d 100644 --- a/icons/src/main/java/de/mm20/launcher2/icons/providers/SystemIconProvider.kt +++ b/icons/src/main/java/de/mm20/launcher2/icons/providers/SystemIconProvider.kt @@ -5,9 +5,10 @@ import de.mm20.launcher2.icons.LauncherIcon import de.mm20.launcher2.search.data.Searchable class SystemIconProvider( - private val context: Context + private val context: Context, + private val themedIcons: Boolean, ) : IconProvider { override suspend fun getIcon(searchable: Searchable, size: Int): LauncherIcon? { - return searchable.loadIcon(context, size) + return searchable.loadIcon(context, size, themedIcons) } } \ No newline at end of file diff --git a/search/src/main/java/de/mm20/launcher2/search/data/Searchable.kt b/search/src/main/java/de/mm20/launcher2/search/data/Searchable.kt index ab649710..7df9244e 100644 --- a/search/src/main/java/de/mm20/launcher2/search/data/Searchable.kt +++ b/search/src/main/java/de/mm20/launcher2/search/data/Searchable.kt @@ -37,6 +37,7 @@ abstract class Searchable : Comparable { open suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? = null abstract fun getPlaceholderIcon(context: Context): StaticLauncherIcon diff --git a/websites/src/main/java/de/mm20/launcher2/search/data/Website.kt b/websites/src/main/java/de/mm20/launcher2/search/data/Website.kt index 46ff0023..7b37c2b2 100644 --- a/websites/src/main/java/de/mm20/launcher2/search/data/Website.kt +++ b/websites/src/main/java/de/mm20/launcher2/search/data/Website.kt @@ -25,6 +25,7 @@ class Website( override suspend fun loadIcon( context: Context, size: Int, + themed: Boolean, ): LauncherIcon? { if (favicon.isEmpty()) return null try {