ktlint: Reformat all util classes
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -20,16 +20,17 @@
|
|||||||
package com.aurora.store.util
|
package com.aurora.store.util
|
||||||
|
|
||||||
import com.aurora.store.data.network.HttpClient
|
import com.aurora.store.data.network.HttpClient
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
|
||||||
class AC2DMTask @Inject constructor(private val httpClient: HttpClient) {
|
class AC2DMTask @Inject constructor(private val httpClient: HttpClient) {
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getAC2DMResponse(email: String?, oAuthToken: String?): Map<String, String> {
|
fun getAC2DMResponse(email: String?, oAuthToken: String?): Map<String, String> {
|
||||||
if (email == null || oAuthToken == null)
|
if (email == null || oAuthToken == null) {
|
||||||
return mapOf()
|
return mapOf()
|
||||||
|
}
|
||||||
|
|
||||||
val params: MutableMap<String, Any> = hashMapOf()
|
val params: MutableMap<String, Any> = hashMapOf()
|
||||||
params["lang"] = Locale.getDefault().toString().replace("_", "-")
|
params["lang"] = Locale.getDefault().toString().replace("_", "-")
|
||||||
|
|||||||
@@ -52,13 +52,12 @@ object CertUtil {
|
|||||||
"com.machiav3lli.fdroid"
|
"com.machiav3lli.fdroid"
|
||||||
)
|
)
|
||||||
|
|
||||||
fun isFDroidApp(context: Context, packageName: String): Boolean {
|
fun isFDroidApp(context: Context, packageName: String): Boolean =
|
||||||
return isInstalledByFDroid(context, packageName) || isSignedByFDroid(context, packageName)
|
isInstalledByFDroid(context, packageName) || isSignedByFDroid(context, packageName)
|
||||||
}
|
|
||||||
|
|
||||||
fun isAppGalleryApp(context: Context, packageName: String): Boolean {
|
fun isAppGalleryApp(context: Context, packageName: String): Boolean =
|
||||||
return context.packageManager.getUpdateOwnerPackageNameCompat(packageName) == PACKAGE_NAME_APP_GALLERY
|
context.packageManager.getUpdateOwnerPackageNameCompat(packageName) ==
|
||||||
}
|
PACKAGE_NAME_APP_GALLERY
|
||||||
|
|
||||||
fun isAuroraStoreApp(context: Context, packageName: String): Boolean {
|
fun isAuroraStoreApp(context: Context, packageName: String): Boolean {
|
||||||
val installerPackageNames = AppInstaller.getAvailableInstallersInfo(context)
|
val installerPackageNames = AppInstaller.getAvailableInstallersInfo(context)
|
||||||
@@ -68,35 +67,31 @@ object CertUtil {
|
|||||||
return installerPackageNames.contains(packageInstaller)
|
return installerPackageNames.contains(packageInstaller)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEncodedCertificateHashes(context: Context, packageName: String): List<String> {
|
fun getEncodedCertificateHashes(context: Context, packageName: String): List<String> = try {
|
||||||
return try {
|
val certificates = getX509Certificates(context, packageName)
|
||||||
val certificates = getX509Certificates(context, packageName)
|
certificates.map {
|
||||||
certificates.map {
|
val messageDigest = MessageDigest.getInstance(Algorithm.SHA.value)
|
||||||
val messageDigest = MessageDigest.getInstance(Algorithm.SHA.value)
|
messageDigest.update(it.encoded)
|
||||||
messageDigest.update(it.encoded)
|
Base64.encodeToString(
|
||||||
Base64.encodeToString(
|
messageDigest.digest(),
|
||||||
messageDigest.digest(),
|
Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP
|
||||||
Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.e(TAG, "Failed to get SHA256 certificate hash", exception)
|
|
||||||
emptyList()
|
|
||||||
}
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Failed to get SHA256 certificate hash", exception)
|
||||||
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSignedByFDroid(context: Context, packageName: String): Boolean {
|
private fun isSignedByFDroid(context: Context, packageName: String): Boolean = try {
|
||||||
return try {
|
getX509Certificates(context, packageName).any { cert ->
|
||||||
getX509Certificates(context, packageName).any { cert ->
|
cert.subjectDN.name.split(",").associate {
|
||||||
cert.subjectDN.name.split(",").associate {
|
val (left, right) = it.split("=")
|
||||||
val (left, right) = it.split("=")
|
left to right
|
||||||
left to right
|
}["O"] == "fdroid.org"
|
||||||
}["O"] == "fdroid.org"
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.e(TAG, "Failed to check signing cert for $packageName")
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Failed to check signing cert for $packageName")
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMicroGGms(context: Context): Boolean {
|
fun isMicroGGms(context: Context): Boolean {
|
||||||
@@ -114,20 +109,23 @@ object CertUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isInstalledByFDroid(context: Context, packageName: String): Boolean {
|
private fun isInstalledByFDroid(context: Context, packageName: String): Boolean =
|
||||||
return fdroidPackages.contains(
|
fdroidPackages.contains(
|
||||||
context.packageManager.getUpdateOwnerPackageNameCompat(packageName)
|
context.packageManager.getUpdateOwnerPackageNameCompat(packageName)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
private fun getX509Certificates(context: Context, packageName: String): List<X509Certificate> {
|
private fun getX509Certificates(context: Context, packageName: String): List<X509Certificate> =
|
||||||
return try {
|
try {
|
||||||
val packageInfo = getPackageInfoWithSignature(context, packageName)
|
val packageInfo = getPackageInfoWithSignature(context, packageName)
|
||||||
if (isPAndAbove) {
|
if (isPAndAbove) {
|
||||||
if (packageInfo.signingInfo!!.hasMultipleSigners()) {
|
if (packageInfo.signingInfo!!.hasMultipleSigners()) {
|
||||||
packageInfo.signingInfo!!.apkContentsSigners.map { it.generateX509Certificate() }
|
packageInfo.signingInfo!!.apkContentsSigners.map {
|
||||||
|
it.generateX509Certificate()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
packageInfo.signingInfo!!.signingCertificateHistory.map { it.generateX509Certificate() }
|
packageInfo.signingInfo!!.signingCertificateHistory.map {
|
||||||
|
it.generateX509Certificate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@@ -137,16 +135,14 @@ object CertUtil {
|
|||||||
Log.e(TAG, "Failed to get X509 certificates", exception)
|
Log.e(TAG, "Failed to get X509 certificates", exception)
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPackageInfoWithSignature(context: Context, packageName: String): PackageInfo {
|
private fun getPackageInfoWithSignature(context: Context, packageName: String): PackageInfo =
|
||||||
return if (isPAndAbove) {
|
if (isPAndAbove) {
|
||||||
getPackageInfo(context, packageName, PackageManager.GET_SIGNING_CERTIFICATES)
|
getPackageInfo(context, packageName, PackageManager.GET_SIGNING_CERTIFICATES)
|
||||||
} else {
|
} else {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
getPackageInfo(context, packageName, PackageManager.GET_SIGNATURES)
|
getPackageInfo(context, packageName, PackageManager.GET_SIGNATURES)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractSHA1Fingerprint(certificate: X509Certificate): String {
|
private fun extractSHA1Fingerprint(certificate: X509Certificate): String {
|
||||||
val messageDigest = MessageDigest.getInstance(Algorithm.SHA1.value)
|
val messageDigest = MessageDigest.getInstance(Algorithm.SHA1.value)
|
||||||
@@ -156,10 +152,9 @@ object CertUtil {
|
|||||||
.lowercase()
|
.lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseX500Principal(principal: X500Principal): Map<String, String> {
|
private fun parseX500Principal(principal: X500Principal): Map<String, String> =
|
||||||
return principal.name.split(",").associate {
|
principal.name.split(",").associate {
|
||||||
val (left, right) = it.split("=")
|
val (left, right) = it.split("=")
|
||||||
left.trim() to right.trim()
|
left.trim() to right.trim()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ object CommonUtil {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun addSiPrefix(value: Long): String {
|
fun addSiPrefix(value: Long): String {
|
||||||
if (value <= 1L)
|
if (value <= 1L) {
|
||||||
return "NA"
|
return "NA"
|
||||||
|
}
|
||||||
var tempValue = value
|
var tempValue = value
|
||||||
var order = 0
|
var order = 0
|
||||||
while (tempValue >= 1000.0) {
|
while (tempValue >= 1000.0) {
|
||||||
@@ -100,7 +101,8 @@ object CommonUtil {
|
|||||||
val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt()
|
val exp = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt()
|
||||||
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1].toString() + if (si) "" else "i"
|
val pre = (if (si) "kMGTPE" else "KMGTPE")[exp - 1].toString() + if (si) "" else "i"
|
||||||
return String.format(
|
return String.format(
|
||||||
Locale.getDefault(), "%.1f %sB/s",
|
Locale.getDefault(),
|
||||||
|
"%.1f %sB/s",
|
||||||
bytes / unit.toDouble().pow(exp.toDouble()),
|
bytes / unit.toDouble().pow(exp.toDouble()),
|
||||||
pre
|
pre
|
||||||
)
|
)
|
||||||
@@ -120,8 +122,8 @@ object CommonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun parseProxyUrl(proxyUrl: String): ProxyInfo? {
|
fun parseProxyUrl(proxyUrl: String): ProxyInfo? {
|
||||||
val pattern = """^(https?|socks5?)://(?:([^\s:@]+):([^\s:@]+)@)?([^\s:@]+):(\d+)$""".toRegex()
|
val pattern = """^(https?|socks5?)://(?:([^\s:@]+):([^\s:@]+)@)?([^\s:@]+):(\d+)$"""
|
||||||
val match = pattern.find(proxyUrl)
|
val match = pattern.toRegex().find(proxyUrl)
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
match != null -> {
|
match != null -> {
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import com.aurora.store.data.installer.AppInstaller
|
|||||||
import com.aurora.store.data.model.DownloadStatus
|
import com.aurora.store.data.model.DownloadStatus
|
||||||
import com.aurora.store.data.receiver.DownloadCancelReceiver
|
import com.aurora.store.data.receiver.DownloadCancelReceiver
|
||||||
import com.aurora.store.data.room.download.Download
|
import com.aurora.store.data.room.download.Download
|
||||||
|
import com.aurora.store.data.room.download.Download as AuroraDownload
|
||||||
import com.aurora.store.data.room.update.Update
|
import com.aurora.store.data.room.update.Update
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import com.aurora.store.data.room.download.Download as AuroraDownload
|
|
||||||
|
|
||||||
object NotificationUtil {
|
object NotificationUtil {
|
||||||
|
|
||||||
@@ -78,14 +78,13 @@ object NotificationUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDownloadNotification(context: Context): Notification {
|
fun getDownloadNotification(context: Context): Notification =
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_DOWNLOADS)
|
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_DOWNLOADS)
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
.setContentTitle(context.getString(R.string.app_updater_service_notif_title))
|
.setContentTitle(context.getString(R.string.app_updater_service_notif_title))
|
||||||
.setContentText(context.getString(R.string.app_updater_service_notif_text))
|
.setContentText(context.getString(R.string.app_updater_service_notif_text))
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.build()
|
.build()
|
||||||
}
|
|
||||||
|
|
||||||
fun getDownloadNotification(
|
fun getDownloadNotification(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -186,37 +185,32 @@ object NotificationUtil {
|
|||||||
context: Context,
|
context: Context,
|
||||||
displayName: String,
|
displayName: String,
|
||||||
packageName: String
|
packageName: String
|
||||||
): Notification {
|
): Notification = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_INSTALL)
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_INSTALL)
|
.setSmallIcon(R.drawable.ic_install)
|
||||||
.setSmallIcon(R.drawable.ic_install)
|
.setLargeIcon(PackageUtil.getIconForPackage(context, packageName))
|
||||||
.setLargeIcon(PackageUtil.getIconForPackage(context, packageName))
|
.setContentTitle(displayName)
|
||||||
.setContentTitle(displayName)
|
.setContentText(context.getString(R.string.installer_status_success))
|
||||||
.setContentText(context.getString(R.string.installer_status_success))
|
.setContentIntent(getContentIntentForDetails(context, packageName))
|
||||||
.setContentIntent(getContentIntentForDetails(context, packageName))
|
.build()
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getInstallerStatusNotification(
|
fun getInstallerStatusNotification(
|
||||||
context: Context,
|
context: Context,
|
||||||
packageName: String,
|
packageName: String,
|
||||||
displayName: String,
|
displayName: String,
|
||||||
content: String?
|
content: String?
|
||||||
): Notification {
|
): Notification = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_INSTALL)
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_INSTALL)
|
.setSmallIcon(R.drawable.ic_install)
|
||||||
.setSmallIcon(R.drawable.ic_install)
|
.setContentTitle(displayName)
|
||||||
.setContentTitle(displayName)
|
.setContentText(content)
|
||||||
.setContentText(content)
|
.setContentIntent(getContentIntentForDetails(context, packageName))
|
||||||
.setContentIntent(getContentIntentForDetails(context, packageName))
|
.build()
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getUpdateNotification(context: Context): Notification {
|
fun getUpdateNotification(context: Context): Notification =
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_UPDATES)
|
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_UPDATES)
|
||||||
.setSmallIcon(R.drawable.ic_updates)
|
.setSmallIcon(R.drawable.ic_updates)
|
||||||
.setContentTitle(context.getString(R.string.checking_updates))
|
.setContentTitle(context.getString(R.string.checking_updates))
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.build()
|
.build()
|
||||||
}
|
|
||||||
|
|
||||||
fun getUpdateNotification(context: Context, updatesList: List<Update>): Notification {
|
fun getUpdateNotification(context: Context, updatesList: List<Update>): Notification {
|
||||||
val contentIntent = NavDeepLinkBuilder(context)
|
val contentIntent = NavDeepLinkBuilder(context)
|
||||||
@@ -229,16 +223,17 @@ object NotificationUtil {
|
|||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_UPDATES)
|
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_UPDATES)
|
||||||
.setSmallIcon(R.drawable.ic_updates)
|
.setSmallIcon(R.drawable.ic_updates)
|
||||||
.setContentTitle(
|
.setContentTitle(
|
||||||
if (updatesList.size == 1)
|
if (updatesList.size == 1) {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.notification_updates_available_1,
|
R.string.notification_updates_available_1,
|
||||||
updatesList.size
|
updatesList.size
|
||||||
)
|
)
|
||||||
else
|
} else {
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.notification_updates_available,
|
R.string.notification_updates_available,
|
||||||
updatesList.size
|
updatesList.size
|
||||||
)
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.setContentText(
|
.setContentText(
|
||||||
when (updatesList.size) {
|
when (updatesList.size) {
|
||||||
@@ -284,17 +279,16 @@ object NotificationUtil {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getExportNotification(context: Context): Notification {
|
fun getExportNotification(context: Context): Notification =
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_EXPORT)
|
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_EXPORT)
|
||||||
.setSmallIcon(R.drawable.ic_file_copy)
|
.setSmallIcon(R.drawable.ic_file_copy)
|
||||||
.setContentTitle(context.getString(R.string.export_app_title))
|
.setContentTitle(context.getString(R.string.export_app_title))
|
||||||
.setContentText(context.getString(R.string.export_app_summary))
|
.setContentText(context.getString(R.string.export_app_summary))
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.build()
|
.build()
|
||||||
}
|
|
||||||
|
|
||||||
fun getUnarchiveAuthNotification(context: Context, packageName: String): Notification {
|
fun getUnarchiveAuthNotification(context: Context, packageName: String): Notification =
|
||||||
return NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ACCOUNT)
|
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ACCOUNT)
|
||||||
.setSmallIcon(R.drawable.ic_account)
|
.setSmallIcon(R.drawable.ic_account)
|
||||||
.setContentTitle(context.getString(R.string.authentication_required_title))
|
.setContentTitle(context.getString(R.string.authentication_required_title))
|
||||||
.setContentText(context.getString(R.string.authentication_required_unarchive))
|
.setContentText(context.getString(R.string.authentication_required_unarchive))
|
||||||
@@ -303,7 +297,6 @@ object NotificationUtil {
|
|||||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.build()
|
.build()
|
||||||
}
|
|
||||||
|
|
||||||
fun getExportStatusNotification(
|
fun getExportStatusNotification(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -362,23 +355,21 @@ object NotificationUtil {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getContentIntentForSplash(context: Context, packageName: String): PendingIntent {
|
private fun getContentIntentForSplash(context: Context, packageName: String): PendingIntent =
|
||||||
return NavDeepLinkBuilder(context)
|
NavDeepLinkBuilder(context)
|
||||||
.setGraph(R.navigation.mobile_navigation)
|
.setGraph(R.navigation.mobile_navigation)
|
||||||
.setDestination(R.id.splashFragment)
|
.setDestination(R.id.splashFragment)
|
||||||
.setComponentName(MainActivity::class.java)
|
.setComponentName(MainActivity::class.java)
|
||||||
.setArguments(bundleOf("packageName" to packageName))
|
.setArguments(bundleOf("packageName" to packageName))
|
||||||
.createPendingIntent()
|
.createPendingIntent()
|
||||||
}
|
|
||||||
|
|
||||||
private fun getContentIntentForDetails(context: Context, packageName: String): PendingIntent {
|
private fun getContentIntentForDetails(context: Context, packageName: String): PendingIntent =
|
||||||
return NavDeepLinkBuilder(context)
|
NavDeepLinkBuilder(context)
|
||||||
.setGraph(R.navigation.mobile_navigation)
|
.setGraph(R.navigation.mobile_navigation)
|
||||||
.setDestination(R.id.splashFragment)
|
.setDestination(R.id.splashFragment)
|
||||||
.setComponentName(MainActivity::class.java)
|
.setComponentName(MainActivity::class.java)
|
||||||
.setArguments(bundleOf("packageName" to packageName))
|
.setArguments(bundleOf("packageName" to packageName))
|
||||||
.createPendingIntent()
|
.createPendingIntent()
|
||||||
}
|
|
||||||
|
|
||||||
private fun getInstallIntent(context: Context, download: Download): PendingIntent? {
|
private fun getInstallIntent(context: Context, download: Download): PendingIntent? {
|
||||||
val intent = Intent(context, InstallActivity::class.java).apply {
|
val intent = Intent(context, InstallActivity::class.java).apply {
|
||||||
|
|||||||
@@ -58,14 +58,13 @@ object PackageUtil {
|
|||||||
private const val VERSION_CODE_MICROG_COMPANION_MIN: Long = 84022620
|
private const val VERSION_CODE_MICROG_COMPANION_MIN: Long = 84022620
|
||||||
private const val MICROG_INSTALL_ACTIVITY = "org.microg.vending.installer.AppInstallActivity"
|
private const val MICROG_INSTALL_ACTIVITY = "org.microg.vending.installer.AppInstallActivity"
|
||||||
|
|
||||||
fun getAllValidPackages(context: Context): List<PackageInfo> {
|
fun getAllValidPackages(context: Context): List<PackageInfo> =
|
||||||
return context.packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
|
context.packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
|
||||||
.filter { it.isValidApp(context.packageManager) }
|
.filter { it.isValidApp(context.packageManager) }
|
||||||
.sortedBy {
|
.sortedBy {
|
||||||
it.applicationInfo!!.loadLabel(context.packageManager).toString()
|
it.applicationInfo!!.loadLabel(context.packageManager).toString()
|
||||||
.lowercase(Locale.getDefault())
|
.lowercase(Locale.getDefault())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun hasSupportedAppGallery(context: Context): Boolean {
|
fun hasSupportedAppGallery(context: Context): Boolean {
|
||||||
return try {
|
return try {
|
||||||
@@ -85,10 +84,11 @@ object PackageUtil {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
val versionCode = if (Build.VERSION.SDK_INT >= 28)
|
val versionCode = if (Build.VERSION.SDK_INT >= 28) {
|
||||||
packageInfo.longVersionCode
|
packageInfo.longVersionCode
|
||||||
else
|
} else {
|
||||||
packageInfo.versionCode.toLong()
|
packageInfo.versionCode.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
Log.i(TAG, "AppGallery - ${packageInfo.versionName} ($versionCode)")
|
Log.i(TAG, "AppGallery - ${packageInfo.versionName} ($versionCode)")
|
||||||
|
|
||||||
@@ -119,20 +119,18 @@ object PackageUtil {
|
|||||||
return resolveInfo != null
|
return resolveInfo != null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasMicroGCompanion(context: Context): Boolean {
|
fun hasMicroGCompanion(context: Context): Boolean = isInstalled(
|
||||||
return isInstalled(
|
context,
|
||||||
context,
|
PACKAGE_NAME_PLAY_STORE,
|
||||||
PACKAGE_NAME_PLAY_STORE,
|
VERSION_CODE_MICROG_COMPANION_MIN
|
||||||
VERSION_CODE_MICROG_COMPANION_MIN
|
) && hasActivity(
|
||||||
) && hasActivity(
|
context,
|
||||||
context,
|
PACKAGE_NAME_PLAY_STORE,
|
||||||
PACKAGE_NAME_PLAY_STORE,
|
MICROG_INSTALL_ACTIVITY
|
||||||
MICROG_INSTALL_ACTIVITY
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isInstalled(context: Context, packageName: String, versionCode: Long? = null): Boolean {
|
fun isInstalled(context: Context, packageName: String, versionCode: Long? = null): Boolean =
|
||||||
return try {
|
try {
|
||||||
val packageInfo = getPackageInfo(context, packageName, PackageManager.GET_META_DATA)
|
val packageInfo = getPackageInfo(context, packageName, PackageManager.GET_META_DATA)
|
||||||
if (versionCode != null) {
|
if (versionCode != null) {
|
||||||
PackageInfoCompat.getLongVersionCode(packageInfo) >= versionCode
|
PackageInfoCompat.getLongVersionCode(packageInfo) >= versionCode
|
||||||
@@ -142,44 +140,37 @@ object PackageUtil {
|
|||||||
} catch (_: PackageManager.NameNotFoundException) {
|
} catch (_: PackageManager.NameNotFoundException) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isArchived(context: Context, packageName: String): Boolean = try {
|
||||||
|
isVAndAbove && context.packageManager.getArchivedPackage(packageName) != null
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isArchived(context: Context, packageName: String): Boolean {
|
fun isSharedLibrary(context: Context, packageName: String): Boolean = if (isOAndAbove) {
|
||||||
return try {
|
getAllSharedLibraries(context).any { it.name == packageName }
|
||||||
isVAndAbove && context.packageManager.getArchivedPackage(packageName) != null
|
} else {
|
||||||
} catch (e: Exception) {
|
false
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isSharedLibrary(context: Context, packageName: String): Boolean {
|
|
||||||
return if (isOAndAbove) {
|
|
||||||
getAllSharedLibraries(context).any { it.name == packageName }
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSharedLibraryInstalled(
|
fun isSharedLibraryInstalled(
|
||||||
context: Context,
|
context: Context,
|
||||||
packageName: String,
|
packageName: String,
|
||||||
versionCode: Long
|
versionCode: Long
|
||||||
): Boolean {
|
): Boolean = if (isOAndAbove) {
|
||||||
return if (isOAndAbove) {
|
val sharedLibraries = getAllSharedLibraries(context)
|
||||||
val sharedLibraries = getAllSharedLibraries(context)
|
if (isPAndAbove) {
|
||||||
if (isPAndAbove) {
|
sharedLibraries.any {
|
||||||
sharedLibraries.any {
|
it.name == packageName && it.longVersion == versionCode
|
||||||
it.name == packageName && it.longVersion == versionCode
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sharedLibraries.any {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
it.name == packageName && it.version == versionCode.toInt()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
sharedLibraries.any {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
it.name == packageName && it.version == versionCode.toInt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isUpdatable(context: Context, packageName: String, versionCode: Long): Boolean {
|
fun isUpdatable(context: Context, packageName: String, versionCode: Long): Boolean {
|
||||||
@@ -191,48 +182,45 @@ object PackageUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMicroGBundleInstalled(context: Context): Boolean {
|
/**
|
||||||
/**
|
* Confirm if MicroG bundle is installed
|
||||||
* Confirm if MicroG bundle is installed
|
* Considering the following:
|
||||||
* Considering the following:
|
* 1. GmsCore is installed and it is a microG huawei variant
|
||||||
* 1. GmsCore is installed and it is a microG huawei variant
|
* 2. Play Store is installed - (microG Companion)
|
||||||
* 2. Play Store is installed - (microG Companion)
|
*/
|
||||||
*/
|
fun isMicroGBundleInstalled(context: Context): Boolean =
|
||||||
return hasSupportedMicroGVariant(context) && isInstalled(context, PACKAGE_NAME_PLAY_STORE)
|
hasSupportedMicroGVariant(context) && isInstalled(context, PACKAGE_NAME_PLAY_STORE)
|
||||||
|
|
||||||
|
fun getInstalledVersionName(context: Context, packageName: String): String = try {
|
||||||
|
getPackageInfo(context, packageName).versionName ?: ""
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInstalledVersionName(context: Context, packageName: String): String {
|
fun getInstalledVersionCode(context: Context, packageName: String): Long = try {
|
||||||
return try {
|
PackageInfoCompat.getLongVersionCode(getPackageInfo(context, packageName))
|
||||||
getPackageInfo(context, packageName).versionName ?: ""
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
0
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInstalledVersionCode(context: Context, packageName: String): Long {
|
fun isTv(context: Context): Boolean =
|
||||||
return try {
|
context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
||||||
PackageInfoCompat.getLongVersionCode(getPackageInfo(context, packageName))
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isTv(context: Context): Boolean {
|
|
||||||
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLaunchIntent(context: Context, packageName: String?): Intent? {
|
fun getLaunchIntent(context: Context, packageName: String?): Intent? {
|
||||||
val intent = if (isTv(context)) {
|
val intent = if (isTv(context)) {
|
||||||
context.packageManager.getLeanbackLaunchIntentForPackage(packageName!!)
|
context.packageManager.getLeanbackLaunchIntentForPackage(packageName!!)
|
||||||
} else {
|
} else {
|
||||||
context.packageManager.getLaunchIntentForPackage(packageName!!)
|
context.packageManager.getLaunchIntentForPackage(packageName!!)
|
||||||
}
|
} ?: return null
|
||||||
|
|
||||||
return if (intent == null) {
|
return intent.apply {
|
||||||
null
|
addCategory(
|
||||||
} else {
|
if (isTv(context)) {
|
||||||
intent.addCategory(if (isTv(context)) Intent.CATEGORY_LEANBACK_LAUNCHER else Intent.CATEGORY_LAUNCHER)
|
Intent.CATEGORY_LEANBACK_LAUNCHER
|
||||||
intent
|
} else {
|
||||||
|
Intent.CATEGORY_LAUNCHER
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,15 +245,13 @@ object PackageUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getInstallUnknownAppsIntent(): Intent {
|
fun getInstallUnknownAppsIntent(): Intent = if (isOAndAbove) {
|
||||||
return if (isOAndAbove) {
|
Intent(
|
||||||
Intent(
|
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
|
||||||
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
|
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
||||||
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
)
|
||||||
)
|
} else {
|
||||||
} else {
|
Intent(Settings.ACTION_SECURITY_SETTINGS)
|
||||||
Intent(Settings.ACTION_SECURITY_SETTINGS)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canRequestPackageInstalls(context: Context): Boolean {
|
fun canRequestPackageInstalls(context: Context): Boolean {
|
||||||
@@ -275,7 +261,8 @@ object PackageUtil {
|
|||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
val secureResult = Settings.Secure.getInt(
|
val secureResult = Settings.Secure.getInt(
|
||||||
context.contentResolver,
|
context.contentResolver,
|
||||||
Settings.Secure.INSTALL_NON_MARKET_APPS, 0
|
Settings.Secure.INSTALL_NON_MARKET_APPS,
|
||||||
|
0
|
||||||
)
|
)
|
||||||
|
|
||||||
return secureResult == 1
|
return secureResult == 1
|
||||||
@@ -283,8 +270,8 @@ object PackageUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getPackageInfo(context: Context, packageName: String, flags: Int = 0): PackageInfo {
|
fun getPackageInfo(context: Context, packageName: String, flags: Int = 0): PackageInfo =
|
||||||
return if (isTAndAbove) {
|
if (isTAndAbove) {
|
||||||
context.packageManager.getPackageInfo(
|
context.packageManager.getPackageInfo(
|
||||||
packageName,
|
packageName,
|
||||||
PackageInfoFlags.of(flags.toLong())
|
PackageInfoFlags.of(flags.toLong())
|
||||||
@@ -292,21 +279,18 @@ object PackageUtil {
|
|||||||
} else {
|
} else {
|
||||||
context.packageManager.getPackageInfo(packageName, flags)
|
context.packageManager.getPackageInfo(packageName, flags)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun getIconForPackage(context: Context, packageName: String): Bitmap? {
|
fun getIconForPackage(context: Context, packageName: String): Bitmap? = try {
|
||||||
return try {
|
val packageInfo = context.packageManager.getPackageInfo(packageName, 0)
|
||||||
val packageInfo = context.packageManager.getPackageInfo(packageName, 0)
|
val icon = packageInfo.applicationInfo!!.loadIcon(context.packageManager)
|
||||||
val icon = packageInfo.applicationInfo!!.loadIcon(context.packageManager)
|
if (icon.intrinsicWidth > 0 && icon.intrinsicHeight > 0) {
|
||||||
if (icon.intrinsicWidth > 0 && icon.intrinsicHeight > 0) {
|
icon.toBitmap(96, 96)
|
||||||
icon.toBitmap(96, 96)
|
} else {
|
||||||
} else {
|
context.packageManager.defaultActivityIcon.toBitmap(96, 96)
|
||||||
context.packageManager.defaultActivityIcon.toBitmap(96, 96)
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.e(TAG, "Failed to get icon for package!", exception)
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Failed to get icon for package!", exception)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIconDrawableForPackage(context: Context, packageName: String): Drawable? {
|
fun getIconDrawableForPackage(context: Context, packageName: String): Drawable? {
|
||||||
@@ -323,15 +307,14 @@ object PackageUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAllSharedLibraries(context: Context, flags: Int = 0): List<SharedLibraryInfo> {
|
private fun getAllSharedLibraries(context: Context, flags: Int = 0): List<SharedLibraryInfo> =
|
||||||
return if (isTAndAbove) {
|
if (isTAndAbove) {
|
||||||
context.packageManager.getSharedLibraries(PackageInfoFlags.of(flags.toLong()))
|
context.packageManager.getSharedLibraries(PackageInfoFlags.of(flags.toLong()))
|
||||||
} else if (isOAndAbove) {
|
} else if (isOAndAbove) {
|
||||||
context.packageManager.getSharedLibraries(flags)
|
context.packageManager.getSharedLibraries(flags)
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun getFilter(): IntentFilter {
|
fun getFilter(): IntentFilter {
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
|
|||||||
@@ -32,36 +32,28 @@ object PathUtil {
|
|||||||
private const val DOWNLOADS = "Downloads"
|
private const val DOWNLOADS = "Downloads"
|
||||||
private const val SPOOF = "SpoofConfigs"
|
private const val SPOOF = "SpoofConfigs"
|
||||||
|
|
||||||
fun getOldDownloadDirectories(context: Context): List<File> {
|
fun getOldDownloadDirectories(context: Context): List<File> = listOf(
|
||||||
return listOf(
|
File(context.filesDir, DOWNLOADS), // till 4.4.2
|
||||||
File(context.filesDir, DOWNLOADS), // till 4.4.2
|
File(context.getExternalFilesDir(null), DOWNLOADS) // till 4.4.2
|
||||||
File(context.getExternalFilesDir(null), DOWNLOADS) // till 4.4.2
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDownloadDirectory(context: Context): File {
|
fun getDownloadDirectory(context: Context): File = File(context.cacheDir, DOWNLOADS)
|
||||||
return File(context.cacheDir, DOWNLOADS)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPackageDirectory(context: Context, packageName: String): File {
|
private fun getPackageDirectory(context: Context, packageName: String): File =
|
||||||
return File(getDownloadDirectory(context), packageName)
|
File(getDownloadDirectory(context), packageName)
|
||||||
}
|
|
||||||
|
|
||||||
fun getAppDownloadDir(context: Context, packageName: String, versionCode: Long): File {
|
fun getAppDownloadDir(context: Context, packageName: String, versionCode: Long): File =
|
||||||
return File(getPackageDirectory(context, packageName), versionCode.toString())
|
File(getPackageDirectory(context, packageName), versionCode.toString())
|
||||||
}
|
|
||||||
|
|
||||||
fun getLibDownloadDir(
|
fun getLibDownloadDir(
|
||||||
context: Context,
|
context: Context,
|
||||||
packageName: String,
|
packageName: String,
|
||||||
versionCode: Long,
|
versionCode: Long,
|
||||||
sharedLibPackageName: String
|
sharedLibPackageName: String
|
||||||
): File {
|
): File = File(
|
||||||
return File(
|
getAppDownloadDir(context, packageName, versionCode),
|
||||||
getAppDownloadDir(context, packageName, versionCode),
|
"$LIBRARIES/$sharedLibPackageName"
|
||||||
"$LIBRARIES/$sharedLibPackageName"
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an instance of java's [File] class for the given [PlayFile]
|
* Returns an instance of java's [File] class for the given [PlayFile]
|
||||||
@@ -92,23 +84,19 @@ object PathUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getZipFile(context: Context, packageName: String, versionCode: Long): File {
|
fun getZipFile(context: Context, packageName: String, versionCode: Long): File = File(
|
||||||
return File(
|
getAppDownloadDir(
|
||||||
getAppDownloadDir(
|
context,
|
||||||
context,
|
packageName,
|
||||||
packageName,
|
versionCode
|
||||||
versionCode,
|
),
|
||||||
), "${packageName}_${versionCode}.apks"
|
"${packageName}_$versionCode.apks"
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun getObbDownloadDir(packageName: String): File {
|
fun getObbDownloadDir(packageName: String): File =
|
||||||
return File(Environment.getExternalStorageDirectory(), "/Android/obb/$packageName")
|
File(Environment.getExternalStorageDirectory(), "/Android/obb/$packageName")
|
||||||
}
|
|
||||||
|
|
||||||
fun getSpoofDirectory(context: Context): File {
|
fun getSpoofDirectory(context: Context): File = File(context.filesDir, SPOOF)
|
||||||
return File(context.filesDir, SPOOF)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNewEmptySpoofConfig(context: Context): File {
|
fun getNewEmptySpoofConfig(context: Context): File {
|
||||||
val file = File(getSpoofDirectory(context), "${UUID.randomUUID()}.properties")
|
val file = File(getSpoofDirectory(context), "${UUID.randomUUID()}.properties")
|
||||||
@@ -117,4 +105,3 @@ object PathUtil {
|
|||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,17 +64,15 @@ object Preferences {
|
|||||||
|
|
||||||
private var prefs: SharedPreferences? = null
|
private var prefs: SharedPreferences? = null
|
||||||
|
|
||||||
fun getPrefs(context: Context): SharedPreferences {
|
fun getPrefs(context: Context): SharedPreferences = when (BuildConfig.FLAVOR) {
|
||||||
return when (BuildConfig.FLAVOR) {
|
"vanilla" -> {
|
||||||
"vanilla" -> {
|
prefs ?: PreferenceManager.getDefaultSharedPreferences(context).also { prefs = it }
|
||||||
prefs ?: PreferenceManager.getDefaultSharedPreferences(context).also { prefs = it }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val prefName = "${context.packageName}_${BuildConfig.FLAVOR}_preferences"
|
val prefName = "${context.packageName}_${BuildConfig.FLAVOR}_preferences"
|
||||||
prefs ?: context.getSharedPreferences(prefName, Context.MODE_PRIVATE)
|
prefs ?: context.getSharedPreferences(prefName, Context.MODE_PRIVATE)
|
||||||
.also { prefs = it }
|
.also { prefs = it }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,33 +108,24 @@ object Preferences {
|
|||||||
getPrefs(context).edit(true) { putBoolean(key, value) }
|
getPrefs(context).edit(true) { putBoolean(key, value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getString(context: Context, key: String, default: String = ""): String {
|
fun getString(context: Context, key: String, default: String = ""): String =
|
||||||
return getPrefs(context).getString(key, default).toString()
|
getPrefs(context).getString(key, default).toString()
|
||||||
}
|
|
||||||
|
|
||||||
fun getStringSet(
|
fun getStringSet(
|
||||||
context: Context,
|
context: Context,
|
||||||
key: String,
|
key: String,
|
||||||
default: Set<String> = emptySet()
|
default: Set<String> = emptySet()
|
||||||
): Set<String> {
|
): Set<String> = getPrefs(context).getStringSet(key, default) ?: emptySet()
|
||||||
return getPrefs(context).getStringSet(key, default) ?: emptySet()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getInteger(context: Context, key: String, default: Int = 0): Int {
|
fun getInteger(context: Context, key: String, default: Int = 0): Int =
|
||||||
return getPrefs(context).getInt(key, default)
|
getPrefs(context).getInt(key, default)
|
||||||
}
|
|
||||||
|
|
||||||
fun getFloat(context: Context, key: String): Float {
|
fun getFloat(context: Context, key: String): Float = getPrefs(context).getFloat(key, 0.0f)
|
||||||
return getPrefs(context).getFloat(key, 0.0f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLong(context: Context, key: String): Long {
|
fun getLong(context: Context, key: String): Long = getPrefs(context).getLong(key, 0L)
|
||||||
return getPrefs(context).getLong(key, 0L)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBoolean(context: Context, key: String, default: Boolean = false): Boolean {
|
fun getBoolean(context: Context, key: String, default: Boolean = false): Boolean =
|
||||||
return getPrefs(context).getBoolean(key, default)
|
getPrefs(context).getBoolean(key, default)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Preference Extensions*/
|
/*Preference Extensions*/
|
||||||
@@ -151,7 +140,6 @@ fun Context.save(key: String, value: Set<String>) = Preferences.putStringSet(thi
|
|||||||
|
|
||||||
fun Context.remove(key: String) = Preferences.remove(this, key)
|
fun Context.remove(key: String) = Preferences.remove(this, key)
|
||||||
|
|
||||||
|
|
||||||
fun Fragment.save(key: String, value: Int) = requireContext().save(key, value)
|
fun Fragment.save(key: String, value: Int) = requireContext().save(key, value)
|
||||||
|
|
||||||
fun Fragment.save(key: String, value: Boolean) = requireContext().save(key, value)
|
fun Fragment.save(key: String, value: Boolean) = requireContext().save(key, value)
|
||||||
|
|||||||
@@ -11,10 +11,9 @@ object ShortcutManagerUtil {
|
|||||||
|
|
||||||
private const val TAG = "ShortcutManagerUtil"
|
private const val TAG = "ShortcutManagerUtil"
|
||||||
|
|
||||||
fun canPinShortcut(context: Context, packageName: String): Boolean {
|
fun canPinShortcut(context: Context, packageName: String): Boolean =
|
||||||
return ShortcutManagerCompat.isRequestPinShortcutSupported(context) &&
|
ShortcutManagerCompat.isRequestPinShortcutSupported(context) &&
|
||||||
context.packageManager.getLaunchIntentForPackage(packageName) != null
|
context.packageManager.getLaunchIntentForPackage(packageName) != null
|
||||||
}
|
|
||||||
|
|
||||||
fun requestPinShortcut(context: Context, packageName: String) {
|
fun requestPinShortcut(context: Context, packageName: String) {
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
|
|||||||
Reference in New Issue
Block a user