Annual refactor
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
|
||||
|
||||
fun AppShortcut(context: Context, pinRequestIntent: Intent): AppShortcut? {
|
||||
return LauncherShortcut.fromPinRequestIntent(context, pinRequestIntent)
|
||||
?: LegacyShortcut.fromPinRequestIntent(context, pinRequestIntent)
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.Context
|
||||
import android.content.IntentSender
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Process
|
||||
import androidx.core.content.getSystemService
|
||||
import de.mm20.launcher2.ktx.romanize
|
||||
import de.mm20.launcher2.search.AppProfile
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import java.text.Collator
|
||||
|
||||
class AppShortcutConfigActivity(
|
||||
private val launcherActivityInfo: LauncherActivityInfo,
|
||||
): Comparable<AppShortcutConfigActivity> {
|
||||
val label = launcherActivityInfo.label.toString()
|
||||
val profile: AppProfile = if (launcherActivityInfo.user == Process.myUserHandle()) AppProfile.Personal else AppProfile.Work
|
||||
|
||||
fun getIcon(context: Context): Flow<Drawable?> = flow {
|
||||
val icon = launcherActivityInfo.getIcon(context.resources.displayMetrics.densityDpi)
|
||||
emit(icon)
|
||||
}
|
||||
fun getIntent(context: Context): IntentSender? {
|
||||
val launcherApps = context.getSystemService<LauncherApps>()!!
|
||||
return launcherApps.getShortcutConfigActivityIntent(launcherActivityInfo)
|
||||
}
|
||||
|
||||
override fun compareTo(other: AppShortcutConfigActivity): Int {
|
||||
|
||||
val label1 = label
|
||||
val label2 = other.label
|
||||
return Collator.getInstance().apply { strength = Collator.SECONDARY }
|
||||
.compare(label1.romanize(), label2.romanize())
|
||||
}
|
||||
}
|
||||
+69
-67
@@ -1,21 +1,19 @@
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Process
|
||||
import android.os.UserHandle
|
||||
import android.util.Log
|
||||
import androidx.core.content.getSystemService
|
||||
import de.mm20.launcher2.ktx.normalize
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.search.data.AppShortcut
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import de.mm20.launcher2.search.data.LauncherShortcut
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.SearchableRepository
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -28,22 +26,25 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.apache.commons.text.similarity.FuzzyScore
|
||||
import java.util.Locale
|
||||
|
||||
interface AppShortcutRepository {
|
||||
interface AppShortcutRepository : SearchableRepository<AppShortcut> {
|
||||
|
||||
fun search(query: String): Flow<ImmutableList<AppShortcut>>
|
||||
suspend fun getShortcutsForActivity(
|
||||
launcherActivityInfo: LauncherActivityInfo,
|
||||
count: Int = 5
|
||||
): List<LauncherShortcut>
|
||||
fun findMany(
|
||||
componentName: ComponentName? = null,
|
||||
user: UserHandle = Process.myUserHandle(),
|
||||
manifest: Boolean = false,
|
||||
dynamic: Boolean = false,
|
||||
pinned: Boolean = false,
|
||||
cached: Boolean = false,
|
||||
limit: Int = 5,
|
||||
): Flow<ImmutableList<AppShortcut>>
|
||||
|
||||
suspend fun getShortcutsConfigActivities(): List<LauncherApp>
|
||||
|
||||
fun removePinnedShortcut(shortcut: LauncherShortcut)
|
||||
suspend fun getShortcutsConfigActivities(): List<AppShortcutConfigActivity>
|
||||
}
|
||||
|
||||
internal class AppShortcutRepositoryImpl(
|
||||
@@ -53,33 +54,58 @@ internal class AppShortcutRepositoryImpl(
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.Default + Job())
|
||||
|
||||
override suspend fun getShortcutsForActivity(
|
||||
launcherActivityInfo: LauncherActivityInfo,
|
||||
count: Int,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val launcherApps = context.getSystemService<LauncherApps>()!!
|
||||
if (!launcherApps.hasShortcutHostPermission()) return@withContext emptyList()
|
||||
val query = LauncherApps.ShortcutQuery()
|
||||
.setPackage(launcherActivityInfo.applicationInfo.packageName)
|
||||
.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC or LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST)
|
||||
val shortcuts = try {
|
||||
launcherApps.getShortcuts(query, launcherActivityInfo.user)
|
||||
} catch (e: IllegalStateException) {
|
||||
emptyList()
|
||||
}
|
||||
val appShortcuts = mutableListOf<LauncherShortcut>()
|
||||
appShortcuts.addAll(shortcuts
|
||||
?.let {
|
||||
if (it.size > count) it.subList(0, count)
|
||||
else it
|
||||
}
|
||||
?.map {
|
||||
LauncherShortcut(
|
||||
context,
|
||||
it,
|
||||
override fun findMany(
|
||||
componentName: ComponentName?,
|
||||
user: UserHandle,
|
||||
manifest: Boolean,
|
||||
dynamic: Boolean,
|
||||
pinned: Boolean,
|
||||
cached: Boolean,
|
||||
limit: Int
|
||||
): Flow<ImmutableList<AppShortcut>> = flow {
|
||||
val shortcuts = withContext(Dispatchers.IO) {
|
||||
val launcherApps = context.getSystemService<LauncherApps>()!!
|
||||
if (!launcherApps.hasShortcutHostPermission()) return@withContext emptyList()
|
||||
val query = LauncherApps.ShortcutQuery()
|
||||
.setActivity(componentName)
|
||||
.setQueryFlags(
|
||||
buildQueryFlags(manifest, dynamic, pinned, cached)
|
||||
)
|
||||
} ?: emptyList())
|
||||
appShortcuts
|
||||
val shortcuts = try {
|
||||
launcherApps.getShortcuts(query, user)
|
||||
} catch (e: IllegalStateException) {
|
||||
emptyList()
|
||||
}
|
||||
val appShortcuts = mutableListOf<LauncherShortcut>()
|
||||
appShortcuts.addAll(shortcuts
|
||||
?.let {
|
||||
if (it.size > limit) it.subList(0, limit)
|
||||
else it
|
||||
}
|
||||
?.map {
|
||||
LauncherShortcut(
|
||||
context,
|
||||
it,
|
||||
)
|
||||
} ?: emptyList()
|
||||
)
|
||||
appShortcuts
|
||||
}
|
||||
emit(shortcuts.toImmutableList())
|
||||
}
|
||||
|
||||
private fun buildQueryFlags(
|
||||
manifest: Boolean,
|
||||
dynamic: Boolean,
|
||||
pinned: Boolean,
|
||||
cached: Boolean,
|
||||
): Int {
|
||||
var flags = 0
|
||||
if (manifest) flags = flags or LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST
|
||||
if (dynamic) flags = flags or LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||
if (pinned) flags = flags or LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED
|
||||
if (cached) flags = flags or LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED
|
||||
return flags
|
||||
}
|
||||
|
||||
override fun search(query: String) = channelFlow<ImmutableList<AppShortcut>> {
|
||||
@@ -93,7 +119,6 @@ internal class AppShortcutRepositoryImpl(
|
||||
return@withContext
|
||||
}
|
||||
|
||||
|
||||
shortcutChangeEmitter.collectLatest {
|
||||
val launcherApps =
|
||||
context.getSystemService<LauncherApps>() ?: return@collectLatest send(
|
||||
@@ -180,39 +205,16 @@ internal class AppShortcutRepositoryImpl(
|
||||
}
|
||||
}.shareIn(scope, SharingStarted.WhileSubscribed(500), 1)
|
||||
|
||||
override fun removePinnedShortcut(shortcut: LauncherShortcut) {
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
if (!launcherApps.hasShortcutHostPermission()) return
|
||||
val pinnedShortcutsQuery = LauncherApps.ShortcutQuery().apply {
|
||||
setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED)
|
||||
}
|
||||
val userHandle = shortcut.launcherShortcut.userHandle
|
||||
val allPinned = launcherApps.getShortcuts(pinnedShortcutsQuery, userHandle)
|
||||
|
||||
if (allPinned == null) {
|
||||
Log.e("MM20", "Could not remove shortcut ${shortcut.key}: shortcut query returned null")
|
||||
return
|
||||
}
|
||||
|
||||
launcherApps.pinShortcuts(
|
||||
shortcut.launcherShortcut.`package`,
|
||||
allPinned.filter { it.id != shortcut.launcherShortcut.id }.map { it.id },
|
||||
userHandle
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getShortcutsConfigActivities(): List<LauncherApp> {
|
||||
override suspend fun getShortcutsConfigActivities(): List<AppShortcutConfigActivity> {
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
if (!launcherApps.hasShortcutHostPermission()) return emptyList()
|
||||
val results = mutableListOf<LauncherApp>()
|
||||
val results = mutableListOf<AppShortcutConfigActivity>()
|
||||
val profiles = launcherApps.profiles
|
||||
for (profile in profiles) {
|
||||
val activities = launcherApps.getShortcutConfigActivityList(null, profile)
|
||||
results.addAll(
|
||||
activities.map {
|
||||
LauncherApp(
|
||||
context, it
|
||||
)
|
||||
AppShortcutConfigActivity(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+18
-13
@@ -11,9 +11,6 @@ import de.mm20.launcher2.ktx.jsonObjectOf
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.SearchableDeserializer
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
import de.mm20.launcher2.search.data.LauncherShortcut
|
||||
import de.mm20.launcher2.search.data.LegacyShortcut
|
||||
import de.mm20.launcher2.search.data.UnavailableShortcut
|
||||
import org.json.JSONObject
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
||||
@@ -37,7 +34,7 @@ class LauncherShortcutDeserializer(
|
||||
val context: Context
|
||||
) : SearchableDeserializer, KoinComponent {
|
||||
|
||||
override fun deserialize(serialized: String): SavableSearchable? {
|
||||
override suspend fun deserialize(serialized: String): SavableSearchable? {
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
|
||||
val json = JSONObject(serialized)
|
||||
@@ -65,16 +62,9 @@ class LauncherShortcutDeserializer(
|
||||
} catch (e: IllegalStateException) {
|
||||
return null
|
||||
}
|
||||
val pm = context.packageManager
|
||||
val appName = try {
|
||||
pm.getApplicationInfo(packageName, 0).loadLabel(pm).toString()
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
return null
|
||||
}
|
||||
if (shortcuts == null || shortcuts.isEmpty()) {
|
||||
if (shortcuts.isNullOrEmpty()) {
|
||||
return null
|
||||
} else {
|
||||
val activity = shortcuts[0].activity
|
||||
return LauncherShortcut(
|
||||
context = context,
|
||||
launcherShortcut = shortcuts[0],
|
||||
@@ -84,6 +74,21 @@ class LauncherShortcutDeserializer(
|
||||
}
|
||||
}
|
||||
|
||||
class UnavailableShortcutSerializer: SearchableSerializer {
|
||||
override fun serialize(searchable: SavableSearchable): String? {
|
||||
searchable as UnavailableShortcut
|
||||
return jsonObjectOf(
|
||||
"packagename" to searchable.packageName,
|
||||
"id" to searchable.shortcutId,
|
||||
"user" to searchable.userSerial,
|
||||
).toString()
|
||||
}
|
||||
|
||||
override val typePrefix: String
|
||||
get() = LauncherShortcut.Domain
|
||||
|
||||
}
|
||||
|
||||
class LegacyShortcutSerializer: SearchableSerializer {
|
||||
override fun serialize(searchable: SavableSearchable): String {
|
||||
searchable as LegacyShortcut
|
||||
@@ -106,7 +111,7 @@ class LegacyShortcutSerializer: SearchableSerializer {
|
||||
class LegacyShortcutDeserializer(
|
||||
val context: Context
|
||||
): SearchableDeserializer {
|
||||
override fun deserialize(serialized: String): SavableSearchable {
|
||||
override suspend fun deserialize(serialized: String): SavableSearchable {
|
||||
val json = JSONObject(serialized)
|
||||
val label = json.getString("label")
|
||||
val intent = Intent.parseUri(json.getString("intent"), 0)
|
||||
|
||||
+40
-5
@@ -1,6 +1,7 @@
|
||||
package de.mm20.launcher2.search.data
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.LauncherApps
|
||||
@@ -12,11 +13,13 @@ import android.os.Process
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import de.mm20.launcher2.appshortcuts.R
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import de.mm20.launcher2.icons.*
|
||||
import de.mm20.launcher2.ktx.getSerialNumber
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.search.AppProfile
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.lang.NullPointerException
|
||||
@@ -24,7 +27,7 @@ import java.lang.NullPointerException
|
||||
/**
|
||||
* Represents a modern (Android O+) launcher shortcut
|
||||
*/
|
||||
data class LauncherShortcut(
|
||||
internal data class LauncherShortcut(
|
||||
val launcherShortcut: ShortcutInfo,
|
||||
override val appName: String?,
|
||||
internal val userSerialNumber: Long,
|
||||
@@ -32,6 +35,11 @@ data class LauncherShortcut(
|
||||
) : AppShortcut {
|
||||
|
||||
override val domain: String = Domain
|
||||
override val componentName: ComponentName?
|
||||
get() = launcherShortcut.activity
|
||||
|
||||
override val packageName: String
|
||||
get() = launcherShortcut.`package`
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
@@ -48,7 +56,7 @@ data class LauncherShortcut(
|
||||
)
|
||||
|
||||
override val label: String
|
||||
get() = launcherShortcut.shortLabel?.toString() ?: ""
|
||||
get() = launcherShortcut.shortLabel?.toString() ?: launcherShortcut.longLabel?.toString() ?: ""
|
||||
|
||||
override fun overrideLabel(label: String): LauncherShortcut {
|
||||
return this.copy(labelOverride = label)
|
||||
@@ -56,8 +64,10 @@ data class LauncherShortcut(
|
||||
|
||||
override val preferDetailsOverLaunch: Boolean = false
|
||||
|
||||
private val isMainProfile = launcherShortcut.userHandle == Process.myUserHandle()
|
||||
override val profile: AppProfile
|
||||
get() = if (isMainProfile) AppProfile.Personal else AppProfile.Work
|
||||
|
||||
val isMainProfile = launcherShortcut.userHandle == Process.myUserHandle()
|
||||
|
||||
override val key: String
|
||||
get() = if (isMainProfile) {
|
||||
@@ -145,6 +155,31 @@ data class LauncherShortcut(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getSerializer(): SearchableSerializer {
|
||||
return LauncherShortcutSerializer()
|
||||
}
|
||||
|
||||
override suspend fun delete(context: Context) {
|
||||
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
if (!launcherApps.hasShortcutHostPermission()) return
|
||||
val pinnedShortcutsQuery = LauncherApps.ShortcutQuery().apply {
|
||||
setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED)
|
||||
}
|
||||
val userHandle = launcherShortcut.userHandle
|
||||
val allPinned = launcherApps.getShortcuts(pinnedShortcutsQuery, userHandle)
|
||||
|
||||
if (allPinned == null) {
|
||||
Log.e("MM20", "Could not remove shortcut ${key}: shortcut query returned null")
|
||||
return
|
||||
}
|
||||
|
||||
launcherApps.pinShortcuts(
|
||||
launcherShortcut.`package`,
|
||||
allPinned.filter { it.id != launcherShortcut.id }.map { it.id },
|
||||
userHandle
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromPinRequestIntent(context: Context, data: Intent): LauncherShortcut? {
|
||||
val launcherApps =
|
||||
+17
-3
@@ -1,5 +1,6 @@
|
||||
package de.mm20.launcher2.search.data
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ShortcutIconResource
|
||||
@@ -10,8 +11,11 @@ import de.mm20.launcher2.icons.*
|
||||
import de.mm20.launcher2.ktx.getDrawableOrNull
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.ktx.tryStartActivity
|
||||
import de.mm20.launcher2.search.AppProfile
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
|
||||
data class LegacyShortcut(
|
||||
internal data class LegacyShortcut(
|
||||
val intent: Intent,
|
||||
override val label: String,
|
||||
override val appName: String?,
|
||||
@@ -22,6 +26,9 @@ data class LegacyShortcut(
|
||||
override val domain = Domain
|
||||
override val key: String = "$domain://${intent.toUri(0)}"
|
||||
|
||||
override val profile: AppProfile
|
||||
get() = AppProfile.Personal
|
||||
|
||||
override fun overrideLabel(label: String): LegacyShortcut {
|
||||
return this.copy(labelOverride = label)
|
||||
}
|
||||
@@ -31,7 +38,10 @@ data class LegacyShortcut(
|
||||
return context.tryStartActivity(intent, options)
|
||||
}
|
||||
|
||||
val packageName: String?
|
||||
override val componentName: ComponentName?
|
||||
get() = intent.component
|
||||
|
||||
override val packageName: String?
|
||||
get() = intent.`package` ?: intent.component?.packageName
|
||||
|
||||
override suspend fun loadIcon(context: Context, size: Int, themed: Boolean): LauncherIcon? {
|
||||
@@ -75,6 +85,10 @@ data class LegacyShortcut(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getSerializer(): SearchableSerializer {
|
||||
return LegacyShortcutSerializer()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val Domain = "legacyshortcut"
|
||||
@@ -1,8 +1,15 @@
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.SearchableDeserializer
|
||||
import de.mm20.launcher2.search.SearchableRepository
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val appShortcutsModule = module {
|
||||
single<AppShortcutRepository> { AppShortcutRepositoryImpl(androidContext(), get()) }
|
||||
factory<SearchableRepository<AppShortcut>>(named<AppShortcut>()) { AppShortcutRepositoryImpl(androidContext(), get()) }
|
||||
factory<AppShortcutRepository> { AppShortcutRepositoryImpl(androidContext(), get()) }
|
||||
factory<SearchableDeserializer>(named(LauncherShortcut.Domain)) { LauncherShortcutDeserializer(androidContext()) }
|
||||
factory<SearchableDeserializer>(named(LegacyShortcut.Domain)) { LegacyShortcutDeserializer(androidContext()) }
|
||||
}
|
||||
+17
-4
@@ -1,24 +1,27 @@
|
||||
package de.mm20.launcher2.search.data
|
||||
package de.mm20.launcher2.appshortcuts
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Process
|
||||
import android.os.UserManager
|
||||
import de.mm20.launcher2.appshortcuts.R
|
||||
import de.mm20.launcher2.icons.ColorLayer
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
import de.mm20.launcher2.icons.TintedIconLayer
|
||||
import de.mm20.launcher2.search.AppProfile
|
||||
import de.mm20.launcher2.search.AppShortcut
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
|
||||
/**
|
||||
* Shortcut class that is used when a [LauncherShortcut] is not available, e.g. missing permissions
|
||||
* when Kvaesitso is not set as default launcher.
|
||||
*/
|
||||
class UnavailableShortcut(
|
||||
internal class UnavailableShortcut(
|
||||
override val label: String,
|
||||
override val appName: String?,
|
||||
val packageName: String,
|
||||
override val packageName: String,
|
||||
val shortcutId: String,
|
||||
val isMainProfile: Boolean,
|
||||
val userSerial: Long,
|
||||
@@ -34,6 +37,8 @@ class UnavailableShortcut(
|
||||
|
||||
override val labelOverride: String?
|
||||
get() = null
|
||||
override val componentName: ComponentName?
|
||||
get() = null
|
||||
|
||||
override fun getPlaceholderIcon(context: Context): StaticLauncherIcon {
|
||||
return StaticLauncherIcon(
|
||||
@@ -56,6 +61,14 @@ class UnavailableShortcut(
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getSerializer(): SearchableSerializer {
|
||||
return UnavailableShortcutSerializer()
|
||||
}
|
||||
|
||||
override val isUnavailable: Boolean = true
|
||||
override val profile: AppProfile
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
companion object {
|
||||
internal operator fun invoke(context: Context, id: String, packageName: String, userSerial: Long): UnavailableShortcut? {
|
||||
val appInfo = try {
|
||||
@@ -1,36 +0,0 @@
|
||||
package de.mm20.launcher2.search.data
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.content.ContextCompat
|
||||
import de.mm20.launcher2.appshortcuts.R
|
||||
import de.mm20.launcher2.icons.ColorLayer
|
||||
import de.mm20.launcher2.icons.StaticLauncherIcon
|
||||
import de.mm20.launcher2.icons.TintedIconLayer
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
|
||||
interface AppShortcut: SavableSearchable {
|
||||
|
||||
val appName: String?
|
||||
|
||||
override val preferDetailsOverLaunch: Boolean
|
||||
get() = false
|
||||
|
||||
override fun getPlaceholderIcon(context: Context): StaticLauncherIcon {
|
||||
return StaticLauncherIcon(
|
||||
foregroundLayer = TintedIconLayer(
|
||||
color = 0xFF3DDA84.toInt(),
|
||||
icon = ContextCompat.getDrawable(context, R.drawable.ic_file_android)!!,
|
||||
scale = 0.65f,
|
||||
),
|
||||
backgroundLayer = ColorLayer(0xFF3DDA84.toInt()),
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromPinRequestIntent(context: Context, data: Intent): AppShortcut? {
|
||||
return LauncherShortcut.fromPinRequestIntent(context, data)
|
||||
?: LegacyShortcut.fromPinRequestIntent(context, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user