diff --git a/app/src/main/java/com/aurora/store/data/event/BusEvent.kt b/app/src/main/java/com/aurora/store/data/event/BusEvent.kt index d7b56c83e..444e18c37 100644 --- a/app/src/main/java/com/aurora/store/data/event/BusEvent.kt +++ b/app/src/main/java/com/aurora/store/data/event/BusEvent.kt @@ -44,6 +44,6 @@ open class InstallerEvent(open val packageName: String) : Event() { data class Failed( override val packageName: String, val error: String? = null, - val extra: String? = null, + val extra: String? = null ) : InstallerEvent(packageName) } diff --git a/app/src/main/java/com/aurora/store/data/event/EventFlow.kt b/app/src/main/java/com/aurora/store/data/event/EventFlow.kt index 063a08915..495e8245a 100644 --- a/app/src/main/java/com/aurora/store/data/event/EventFlow.kt +++ b/app/src/main/java/com/aurora/store/data/event/EventFlow.kt @@ -2,9 +2,9 @@ package com.aurora.store.data.event import android.util.Log import com.aurora.extensions.TAG +import javax.inject.Singleton import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow -import javax.inject.Singleton @Singleton class EventFlow { diff --git a/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt b/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt index f95f2a187..b0a9b7fb2 100644 --- a/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt +++ b/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt @@ -18,13 +18,13 @@ import com.aurora.store.data.room.update.Update import com.aurora.store.data.work.DownloadWorker import com.aurora.store.util.PathUtil import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import javax.inject.Inject /** * Helper class to work with the [DownloadWorker]. diff --git a/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt b/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt index 50e2c4cdd..37a6c7fa0 100644 --- a/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt +++ b/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt @@ -25,6 +25,10 @@ import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_IDLE import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_METERED import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL import dagger.hilt.android.qualifiers.ApplicationContext +import java.util.UUID +import java.util.concurrent.TimeUnit.HOURS +import java.util.concurrent.TimeUnit.MINUTES +import javax.inject.Inject import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.launchIn @@ -32,10 +36,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import java.util.UUID -import java.util.concurrent.TimeUnit.HOURS -import java.util.concurrent.TimeUnit.MINUTES -import javax.inject.Inject /** * Helper class to work with the [UpdateWorker]. diff --git a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt index 72b54cda1..d0739df30 100644 --- a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt @@ -31,6 +31,7 @@ import com.aurora.extensions.isOAndAbove import com.aurora.extensions.isPAndAbove import com.aurora.extensions.isSAndAbove import com.aurora.store.BuildConfig +import com.aurora.store.data.installer.ShizukuInstaller.Companion.SHIZUKU_PACKAGE_NAME import com.aurora.store.data.installer.base.IInstaller import com.aurora.store.data.model.Installer import com.aurora.store.data.model.InstallerInfo @@ -40,10 +41,10 @@ import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID import com.topjohnwu.superuser.Shell import dagger.hilt.android.qualifiers.ApplicationContext -import rikka.shizuku.Shizuku -import rikka.sui.Sui import javax.inject.Inject import javax.inject.Singleton +import rikka.shizuku.Shizuku +import rikka.sui.Sui @Singleton class AppInstaller @Inject constructor( @@ -58,27 +59,28 @@ class AppInstaller @Inject constructor( ) { companion object { - const val ACTION_INSTALL_STATUS = "com.aurora.store.data.installer.AppInstaller.INSTALL_STATUS" + const val ACTION_INSTALL_STATUS = + "com.aurora.store.data.installer.AppInstaller.INSTALL_STATUS" - const val EXTRA_PACKAGE_NAME = "com.aurora.store.data.installer.AppInstaller.EXTRA_PACKAGE_NAME" - const val EXTRA_VERSION_CODE = "com.aurora.store.data.installer.AppInstaller.EXTRA_VERSION_CODE" - const val EXTRA_DISPLAY_NAME = "com.aurora.store.data.installer.AppInstaller.EXTRA_DISPLAY_NAME" + const val EXTRA_PACKAGE_NAME = + "com.aurora.store.data.installer.AppInstaller.EXTRA_PACKAGE_NAME" + const val EXTRA_VERSION_CODE = + "com.aurora.store.data.installer.AppInstaller.EXTRA_VERSION_CODE" + const val EXTRA_DISPLAY_NAME = + "com.aurora.store.data.installer.AppInstaller.EXTRA_DISPLAY_NAME" - fun getCurrentInstaller(context: Context): Installer { - return Installer.entries[Preferences.getInteger(context, PREFERENCE_INSTALLER_ID)] - } + fun getCurrentInstaller(context: Context): Installer = + Installer.entries[Preferences.getInteger(context, PREFERENCE_INSTALLER_ID)] - fun getAvailableInstallersInfo(context: Context): List { - return listOfNotNull( - SessionInstaller.installerInfo, - NativeInstaller.installerInfo, - if (hasRootAccess()) RootInstaller.installerInfo else null, - if (hasAuroraService(context)) ServiceInstaller.installerInfo else null, - if (hasAppManager(context)) AMInstaller.installerInfo else null, - if (hasShizukuOrSui(context)) ShizukuInstaller.installerInfo else null, - if (hasMicroGCompanion(context)) MicroGInstaller.installerInfo else null - ) - } + fun getAvailableInstallersInfo(context: Context): List = listOfNotNull( + SessionInstaller.installerInfo, + NativeInstaller.installerInfo, + if (hasRootAccess()) RootInstaller.installerInfo else null, + if (hasAuroraService(context)) ServiceInstaller.installerInfo else null, + if (hasAppManager(context)) AMInstaller.installerInfo else null, + if (hasShizukuOrSui(context)) ShizukuInstaller.installerInfo else null, + if (hasMicroGCompanion(context)) MicroGInstaller.installerInfo else null + ) /** * Checks if the given package can be silently installed @@ -92,60 +94,71 @@ class AppInstaller @Inject constructor( if (!PackageUtil.isInstalled(context, packageName) || !isSAndAbove) return false // We cannot do silent updates if we are not the update owner - if (context.packageManager.getUpdateOwnerPackageNameCompat(packageName) != BuildConfig.APPLICATION_ID) return false + if (context.packageManager.getUpdateOwnerPackageNameCompat(packageName) != + BuildConfig.APPLICATION_ID + ) { + return false + } // Ensure app being installed satisfies Android's requirement for targetSdk level when (Build.VERSION.SDK_INT) { - Build.VERSION_CODES.BAKLAVA -> targetSdk >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE - Build.VERSION_CODES.VANILLA_ICE_CREAM -> targetSdk >= Build.VERSION_CODES.TIRAMISU + Build.VERSION_CODES.BAKLAVA -> { + targetSdk >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE + } + + Build.VERSION_CODES.VANILLA_ICE_CREAM -> { + targetSdk >= Build.VERSION_CODES.TIRAMISU + } + Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> targetSdk >= Build.VERSION_CODES.S + Build.VERSION_CODES.TIRAMISU -> targetSdk >= Build.VERSION_CODES.R + Build.VERSION_CODES.S -> targetSdk >= Build.VERSION_CODES.Q + else -> false // Only Android version above 12 can silently update apps } } - Installer.NATIVE -> false // Native installer requires user interaction + + // Native installer requires user interaction + Installer.NATIVE -> false + Installer.ROOT -> hasRootAccess() + Installer.SERVICE -> hasAuroraService(context) - Installer.AM -> false // We cannot check if AppManager has ability to auto-update + + // We cannot check if AppManager has ability to auto-update + Installer.AM -> false + Installer.SHIZUKU -> isOAndAbove && hasShizukuOrSui(context) && hasShizukuPerm() + Installer.MICROG -> false } } - fun hasRootAccess(): Boolean { - return Shell.getShell().isRoot - } + fun hasRootAccess(): Boolean = Shell.getShell().isRoot - fun hasAuroraService(context: Context): Boolean { - return try { - val packageInfo = PackageUtil.getPackageInfo( - context, - ServiceInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME - ) - val version = PackageInfoCompat.getLongVersionCode(packageInfo) - - packageInfo.applicationInfo!!.enabled && version >= 9 - } catch (exception: Exception) { - false - } - } - - fun hasAppManager(context: Context): Boolean { - return PackageUtil.isInstalled(context, AMInstaller.AM_PACKAGE_NAME) or - PackageUtil.isInstalled(context, AMInstaller.AM_DEBUG_PACKAGE_NAME) - } - - fun hasShizukuOrSui(context: Context): Boolean { - return isOAndAbove && (PackageUtil.isInstalled( + fun hasAuroraService(context: Context): Boolean = try { + val packageInfo = PackageUtil.getPackageInfo( context, - ShizukuInstaller.SHIZUKU_PACKAGE_NAME - ) || Sui.isSui()) + ServiceInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME + ) + val version = PackageInfoCompat.getLongVersionCode(packageInfo) + + packageInfo.applicationInfo!!.enabled && version >= 9 + } catch (_: Exception) { + false } - fun hasShizukuPerm(): Boolean { - return Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED - } + fun hasAppManager(context: Context): Boolean = + PackageUtil.isInstalled(context, AMInstaller.AM_PACKAGE_NAME) or + PackageUtil.isInstalled(context, AMInstaller.AM_DEBUG_PACKAGE_NAME) + + fun hasShizukuOrSui(context: Context): Boolean = isOAndAbove && + (PackageUtil.isInstalled(context, SHIZUKU_PACKAGE_NAME) || Sui.isSui()) + + fun hasShizukuPerm(): Boolean = + Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED fun uninstall(context: Context, packageName: String) { val intent = Intent().apply { @@ -166,25 +179,33 @@ class AppInstaller @Inject constructor( private val defaultInstaller: IInstaller get() = sessionInstaller - fun getMicroGInstaller(): IInstaller { - return microGInstaller - } + fun getMicroGInstaller(): IInstaller = microGInstaller - fun getPreferredInstaller(): IInstaller { - return when (getCurrentInstaller(context)) { - Installer.SESSION -> sessionInstaller - Installer.NATIVE -> nativeInstaller - Installer.ROOT -> if (hasRootAccess()) rootInstaller else defaultInstaller - Installer.SERVICE -> if (hasAuroraService(context)) serviceInstaller else defaultInstaller - Installer.AM -> if (hasAppManager(context)) amInstaller else defaultInstaller - Installer.SHIZUKU -> { - if (hasShizukuOrSui(context) && hasShizukuPerm()) { - shizukuInstaller - } else { - defaultInstaller - } - } - Installer.MICROG -> if(hasMicroGCompanion(context)) microGInstaller else defaultInstaller + fun getPreferredInstaller(): IInstaller = when (getCurrentInstaller(context)) { + Installer.SESSION -> sessionInstaller + + Installer.NATIVE -> nativeInstaller + + Installer.ROOT -> if (hasRootAccess()) rootInstaller else defaultInstaller + + Installer.SERVICE -> if (hasAuroraService(context)) { + serviceInstaller + } else { + defaultInstaller + } + + Installer.AM -> if (hasAppManager(context)) amInstaller else defaultInstaller + + Installer.SHIZUKU -> if (hasShizukuOrSui(context) && hasShizukuPerm()) { + shizukuInstaller + } else { + defaultInstaller + } + + Installer.MICROG -> if (hasMicroGCompanion(context)) { + microGInstaller + } else { + defaultInstaller } } } diff --git a/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt index dd4371313..e72fcf4cb 100644 --- a/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt @@ -53,13 +53,12 @@ class MicroGInstaller @Inject constructor( description = R.string.microg_installer_desc ) - fun buildMicroGInstallIntent(uris: ArrayList): Intent { - return Intent("org.microg.vending.action.INSTALL_PACKAGE").apply { + fun buildMicroGInstallIntent(uris: ArrayList): Intent = + Intent("org.microg.vending.action.INSTALL_PACKAGE").apply { setPackage(PACKAGE_NAME_PLAY_STORE) setType("application/vnd.android.package-archive") putExtra(Intent.EXTRA_STREAM, uris) } - } } override fun install(download: Download) { diff --git a/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt index 976fc4548..1d4d9484a 100644 --- a/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt @@ -75,7 +75,10 @@ class RootInstaller @Inject constructor( context.getString(R.string.installer_status_failure), context.getString(R.string.installer_root_unavailable) ) - Log.e(TAG, " >>>>>>>>>>>>>>>>>>>>>>>>>> NO ROOT ACCESS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<") + Log.e( + TAG, + " >>>>>>>>>>>>>>>>>>>>>>>>>> NO ROOT ACCESS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<" + ) } } } @@ -83,8 +86,9 @@ class RootInstaller @Inject constructor( private fun xInstall(packageName: String, versionCode: Long, sharedLibPkgName: String = "") { var totalSize = 0 - for (file in getFiles(packageName, versionCode, sharedLibPkgName)) + for (file in getFiles(packageName, versionCode, sharedLibPkgName)) { totalSize += file.length().toInt() + } val result: Shell.Result = Shell.cmd("pm install-create -i $PLAY_PACKAGE_NAME --user 0 -r -S $totalSize") @@ -100,7 +104,9 @@ class RootInstaller @Inject constructor( val sessionId = sessionIdMatcher.group(1)?.toInt() if (Shell.getShell().isRoot && sessionId != null) { for (file in getFiles(packageName, versionCode, sharedLibPkgName)) { - Shell.cmd("cat \"${file.absoluteFile}\" | pm install-write -S ${file.length()} $sessionId \"${file.name}\"") + Shell.cmd( + "cat \"${file.absoluteFile}\" | pm install-write -S ${file.length()} $sessionId \"${file.name}\"" + ) .exec() } @@ -136,7 +142,5 @@ class RootInstaller @Inject constructor( } } - private fun parseError(result: Shell.Result): String { - return result.err.joinToString(separator = "\n") - } + private fun parseError(result: Shell.Result): String = result.err.joinToString(separator = "\n") } diff --git a/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt index 2fe10cee5..f3726d7f4 100644 --- a/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt @@ -216,8 +216,8 @@ class SessionInstaller @Inject constructor( } } - private fun buildSessionParams(packageName: String): SessionParams { - return SessionParams(SessionParams.MODE_FULL_INSTALL).apply { + private fun buildSessionParams(packageName: String): SessionParams = + SessionParams(SessionParams.MODE_FULL_INSTALL).apply { setAppPackageName(packageName) setInstallLocation(PackageInfo.INSTALL_LOCATION_AUTO) if (isNAndAbove) { @@ -238,7 +238,6 @@ class SessionInstaller @Inject constructor( setApplicationEnabledSettingPersistent() } } - } private fun commitInstall(sessionInfo: SessionInfo) { try { diff --git a/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt index 699b6ef3e..db090dc50 100644 --- a/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt @@ -51,10 +51,10 @@ import com.aurora.store.data.room.download.Download import com.aurora.store.util.PackageUtil.isSharedLibraryInstalled import dagger.hilt.android.qualifiers.ApplicationContext import dev.rikka.tools.refine.Refine -import rikka.shizuku.ShizukuBinderWrapper -import rikka.shizuku.SystemServiceHelper import javax.inject.Inject import javax.inject.Singleton +import rikka.shizuku.ShizukuBinderWrapper +import rikka.shizuku.SystemServiceHelper @Singleton @RequiresApi(Build.VERSION_CODES.O) @@ -99,7 +99,9 @@ class ShizukuInstaller @Inject constructor( Refine.unsafeCast( PackageInstallerHidden(iPackageInstaller, PLAY_PACKAGE_NAME, 0) ) - } else null + } else { + null + } } override fun install(download: Download) { diff --git a/app/src/main/java/com/aurora/store/data/installer/base/InstallerBase.kt b/app/src/main/java/com/aurora/store/data/installer/base/InstallerBase.kt index b525c8e86..035523af3 100644 --- a/app/src/main/java/com/aurora/store/data/installer/base/InstallerBase.kt +++ b/app/src/main/java/com/aurora/store/data/installer/base/InstallerBase.kt @@ -43,20 +43,40 @@ abstract class InstallerBase(private val context: Context) : IInstaller { companion object { fun notifyInstallation(context: Context, displayName: String, packageName: String) { val notificationManager = context.getSystemService() - val notification = NotificationUtil.getInstallNotification(context, displayName, packageName) + val notification = NotificationUtil.getInstallNotification( + context, + displayName, + packageName + ) notificationManager!!.notify(packageName.hashCode(), notification) } - fun getErrorString(context: Context, status: Int): String { - return when (status) { - PackageInstaller.STATUS_FAILURE_ABORTED -> context.getString(R.string.installer_status_user_action) - PackageInstaller.STATUS_FAILURE_BLOCKED -> context.getString(R.string.installer_status_failure_blocked) - PackageInstaller.STATUS_FAILURE_CONFLICT -> context.getString(R.string.installer_status_failure_conflict) - PackageInstaller.STATUS_FAILURE_INCOMPATIBLE -> context.getString(R.string.installer_status_failure_incompatible) - PackageInstaller.STATUS_FAILURE_INVALID -> context.getString(R.string.installer_status_failure_invalid) - PackageInstaller.STATUS_FAILURE_STORAGE -> context.getString(R.string.installer_status_failure_storage) - else -> context.getString(R.string.installer_status_failure) - } + fun getErrorString(context: Context, status: Int): String = when (status) { + PackageInstaller.STATUS_FAILURE_ABORTED -> context.getString( + R.string.installer_status_user_action + ) + + PackageInstaller.STATUS_FAILURE_BLOCKED -> context.getString( + R.string.installer_status_failure_blocked + ) + + PackageInstaller.STATUS_FAILURE_CONFLICT -> context.getString( + R.string.installer_status_failure_conflict + ) + + PackageInstaller.STATUS_FAILURE_INCOMPATIBLE -> context.getString( + R.string.installer_status_failure_incompatible + ) + + PackageInstaller.STATUS_FAILURE_INVALID -> context.getString( + R.string.installer_status_failure_invalid + ) + + PackageInstaller.STATUS_FAILURE_STORAGE -> context.getString( + R.string.installer_status_failure_storage + ) + + else -> context.getString(R.string.installer_status_failure) } } @@ -71,9 +91,8 @@ abstract class InstallerBase(private val context: Context) : IInstaller { AuroraApp.enqueuedInstalls.clear() } - override fun isAlreadyQueued(packageName: String): Boolean { - return AuroraApp.enqueuedInstalls.contains(packageName) - } + override fun isAlreadyQueued(packageName: String): Boolean = + AuroraApp.enqueuedInstalls.contains(packageName) override fun removeFromInstallQueue(packageName: String) { AuroraApp.enqueuedInstalls.remove(packageName) @@ -113,11 +132,9 @@ abstract class InstallerBase(private val context: Context) : IInstaller { return downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") } } - fun getUri(file: File): Uri { - return FileProvider.getUriForFile( - context, - "${BuildConfig.APPLICATION_ID}.fileProvider", - file - ) - } + fun getUri(file: File): Uri = FileProvider.getUriForFile( + context, + "${BuildConfig.APPLICATION_ID}.fileProvider", + file + ) } diff --git a/app/src/main/java/com/aurora/store/data/model/Black.kt b/app/src/main/java/com/aurora/store/data/model/Black.kt index d5960eeb5..750e9ab1a 100644 --- a/app/src/main/java/com/aurora/store/data/model/Black.kt +++ b/app/src/main/java/com/aurora/store/data/model/Black.kt @@ -27,14 +27,10 @@ data class Black(val packageName: String) { var versionName: String = String() var versionCode: Long = 0 - override fun hashCode(): Int { - return packageName.hashCode() - } + override fun hashCode(): Int = packageName.hashCode() - override fun equals(other: Any?): Boolean { - return when (other) { - is Black -> other.packageName == packageName - else -> false - } + override fun equals(other: Any?): Boolean = when (other) { + is Black -> other.packageName == packageName + else -> false } } diff --git a/app/src/main/java/com/aurora/store/data/model/Exodus.kt b/app/src/main/java/com/aurora/store/data/model/Exodus.kt index 4f9ca97a3..41e660902 100644 --- a/app/src/main/java/com/aurora/store/data/model/Exodus.kt +++ b/app/src/main/java/com/aurora/store/data/model/Exodus.kt @@ -55,14 +55,10 @@ data class ExodusTracker( val categories: List = emptyList() ) { - override fun hashCode(): Int { - return id - } + override fun hashCode(): Int = id - override fun equals(other: Any?): Boolean { - return when (other) { - is ExodusTracker -> other.id == id - else -> false - } + override fun equals(other: Any?): Boolean = when (other) { + is ExodusTracker -> other.id == id + else -> false } } diff --git a/app/src/main/java/com/aurora/store/data/model/InstallerInfo.kt b/app/src/main/java/com/aurora/store/data/model/InstallerInfo.kt index 0521b7ce2..ebb0a5a10 100644 --- a/app/src/main/java/com/aurora/store/data/model/InstallerInfo.kt +++ b/app/src/main/java/com/aurora/store/data/model/InstallerInfo.kt @@ -33,14 +33,10 @@ data class InstallerInfo( @StringRes val subtitle: Int, @StringRes val description: Int ) { - override fun equals(other: Any?): Boolean { - return when (other) { - is InstallerInfo -> other.id == id - else -> false - } + override fun equals(other: Any?): Boolean = when (other) { + is InstallerInfo -> other.id == id + else -> false } - override fun hashCode(): Int { - return id.hashCode() - } + override fun hashCode(): Int = id.hashCode() } diff --git a/app/src/main/java/com/aurora/store/data/model/Link.kt b/app/src/main/java/com/aurora/store/data/model/Link.kt index b7ad6ed69..184a611ca 100644 --- a/app/src/main/java/com/aurora/store/data/model/Link.kt +++ b/app/src/main/java/com/aurora/store/data/model/Link.kt @@ -24,16 +24,12 @@ data class Link( var title: String, var subtitle: String, var url: String, - var icon: Int, + var icon: Int ) { - override fun equals(other: Any?): Boolean { - return when (other) { - is Link -> other.id == id - else -> false - } + override fun equals(other: Any?): Boolean = when (other) { + is Link -> other.id == id + else -> false } - override fun hashCode(): Int { - return id.hashCode() - } + override fun hashCode(): Int = id.hashCode() } diff --git a/app/src/main/java/com/aurora/store/data/model/MinimalApp.kt b/app/src/main/java/com/aurora/store/data/model/MinimalApp.kt index 1794e701c..41519abef 100644 --- a/app/src/main/java/com/aurora/store/data/model/MinimalApp.kt +++ b/app/src/main/java/com/aurora/store/data/model/MinimalApp.kt @@ -19,23 +19,18 @@ data class MinimalApp( companion object { - fun fromApp(app: App): MinimalApp { - return MinimalApp( - app.packageName, - app.versionName, - app.versionCode, - app.displayName - ) - } - - fun fromUpdate(update: Update): MinimalApp { - return MinimalApp( - update.packageName, - update.versionName, - update.versionCode, - update.displayName - ) - } + fun fromApp(app: App): MinimalApp = MinimalApp( + app.packageName, + app.versionName, + app.versionCode, + app.displayName + ) + fun fromUpdate(update: Update): MinimalApp = MinimalApp( + update.packageName, + update.versionName, + update.versionCode, + update.displayName + ) } } diff --git a/app/src/main/java/com/aurora/store/data/model/PaginatedAppList.kt b/app/src/main/java/com/aurora/store/data/model/PaginatedAppList.kt index 186da0fdc..0f12252a4 100644 --- a/app/src/main/java/com/aurora/store/data/model/PaginatedAppList.kt +++ b/app/src/main/java/com/aurora/store/data/model/PaginatedAppList.kt @@ -5,4 +5,4 @@ import com.aurora.gplayapi.data.models.App data class PaginatedAppList( val appList: MutableList = mutableListOf(), var hasMore: Boolean -) \ No newline at end of file +) diff --git a/app/src/main/java/com/aurora/store/data/model/SelfUpdate.kt b/app/src/main/java/com/aurora/store/data/model/SelfUpdate.kt index 03305bade..37e4a4e2a 100644 --- a/app/src/main/java/com/aurora/store/data/model/SelfUpdate.kt +++ b/app/src/main/java/com/aurora/store/data/model/SelfUpdate.kt @@ -74,7 +74,8 @@ data class SelfUpdate( isFree = true, isInstalled = true, certificateSetList = CertUtil.getEncodedCertificateHashes( - context, context.packageName + context, + context.packageName ).map { EncodedCertificateSet(certificateSet = it, sha256 = String()) }.toMutableList() diff --git a/app/src/main/java/com/aurora/store/data/model/State.kt b/app/src/main/java/com/aurora/store/data/model/State.kt index ba0c68546..6451a5394 100644 --- a/app/src/main/java/com/aurora/store/data/model/State.kt +++ b/app/src/main/java/com/aurora/store/data/model/State.kt @@ -19,11 +19,8 @@ package com.aurora.store.data.model - sealed class ViewState { - inline fun ViewState.getDataAs(): T { - return (this as? Success<*>)?.data as T - } + inline fun ViewState.getDataAs(): T = (this as? Success<*>)?.data as T data object Loading : ViewState() data object Empty : ViewState() @@ -33,7 +30,7 @@ sealed class ViewState { } sealed class AuthState { - data object Init: AuthState() + data object Init : AuthState() data object Available : AuthState() data object Unavailable : AuthState() data object SignedIn : AuthState() @@ -68,18 +65,15 @@ sealed class AppState { /** * Whether there is some sort of ongoing process related to the app */ - fun inProgress(): Boolean { - return this is Downloading || this is Installing || this is Purchasing || this is Queued - } + fun inProgress(): Boolean = + this is Downloading || this is Installing || this is Purchasing || this is Queued /** * Progress of the process related to the app; 0 otherwise */ - fun progress(): Float { - return when (this) { - is Downloading -> progress - is Installing -> progress - else -> 0F - } + fun progress(): Float = when (this) { + is Downloading -> progress + is Installing -> progress + else -> 0F } } diff --git a/app/src/main/java/com/aurora/store/data/model/UpdateMode.kt b/app/src/main/java/com/aurora/store/data/model/UpdateMode.kt index cb6c94741..5e2bdc2e3 100644 --- a/app/src/main/java/com/aurora/store/data/model/UpdateMode.kt +++ b/app/src/main/java/com/aurora/store/data/model/UpdateMode.kt @@ -4,5 +4,5 @@ enum class UpdateMode { DISABLED, CHECK_AND_NOTIFY, CHECK_AND_INSTALL, - CHECK_ONLY, + CHECK_ONLY } diff --git a/app/src/main/java/com/aurora/store/data/network/HttpClient.kt b/app/src/main/java/com/aurora/store/data/network/HttpClient.kt index 5b7646635..b4c8d038a 100644 --- a/app/src/main/java/com/aurora/store/data/network/HttpClient.kt +++ b/app/src/main/java/com/aurora/store/data/network/HttpClient.kt @@ -26,6 +26,9 @@ import com.aurora.gplayapi.network.IHttpClient import com.aurora.store.BuildConfig.APPLICATION_ID import com.aurora.store.BuildConfig.VERSION_CODE import com.aurora.store.BuildConfig.VERSION_NAME +import java.io.IOException +import javax.inject.Inject +import javax.inject.Singleton import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -38,12 +41,9 @@ import okhttp3.Request import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response -import java.io.IOException -import javax.inject.Inject -import javax.inject.Singleton @Singleton -class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient): IHttpClient { +class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient) : IHttpClient { companion object { private const val POST = "POST" @@ -69,7 +69,7 @@ class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient): IH fun call(url: String, headers: Map = emptyMap()): Response { val request = Request( url = url.toHttpUrl(), - headers = headers.toHeaders(), + headers = headers.toHeaders() ) return okHttpClient.newCall(request).execute() } @@ -102,14 +102,12 @@ class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient): IH } @Throws(IOException::class) - override fun post(url: String, headers: Map, body: ByteArray): PlayResponse { - return post(url, headers, body.toRequestBody()) - } + override fun post(url: String, headers: Map, body: ByteArray): PlayResponse = + post(url, headers, body.toRequestBody()) @Throws(IOException::class) - override fun get(url: String, headers: Map): PlayResponse { - return get(url, headers, mapOf()) - } + override fun get(url: String, headers: Map): PlayResponse = + get(url, headers, mapOf()) @Throws(IOException::class) override fun get( @@ -136,11 +134,7 @@ class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient): IH } @Throws(IOException::class) - override fun get( - url: String, - headers: Map, - paramString: String - ): PlayResponse { + override fun get(url: String, headers: Map, paramString: String): PlayResponse { val request = Request( url = "$url$paramString".toHttpUrl(), headers = headers.toHeaders(), @@ -165,16 +159,14 @@ class HttpClient @Inject constructor(private val okHttpClient: OkHttpClient): IH return urlBuilder.build() } - private fun buildPlayResponse(response: Response): PlayResponse { - return PlayResponse( - isSuccessful = response.isSuccessful, - code = response.code, - responseBytes = response.body.bytes(), - errorString = if (!response.isSuccessful) response.message else String() - ).also { - val isCached = if (response.cacheResponse != null) "CACHED" else "NETWORK" - _responseCode.value = response.code - Log.i(TAG, "OKHTTP [$isCached] [${response.code}] ${response.request.url}") - } + private fun buildPlayResponse(response: Response): PlayResponse = PlayResponse( + isSuccessful = response.isSuccessful, + code = response.code, + responseBytes = response.body.bytes(), + errorString = if (!response.isSuccessful) response.message else String() + ).also { + val isCached = if (response.cacheResponse != null) "CACHED" else "NETWORK" + _responseCode.value = response.code + Log.i(TAG, "OKHTTP [$isCached] [${response.code}] ${response.request.url}") } } diff --git a/app/src/main/java/com/aurora/store/data/network/IHttpClientModule.kt b/app/src/main/java/com/aurora/store/data/network/IHttpClientModule.kt index adfafbdf6..c00c75328 100644 --- a/app/src/main/java/com/aurora/store/data/network/IHttpClientModule.kt +++ b/app/src/main/java/com/aurora/store/data/network/IHttpClientModule.kt @@ -13,7 +13,5 @@ object IHttpClientModule { @Provides @Singleton - fun providesIHttpClientInstance(httpClient: HttpClient): IHttpClient { - return httpClient - } + fun providesIHttpClientInstance(httpClient: HttpClient): IHttpClient = httpClient } diff --git a/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt b/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt index 13fa41d99..bab521fa6 100644 --- a/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt +++ b/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt @@ -33,10 +33,6 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import kotlinx.serialization.json.Json -import okhttp3.Cache -import okhttp3.CertificatePinner -import okhttp3.OkHttpClient import java.io.ByteArrayInputStream import java.io.File import java.io.InputStream @@ -49,6 +45,10 @@ import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import java.util.concurrent.TimeUnit import javax.inject.Singleton +import kotlinx.serialization.json.Json +import okhttp3.Cache +import okhttp3.CertificatePinner +import okhttp3.OkHttpClient @Module @InstallIn(SingletonComponent::class) @@ -90,13 +90,13 @@ object OkHttpClientModule { val googleRootCerts = getGoogleRootCertHashes(context).map { "sha256/$it" } .toTypedArray() - return CertificatePinner.Builder() + return CertificatePinner.Builder() .add("*.googleapis.com", *googleRootCerts) .add("*.google.com", *googleRootCerts) - .add("auroraoss.com", "sha256/mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c=") // GTS Root R4 - .add("*.exodus-privacy.eu.org", "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=") // ISRG Root X1 - .add("gitlab.com", "sha256/x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=") // USERTrust RSA Certification Authority - .add("plexus.techlore.tech", "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=") // ISRG Root X1 + .add("auroraoss.com", "sha256/mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c=") + .add("*.exodus-privacy.eu.org", "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=") + .add("gitlab.com", "sha256/x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=") + .add("plexus.techlore.tech", "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=") .build() } @@ -108,7 +108,11 @@ object OkHttpClientModule { val proxyInfo = json.decodeFromString(proxyInfoString) val proxy = Proxy( - if (proxyInfo.protocol.removeSuffix("5") == "SOCKS") Proxy.Type.SOCKS else Proxy.Type.HTTP, + if (proxyInfo.protocol.removeSuffix("5") == "SOCKS") { + Proxy.Type.SOCKS + } else { + Proxy.Type.HTTP + }, InetSocketAddress.createUnresolved(proxyInfo.host, proxyInfo.port) ) @@ -117,9 +121,8 @@ object OkHttpClientModule { if (!proxyUser.isNullOrBlank() && !proxyPassword.isNullOrBlank()) { Authenticator.setDefault(object : Authenticator() { - override fun getPasswordAuthentication(): PasswordAuthentication { - return PasswordAuthentication(proxyUser, proxyPassword.toCharArray()) - } + override fun getPasswordAuthentication(): PasswordAuthentication = + PasswordAuthentication(proxyUser, proxyPassword.toCharArray()) }) } return proxy @@ -131,25 +134,22 @@ object OkHttpClientModule { @Provides @Singleton - fun providesCacheDir(@ApplicationContext context: Context): Cache { - return Cache( - directory = File(context.cacheDir, "http_cache"), - maxSize = 100L * 1024 * 1024 - ) - } + fun providesCacheDir(@ApplicationContext context: Context): Cache = Cache( + directory = File(context.cacheDir, "http_cache"), + maxSize = 100L * 1024 * 1024 + ) - private fun getGoogleRootCertHashes(context: Context): List { - return try { - val certs = getX509Certificates(context.resources.openRawResource(R.raw.google_roots_ca)) - certs.map { - val messageDigest = MessageDigest.getInstance(Algorithm.SHA256.value) - messageDigest.update(it.publicKey.encoded) - Base64.encodeToString(messageDigest.digest(), Base64.NO_WRAP) - } - } catch (exception: Exception) { - Log.e(TAG, "Failed to get SHA256 certificate hash", exception) - emptyList() + private fun getGoogleRootCertHashes(context: Context): List = try { + val certs = + getX509Certificates(context.resources.openRawResource(R.raw.google_roots_ca)) + certs.map { + val messageDigest = MessageDigest.getInstance(Algorithm.SHA256.value) + messageDigest.update(it.publicKey.encoded) + Base64.encodeToString(messageDigest.digest(), Base64.NO_WRAP) } + } catch (exception: Exception) { + Log.e(TAG, "Failed to get SHA256 certificate hash", exception) + emptyList() } private fun getX509Certificates(inputStream: InputStream): List { diff --git a/app/src/main/java/com/aurora/store/data/paging/GenericPagingSource.kt b/app/src/main/java/com/aurora/store/data/paging/GenericPagingSource.kt index b2b0a150d..9b170d274 100644 --- a/app/src/main/java/com/aurora/store/data/paging/GenericPagingSource.kt +++ b/app/src/main/java/com/aurora/store/data/paging/GenericPagingSource.kt @@ -78,10 +78,9 @@ class GenericPagingSource( } } - override fun getRefreshKey(state: PagingState): Int? { - return state.anchorPosition?.let { anchorPosition -> + override fun getRefreshKey(state: PagingState): Int? = + state.anchorPosition?.let { anchorPosition -> state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1) ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1) } - } } diff --git a/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt b/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt index 5fc660e8f..156c4ee9f 100644 --- a/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt @@ -36,9 +36,8 @@ object AccountProvider { } } - fun isLoggedIn(context: Context): Boolean { - return Preferences.getBoolean(context, Constants.ACCOUNT_SIGNED_IN, false) - } + fun isLoggedIn(context: Context): Boolean = + Preferences.getBoolean(context, Constants.ACCOUNT_SIGNED_IN, false) fun getLoginEmail(context: Context): String? { val email = Preferences.getString(context, Constants.ACCOUNT_EMAIL_PLAIN) diff --git a/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt b/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt index a71d356be..e82a5a882 100644 --- a/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/AuthProvider.kt @@ -33,11 +33,11 @@ import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_AUTH_DATA import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json -import javax.inject.Inject -import javax.inject.Singleton @Singleton class AuthProvider @Inject constructor( @@ -70,9 +70,7 @@ class AuthProvider @Inject constructor( /** * Checks whether saved AuthData is valid or not */ - fun isSavedAuthDataValid(): Boolean { - return AuthHelper.isValid(authData!!) - } + fun isSavedAuthDataValid(): Boolean = AuthHelper.isValid(authData!!) /** * Builds [AuthData] for login using personal Google account @@ -94,7 +92,7 @@ class AuthProvider @Inject constructor( token = token, tokenType = tokenType, properties = spoofProvider.deviceProperties, - locale = spoofProvider.locale, + locale = spoofProvider.locale ) ) } catch (exception: Exception) { @@ -154,10 +152,15 @@ class AuthProvider @Inject constructor( private fun throwError(playResponse: PlayResponse, context: Context) { when (playResponse.code) { 400 -> throw Exception(context.getString(R.string.bad_request)) + 403 -> throw Exception(context.getString(R.string.access_denied_using_vpn)) + 404 -> throw Exception(context.getString(R.string.server_unreachable)) + 429 -> throw Exception(context.getString(R.string.login_rate_limited)) + 503 -> throw Exception(context.getString(R.string.server_maintenance)) + else -> { if (playResponse.errorString.isNotBlank()) { throw Exception(playResponse.errorString) diff --git a/app/src/main/java/com/aurora/store/data/providers/BlacklistProvider.kt b/app/src/main/java/com/aurora/store/data/providers/BlacklistProvider.kt index 1b834193c..91b77aa30 100644 --- a/app/src/main/java/com/aurora/store/data/providers/BlacklistProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/BlacklistProvider.kt @@ -24,15 +24,15 @@ import android.content.SharedPreferences import com.aurora.extensions.isNAndAbove import com.aurora.store.util.Preferences import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.serialization.json.Json import java.io.File import javax.inject.Inject import javax.inject.Singleton +import kotlinx.serialization.json.Json @Singleton class BlacklistProvider @Inject constructor( private val json: Json, - @ApplicationContext val context: Context, + @ApplicationContext val context: Context ) { companion object { @@ -67,19 +67,17 @@ class BlacklistProvider @Inject constructor( } else { Preferences.getString(context, PREFERENCE_BLACKLIST) } - if (rawBlacklist!!.isEmpty()) + if (rawBlacklist!!.isEmpty()) { mutableSetOf() - else + } else { json.decodeFromString>(rawBlacklist) + } } catch (e: Exception) { mutableSetOf() } } - fun isBlacklisted(packageName: String): Boolean { - return blacklist.contains(packageName) - } - + fun isBlacklisted(packageName: String): Boolean = blacklist.contains(packageName) fun blacklist(packageName: String) { blacklist = blacklist.apply { diff --git a/app/src/main/java/com/aurora/store/data/providers/EglExtensionProvider.kt b/app/src/main/java/com/aurora/store/data/providers/EglExtensionProvider.kt index ccada95b2..5a92db1b4 100644 --- a/app/src/main/java/com/aurora/store/data/providers/EglExtensionProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/EglExtensionProvider.kt @@ -41,8 +41,10 @@ object EglExtensionProvider { val configs = arrayOfNulls(configCount[0]) if (egl.eglGetConfigs(display, configs, configCount[0], configCount)) { val pbufferAttribs = intArrayOf( - EGL10.EGL_WIDTH, EGL10.EGL_PBUFFER_BIT, - EGL10.EGL_HEIGHT, EGL10.EGL_PBUFFER_BIT, + EGL10.EGL_WIDTH, + EGL10.EGL_PBUFFER_BIT, + EGL10.EGL_HEIGHT, + EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE ) val contextAttributes = intArrayOf(12440, EGL10.EGL_PIXMAP_BIT, EGL10.EGL_NONE) diff --git a/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt b/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt index f1c606315..70220fd1b 100644 --- a/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/NativeDeviceInfoProvider.kt @@ -30,15 +30,16 @@ object NativeDeviceInfoProvider { fun getNativeDeviceProperties(context: Context, isExport: Boolean = false): Properties { val properties = Properties().apply { - //Build Props + // Build Props setProperty("UserReadableName", "${Build.MANUFACTURER} ${Build.MODEL}") setProperty("Build.HARDWARE", Build.HARDWARE) setProperty( "Build.RADIO", - if (Build.getRadioVersion() != null) + if (Build.getRadioVersion() != null) { Build.getRadioVersion() - else + } else { "unknown" + } ) setProperty("Build.FINGERPRINT", Build.FINGERPRINT) setProperty("Build.BRAND", Build.BRAND) @@ -62,21 +63,24 @@ object NativeDeviceInfoProvider { "${config.navigation == Configuration.NAVIGATIONHIDDEN_YES}" ) - //Display Metrics + // Display Metrics val metrics = context.resources.displayMetrics setProperty("Screen.Density", "${metrics.densityDpi}") setProperty("Screen.Width", "${metrics.widthPixels}") setProperty("Screen.Height", "${metrics.heightPixels}") - //Supported Platforms + // Supported Platforms setProperty("Platforms", Build.SUPPORTED_ABIS.joinToString(separator = ",")) - //Supported Features + // Supported Features setProperty("Features", getFeatures(context).joinToString(separator = ",")) - //Shared Locales + // Shared Locales setProperty("Locales", getLocales(context).joinToString(separator = ",")) - //Shared Libraries - setProperty("SharedLibraries", getSharedLibraries(context).joinToString(separator = ",")) - //GL Extensions + // Shared Libraries + setProperty( + "SharedLibraries", + getSharedLibraries(context).joinToString(separator = ",") + ) + // GL Extensions val activityManager = context.getSystemService() setProperty( "GL.Version", @@ -87,7 +91,7 @@ object NativeDeviceInfoProvider { EglExtensionProvider.eglExtensions.joinToString(separator = ",") ) - //Google Related Props + // Google Related Props setProperty("Client", "android-google") val gsfVersionProvider = NativeGsfVersionProvider(context, isExport) @@ -95,11 +99,11 @@ object NativeDeviceInfoProvider { setProperty("Vending.version", gsfVersionProvider.vendingVersionCode.toString()) setProperty("Vending.versionString", gsfVersionProvider.vendingVersionString) - //MISC + // MISC setProperty("Roaming", "mobile-notroaming") setProperty("TimeZone", "UTC-10") - //Telephony (USA 3650 AT&T) + // Telephony (USA 3650 AT&T) setProperty("CellOperator", "310") setProperty("SimOperator", "38") } @@ -108,29 +112,23 @@ object NativeDeviceInfoProvider { return properties } - private fun getFeatures(context: Context): List { - return context - .packageManager - .systemAvailableFeatures - .mapNotNull { it.name } - } + private fun getFeatures(context: Context): List = context + .packageManager + .systemAvailableFeatures + .mapNotNull { it.name } - private fun getLocales(context: Context): List { - return context - .assets - .locales - .mapNotNull { it.replace("-", "_") } - } + private fun getLocales(context: Context): List = context + .assets + .locales + .mapNotNull { it.replace("-", "_") } - private fun getSharedLibraries(context: Context): List { - return context - .packageManager - .systemSharedLibraryNames - ?.toList() ?: emptyList() - } + private fun getSharedLibraries(context: Context): List = context + .packageManager + .systemSharedLibraryNames + ?.toList() ?: emptyList() private fun stripHuaweiProperties(properties: Properties): Properties { - //Add Pixel 7a properties + // Add Pixel 7a properties properties["Build.HARDWARE"] = "lynx" properties["Build.BOOTLOADER"] = "lynx-1.0-9716681" properties["Build.BRAND"] = "google" diff --git a/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt b/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt index c6efc13ba..c3b29961e 100644 --- a/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt @@ -27,12 +27,12 @@ import androidx.core.content.getSystemService import com.aurora.extensions.isNAndAbove import com.aurora.store.data.model.NetworkStatus import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject +import javax.inject.Singleton import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.distinctUntilChanged -import javax.inject.Inject -import javax.inject.Singleton /** * A simple provider with a flow to observe internet connectivity changes diff --git a/app/src/main/java/com/aurora/store/data/providers/PermissionProvider.kt b/app/src/main/java/com/aurora/store/data/providers/PermissionProvider.kt index 8d3c920b7..9226be283 100644 --- a/app/src/main/java/com/aurora/store/data/providers/PermissionProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/PermissionProvider.kt @@ -54,8 +54,8 @@ class PermissionProvider(private val fragment: Fragment) : /** * Checks whether a known permission has been granted */ - fun isGranted(context: Context, permissionType: PermissionType): Boolean { - return when (permissionType) { + fun isGranted(context: Context, permissionType: PermissionType): Boolean = + when (permissionType) { PermissionType.EXTERNAL_STORAGE, PermissionType.STORAGE_MANAGER -> { context.isExternalStorageAccessible() @@ -76,9 +76,8 @@ class PermissionProvider(private val fragment: Fragment) : PermissionType.DOZE_WHITELIST -> context.isIgnoringBatteryOptimizations() PermissionType.APP_LINKS -> context.isDomainVerified("play.google.com") && - context.isDomainVerified("market.android.com") + context.isDomainVerified("market.android.com") } - } /** * Returns all known permissions that can be requested by Aurora Store @@ -132,7 +131,9 @@ class PermissionProvider(private val fragment: Fragment) : Permission( type = PermissionType.POST_NOTIFICATIONS, title = context.getString(R.string.onboarding_permission_notifications), - subtitle = context.getString(R.string.onboarding_permission_notifications_desc), + subtitle = context.getString( + R.string.onboarding_permission_notifications_desc + ), optional = true, isGranted = isGranted(context, PermissionType.POST_NOTIFICATIONS) ) @@ -147,7 +148,7 @@ class PermissionProvider(private val fragment: Fragment) : subtitle = context.getString(R.string.app_links_desc), optional = true, isGranted = isGranted(context, PermissionType.APP_LINKS) - ), + ) ) } @@ -195,7 +196,7 @@ class PermissionProvider(private val fragment: Fragment) : if (!isGranted(context, PermissionType.INSTALL_UNKNOWN_APPS)) { context.toast(R.string.toast_permission_installer_required) } else { - /** + /* * I don't know why, but for storage manager permission on Android 11 & 12, * we need to request both permissions otherwise the permission is not granted, * even though OS says it is granted. @@ -231,18 +232,16 @@ class PermissionProvider(private val fragment: Fragment) : } @SuppressLint("InlinedApi") - private fun knownPermissions(): Map { - return mapOf( - PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(context), - PermissionType.INSTALL_UNKNOWN_APPS to PackageUtil.getInstallUnknownAppsIntent(), - PermissionType.DOZE_WHITELIST to Intent( - Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, - "package:${BuildConfig.APPLICATION_ID}".toUri() - ), - PermissionType.APP_LINKS to Intent( - ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, - "package:${BuildConfig.APPLICATION_ID}".toUri() - ) + private fun knownPermissions(): Map = mapOf( + PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(context), + PermissionType.INSTALL_UNKNOWN_APPS to PackageUtil.getInstallUnknownAppsIntent(), + PermissionType.DOZE_WHITELIST to Intent( + Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + "package:${BuildConfig.APPLICATION_ID}".toUri() + ), + PermissionType.APP_LINKS to Intent( + ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, + "package:${BuildConfig.APPLICATION_ID}".toUri() ) - } + ) } diff --git a/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt b/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt index 008cd8319..17fc4c3cd 100644 --- a/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/SpoofDeviceProvider.kt @@ -137,12 +137,9 @@ open class SpoofDeviceProvider(private val context: Context) { return File(sourceDir) } } catch (ignored: Exception) { - } return null } - private fun filenameValid(filename: String): Boolean { - return filename.endsWith(SUFFIX) - } + private fun filenameValid(filename: String): Boolean = filename.endsWith(SUFFIX) } diff --git a/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt b/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt index 72fb11a4a..510b303eb 100644 --- a/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/SpoofProvider.kt @@ -24,11 +24,11 @@ import com.aurora.store.R import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_VENDING_VERSION import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.serialization.json.Json import java.util.Locale import java.util.Properties import javax.inject.Inject import javax.inject.Singleton +import kotlinx.serialization.json.Json /** * Provider class to work with device and locale spoofs @@ -36,7 +36,7 @@ import javax.inject.Singleton @Singleton class SpoofProvider @Inject constructor( private val json: Json, - @ApplicationContext val context: Context, + @ApplicationContext val context: Context ) : SpoofDeviceProvider(context) { companion object { @@ -119,7 +119,10 @@ class SpoofProvider @Inject constructor( val versionStrings = resources.getStringArray(R.array.pref_vending_version) currentProperties.setProperty("Vending.version", versionCodes[vendingVersionIndex]) - currentProperties.setProperty("Vending.versionString", versionStrings[vendingVersionIndex]) + currentProperties.setProperty( + "Vending.versionString", + versionStrings[vendingVersionIndex] + ) } } } diff --git a/app/src/main/java/com/aurora/store/data/receiver/DownloadCancelReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/DownloadCancelReceiver.kt index e9f4aefb5..8534f669e 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/DownloadCancelReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/DownloadCancelReceiver.kt @@ -13,9 +13,9 @@ import com.aurora.extensions.TAG import com.aurora.store.AuroraApp import com.aurora.store.data.helper.DownloadHelper import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import javax.inject.Inject @AndroidEntryPoint class DownloadCancelReceiver : BroadcastReceiver() { diff --git a/app/src/main/java/com/aurora/store/data/receiver/MigrationReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/MigrationReceiver.kt index 2e24d09c7..20b4d21c1 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/MigrationReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/MigrationReceiver.kt @@ -64,7 +64,7 @@ class MigrationReceiver : BroadcastReceiver() { if (CertUtil.isAppGalleryApp(context, context.packageName)) { val dispensers = Preferences.getStringSet(context, PREFERENCE_DISPENSER_URLS) .toMutableSet() - + dispensers.remove(Constants.URL_DISPENSER) context.save(PREFERENCE_DISPENSER_URLS, dispensers) @@ -75,7 +75,8 @@ class MigrationReceiver : BroadcastReceiver() { // 63 -> 64 if (currentVersion == 2) { if (isOAndAbove) { - with(context.getSystemService()!!) { // !1189 + with(context.getSystemService()!!) { + // !1189 deleteNotificationChannel("NOTIFICATION_CHANNEL_GENERAL") deleteNotificationChannel("NOTIFICATION_CHANNEL_ALERT") } @@ -87,10 +88,11 @@ class MigrationReceiver : BroadcastReceiver() { if (currentVersion == 3) { val updateMode = UpdateMode.entries[ Preferences.getInteger( - context, - PREFERENCE_UPDATES_AUTO, - UpdateMode.DISABLED.ordinal - )] + context, + PREFERENCE_UPDATES_AUTO, + UpdateMode.DISABLED.ordinal + ) + ] if (updateMode != UpdateMode.DISABLED) { runCatching { diff --git a/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt index 0d134dbe7..dbc1f27cb 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt @@ -48,7 +48,7 @@ open class PackageManagerReceiver : BroadcastReceiver() { } } - //Clear installation queue + // Clear installation queue appInstaller.getPreferredInstaller().removeFromInstallQueue(packageName) } } diff --git a/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt index 9f4cebbd6..4c271564c 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/UnarchivePackageReceiver.kt @@ -15,15 +15,15 @@ import com.aurora.store.data.helper.DownloadHelper import com.aurora.store.data.providers.AccountProvider import com.aurora.store.util.NotificationUtil import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import javax.inject.Inject /** * Triggers re-install/unarchive of a previously archived app on Android 15+ devices. */ @AndroidEntryPoint -class UnarchivePackageReceiver: BroadcastReceiver() { +class UnarchivePackageReceiver : BroadcastReceiver() { @Inject lateinit var appDetailsHelper: AppDetailsHelper diff --git a/app/src/main/java/com/aurora/store/data/room/MigrationHelper.kt b/app/src/main/java/com/aurora/store/data/room/MigrationHelper.kt index 57725012e..fa2b05c90 100644 --- a/app/src/main/java/com/aurora/store/data/room/MigrationHelper.kt +++ b/app/src/main/java/com/aurora/store/data/room/MigrationHelper.kt @@ -35,7 +35,9 @@ object MigrationHelper { private fun migrateFrom1To2(database: SupportSQLiteDatabase) { database.beginTransaction() try { - database.execSQL("CREATE TABLE `favourite` (`packageName` TEXT NOT NULL, `displayName` TEXT NOT NULL, `iconURL` TEXT NOT NULL, `added` INTEGER NOT NULL, `mode` TEXT NOT NULL, PRIMARY KEY(`packageName`))") + database.execSQL( + "CREATE TABLE `favourite` (`packageName` TEXT NOT NULL, `displayName` TEXT NOT NULL, `iconURL` TEXT NOT NULL, `added` INTEGER NOT NULL, `mode` TEXT NOT NULL, PRIMARY KEY(`packageName`))" + ) database.setTransactionSuccessful() } catch (exception: Exception) { Log.e(TAG, "Failed while migrating from database version 1 to 2", exception) @@ -47,7 +49,9 @@ object MigrationHelper { private fun migrateFrom2To3(database: SupportSQLiteDatabase) { database.beginTransaction() try { - database.execSQL("CREATE TABLE `update` (`packageName` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `versionName` TEXT NOT NULL, `displayName` TEXT NOT NULL, `iconURL` TEXT NOT NULL, `changelog` TEXT NOT NULL, `id` INTEGER NOT NULL, `developerName` TEXT NOT NULL, `size` INTEGER NOT NULL, `updatedOn` TEXT NOT NULL, `hasValidCert` INTEGER NOT NULL, `offerType` INTEGER NOT NULL, `fileList` TEXT NOT NULL, `sharedLibs` TEXT NOT NULL, PRIMARY KEY(`packageName`))") + database.execSQL( + "CREATE TABLE `update` (`packageName` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `versionName` TEXT NOT NULL, `displayName` TEXT NOT NULL, `iconURL` TEXT NOT NULL, `changelog` TEXT NOT NULL, `id` INTEGER NOT NULL, `developerName` TEXT NOT NULL, `size` INTEGER NOT NULL, `updatedOn` TEXT NOT NULL, `hasValidCert` INTEGER NOT NULL, `offerType` INTEGER NOT NULL, `fileList` TEXT NOT NULL, `sharedLibs` TEXT NOT NULL, PRIMARY KEY(`packageName`))" + ) database.setTransactionSuccessful() } catch (exception: Exception) { Log.e(TAG, "Failed while migrating from database version 2 to 3", exception) @@ -63,7 +67,9 @@ object MigrationHelper { database.beginTransaction() try { listOf("download", "update").forEach { - database.execSQL("ALTER TABLE `$it` ADD COLUMN targetSdk INTEGER NOT NULL DEFAULT 1") + database.execSQL( + "ALTER TABLE `$it` ADD COLUMN targetSdk INTEGER NOT NULL DEFAULT 1" + ) } database.setTransactionSuccessful() } catch (exception: Exception) { @@ -79,7 +85,9 @@ object MigrationHelper { private fun migrateFrom4To5(database: SupportSQLiteDatabase) { database.beginTransaction() try { - database.execSQL("ALTER TABLE `download` ADD COLUMN downloadedAt INTEGER NOT NULL DEFAULT 0") + database.execSQL( + "ALTER TABLE `download` ADD COLUMN downloadedAt INTEGER NOT NULL DEFAULT 0" + ) database.setTransactionSuccessful() } catch (exception: Exception) { Log.e(TAG, "Failed while migrating from database version 4 to 5", exception) diff --git a/app/src/main/java/com/aurora/store/data/room/RoomModule.kt b/app/src/main/java/com/aurora/store/data/room/RoomModule.kt index 652cdddd0..05ecb723e 100644 --- a/app/src/main/java/com/aurora/store/data/room/RoomModule.kt +++ b/app/src/main/java/com/aurora/store/data/room/RoomModule.kt @@ -29,25 +29,25 @@ object RoomModule { fun providesRoomInstance( @ApplicationContext context: Context, downloadConverter: DownloadConverter - ): AuroraDatabase { - return Room.databaseBuilder(context, AuroraDatabase::class.java, DATABASE) - .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6) - .addTypeConverter(downloadConverter) - .build() - } + ): AuroraDatabase = Room.databaseBuilder(context, AuroraDatabase::class.java, DATABASE) + .addMigrations( + MIGRATION_1_2, + MIGRATION_2_3, + MIGRATION_3_4, + MIGRATION_4_5, + MIGRATION_5_6 + ) + .addTypeConverter(downloadConverter) + .build() @Provides - fun providesDownloadDao(auroraDatabase: AuroraDatabase): DownloadDao { - return auroraDatabase.downloadDao() - } + fun providesDownloadDao(auroraDatabase: AuroraDatabase): DownloadDao = + auroraDatabase.downloadDao() @Provides - fun providesFavouriteDao(auroraDatabase: AuroraDatabase): FavouriteDao { - return auroraDatabase.favouriteDao() - } + fun providesFavouriteDao(auroraDatabase: AuroraDatabase): FavouriteDao = + auroraDatabase.favouriteDao() @Provides - fun providesUpdateDao(auroraDatabase: AuroraDatabase): UpdateDao { - return auroraDatabase.updateDao() - } + fun providesUpdateDao(auroraDatabase: AuroraDatabase): UpdateDao = auroraDatabase.updateDao() } diff --git a/app/src/main/java/com/aurora/store/data/room/download/Download.kt b/app/src/main/java/com/aurora/store/data/room/download/Download.kt index 7f40ade9d..5a2ef3f40 100644 --- a/app/src/main/java/com/aurora/store/data/room/download/Download.kt +++ b/app/src/main/java/com/aurora/store/data/room/download/Download.kt @@ -12,8 +12,8 @@ import com.aurora.store.data.model.DownloadStatus import com.aurora.store.data.room.suite.ExternalApk import com.aurora.store.data.room.update.Update import com.aurora.store.util.PathUtil -import kotlinx.parcelize.Parcelize import java.util.Date +import kotlinx.parcelize.Parcelize @Parcelize @Entity(tableName = "download") @@ -44,73 +44,67 @@ data class Download( private val isSuccessful get() = status == DownloadStatus.COMPLETED companion object { - fun fromApp(app: App): Download { - return Download( - app.packageName, - app.versionCode, - app.offerType, - app.isInstalled, - app.displayName, - app.iconArtwork.url, - app.size, - app.id, - DownloadStatus.QUEUED, - 0, - 0L, - 0L, - 0, - 0, - app.fileList.filterNot { it.url.isBlank() }, - app.dependencies.dependentLibraries.map { SharedLib.fromApp(it) }, - app.targetSdk, - Date().time, - app.requiresGMS() - ) - } + fun fromApp(app: App): Download = Download( + app.packageName, + app.versionCode, + app.offerType, + app.isInstalled, + app.displayName, + app.iconArtwork.url, + app.size, + app.id, + DownloadStatus.QUEUED, + 0, + 0L, + 0L, + 0, + 0, + app.fileList.filterNot { it.url.isBlank() }, + app.dependencies.dependentLibraries.map { SharedLib.fromApp(it) }, + app.targetSdk, + Date().time, + app.requiresGMS() + ) - fun fromUpdate(update: Update): Download { - return Download( - update.packageName, - update.versionCode, - update.offerType, - true, - update.displayName, - update.iconURL, - update.size, - update.id, - DownloadStatus.QUEUED, - 0, - 0L, - 0L, - 0, - 0, - update.fileList, - update.sharedLibs, - update.targetSdk, - Date().time - ) - } + fun fromUpdate(update: Update): Download = Download( + update.packageName, + update.versionCode, + update.offerType, + true, + update.displayName, + update.iconURL, + update.size, + update.id, + DownloadStatus.QUEUED, + 0, + 0L, + 0L, + 0, + 0, + update.fileList, + update.sharedLibs, + update.targetSdk, + Date().time + ) - fun fromExternalApk(externalApk: ExternalApk): Download { - return Download( - packageName = externalApk.packageName, - versionCode = externalApk.versionCode, - offerType = 0, - isInstalled = false, - displayName = externalApk.displayName, - iconURL = externalApk.iconURL, - size = 0, - id = 0, - status = DownloadStatus.QUEUED, - progress = 0, - speed = 0L, - timeRemaining = 0L, - totalFiles = 1, - downloadedFiles = 0, - fileList = externalApk.fileList, - sharedLibs = emptyList(), - ) - } + fun fromExternalApk(externalApk: ExternalApk): Download = Download( + packageName = externalApk.packageName, + versionCode = externalApk.versionCode, + offerType = 0, + isInstalled = false, + displayName = externalApk.displayName, + iconURL = externalApk.iconURL, + size = 0, + id = 0, + status = DownloadStatus.QUEUED, + progress = 0, + speed = 0L, + timeRemaining = 0L, + totalFiles = 1, + downloadedFiles = 0, + fileList = externalApk.fileList, + sharedLibs = emptyList() + ) } fun canInstall(context: Context): Boolean { diff --git a/app/src/main/java/com/aurora/store/data/room/download/DownloadConverter.kt b/app/src/main/java/com/aurora/store/data/room/download/DownloadConverter.kt index 339b6206d..144dc0bab 100644 --- a/app/src/main/java/com/aurora/store/data/room/download/DownloadConverter.kt +++ b/app/src/main/java/com/aurora/store/data/room/download/DownloadConverter.kt @@ -3,31 +3,25 @@ package com.aurora.store.data.room.download import androidx.room.ProvidedTypeConverter import androidx.room.TypeConverter import com.aurora.gplayapi.data.models.PlayFile -import kotlinx.serialization.json.Json import javax.inject.Inject import javax.inject.Singleton +import kotlinx.serialization.json.Json @Singleton @ProvidedTypeConverter class DownloadConverter @Inject constructor(private val json: Json) { @TypeConverter - fun toSharedLibList(string: String): List { - return json.decodeFromString>(string) - } + fun toSharedLibList(string: String): List = + json.decodeFromString>(string) @TypeConverter - fun fromSharedLibList(list: List): String { - return json.encodeToString(list) - } + fun fromSharedLibList(list: List): String = json.encodeToString(list) @TypeConverter - fun toGPlayFileList(string: String): List { - return json.decodeFromString>(string) - } + fun toGPlayFileList(string: String): List = + json.decodeFromString>(string) @TypeConverter - fun fromGPlayFileList(list: List): String { - return json.encodeToString(list) - } + fun fromGPlayFileList(list: List): String = json.encodeToString(list) } diff --git a/app/src/main/java/com/aurora/store/data/room/download/DownloadDao.kt b/app/src/main/java/com/aurora/store/data/room/download/DownloadDao.kt index f69712023..c65ac3553 100644 --- a/app/src/main/java/com/aurora/store/data/room/download/DownloadDao.kt +++ b/app/src/main/java/com/aurora/store/data/room/download/DownloadDao.kt @@ -31,12 +31,7 @@ interface DownloadDao { WHERE packageName=:packageName """ ) - suspend fun updateProgress( - packageName: String, - progress: Int, - speed: Long, - timeRemaining: Long - ) + suspend fun updateProgress(packageName: String, progress: Int, speed: Long, timeRemaining: Long) @Query("SELECT * FROM download") fun downloads(): Flow> diff --git a/app/src/main/java/com/aurora/store/data/room/download/SharedLib.kt b/app/src/main/java/com/aurora/store/data/room/download/SharedLib.kt index 9ccba497e..37174e2fe 100644 --- a/app/src/main/java/com/aurora/store/data/room/download/SharedLib.kt +++ b/app/src/main/java/com/aurora/store/data/room/download/SharedLib.kt @@ -14,12 +14,10 @@ data class SharedLib( var fileList: List ) : Parcelable { companion object { - fun fromApp(app: App): SharedLib { - return SharedLib( - app.packageName, - app.versionCode, - app.fileList.filterNot { it.url.isBlank() } - ) - } + fun fromApp(app: App): SharedLib = SharedLib( + app.packageName, + app.versionCode, + app.fileList.filterNot { it.url.isBlank() } + ) } } diff --git a/app/src/main/java/com/aurora/store/data/room/favourite/Favourite.kt b/app/src/main/java/com/aurora/store/data/room/favourite/Favourite.kt index 69cbaa138..c854ee930 100644 --- a/app/src/main/java/com/aurora/store/data/room/favourite/Favourite.kt +++ b/app/src/main/java/com/aurora/store/data/room/favourite/Favourite.kt @@ -21,23 +21,19 @@ data class Favourite( ) : Parcelable { companion object { - fun fromApp(app: App, mode: Mode): Favourite { - return Favourite( - packageName = app.packageName, - displayName = app.displayName, - iconURL = app.iconArtwork.url, - added = System.currentTimeMillis(), - mode = mode - ) - } + fun fromApp(app: App, mode: Mode): Favourite = Favourite( + packageName = app.packageName, + displayName = app.displayName, + iconURL = app.iconArtwork.url, + added = System.currentTimeMillis(), + mode = mode + ) - fun Favourite.toApp(): App { - return App( - packageName = packageName, - displayName = displayName, - iconArtwork = Artwork(url = iconURL) - ) - } + fun Favourite.toApp(): App = App( + packageName = packageName, + displayName = displayName, + iconArtwork = Artwork(url = iconURL) + ) } enum class Mode { diff --git a/app/src/main/java/com/aurora/store/data/room/favourite/ImportExport.kt b/app/src/main/java/com/aurora/store/data/room/favourite/ImportExport.kt index 8311cc13f..8c41cfaba 100644 --- a/app/src/main/java/com/aurora/store/data/room/favourite/ImportExport.kt +++ b/app/src/main/java/com/aurora/store/data/room/favourite/ImportExport.kt @@ -6,5 +6,5 @@ import kotlinx.serialization.Serializable @Serializable data class ImportExport( val favourites: List, - val auroraStoreVersion: Int = BuildConfig.VERSION_CODE, + val auroraStoreVersion: Int = BuildConfig.VERSION_CODE ) diff --git a/app/src/main/java/com/aurora/store/data/room/suite/ExternalApk.kt b/app/src/main/java/com/aurora/store/data/room/suite/ExternalApk.kt index cda9af7c5..b72cfb177 100644 --- a/app/src/main/java/com/aurora/store/data/room/suite/ExternalApk.kt +++ b/app/src/main/java/com/aurora/store/data/room/suite/ExternalApk.kt @@ -21,7 +21,5 @@ data class ExternalApk( var fileList: List ) : Parcelable { - fun isInstalled(context: Context): Boolean { - return PackageUtil.isInstalled(context, packageName) - } -} \ No newline at end of file + fun isInstalled(context: Context): Boolean = PackageUtil.isInstalled(context, packageName) +} diff --git a/app/src/main/java/com/aurora/store/data/room/update/Update.kt b/app/src/main/java/com/aurora/store/data/room/update/Update.kt index 1dfb216e0..bec3e8e76 100644 --- a/app/src/main/java/com/aurora/store/data/room/update/Update.kt +++ b/app/src/main/java/com/aurora/store/data/room/update/Update.kt @@ -33,40 +33,34 @@ data class Update( ) : Parcelable { companion object { - fun fromApp(context: Context, app: App): Update { - return Update( - app.packageName, - app.versionCode, - app.versionName, - app.displayName, - app.iconArtwork.url, - app.changes, - app.id, - app.developerName, - app.size, - app.updatedOn, - app.certificateSetList.any { - it.certificateSet in CertUtil.getEncodedCertificateHashes( - context, app.packageName - ) - }, - app.offerType, - app.fileList.filterNot { it.url.isBlank() }, - app.dependencies.dependentLibraries.map { SharedLib.fromApp(it) }, - app.targetSdk - ) - } + fun fromApp(context: Context, app: App): Update = Update( + app.packageName, + app.versionCode, + app.versionName, + app.displayName, + app.iconArtwork.url, + app.changes, + app.id, + app.developerName, + app.size, + app.updatedOn, + app.certificateSetList.any { + it.certificateSet in CertUtil.getEncodedCertificateHashes( + context, + app.packageName + ) + }, + app.offerType, + app.fileList.filterNot { it.url.isBlank() }, + app.dependencies.dependentLibraries.map { SharedLib.fromApp(it) }, + app.targetSdk + ) } - fun isSelfUpdate(context: Context): Boolean { - return packageName == context.packageName - } + fun isSelfUpdate(context: Context): Boolean = packageName == context.packageName - fun isInstalled(context: Context): Boolean { - return PackageUtil.isInstalled(context, packageName) - } + fun isInstalled(context: Context): Boolean = PackageUtil.isInstalled(context, packageName) - fun isUpToDate(context: Context): Boolean { - return PackageUtil.isInstalled(context, packageName, versionCode) - } + fun isUpToDate(context: Context): Boolean = + PackageUtil.isInstalled(context, packageName, versionCode) } diff --git a/app/src/main/java/com/aurora/store/data/work/AuthWorker.kt b/app/src/main/java/com/aurora/store/data/work/AuthWorker.kt index b630423b0..21a302297 100644 --- a/app/src/main/java/com/aurora/store/data/work/AuthWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/AuthWorker.kt @@ -100,8 +100,8 @@ open class AuthWorker @AssistedInject constructor( } } - private suspend fun fetchAuthToken(email: String, oldToken: String? = null): String { - return suspendCoroutine { continuation -> + private suspend fun fetchAuthToken(email: String, oldToken: String? = null): String = + suspendCoroutine { continuation -> fetchAuthToken(email, oldToken) { future -> try { val bundle = future.result @@ -110,14 +110,15 @@ open class AuthWorker @AssistedInject constructor( if (token != null) { continuation.resume(token) } else { - continuation.resumeWithException(IllegalStateException("Auth token is null")) + continuation.resumeWithException( + IllegalStateException("Auth token is null") + ) } } catch (e: Exception) { continuation.resumeWithException(e) } } } - } private fun fetchAuthToken( email: String, @@ -155,8 +156,8 @@ open class AuthWorker @AssistedInject constructor( } } - private fun verifyAndSaveAuth(authData: AuthData, accountType: AccountType): AuthData? { - return if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) { + private fun verifyAndSaveAuth(authData: AuthData, accountType: AccountType): AuthData? = + if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) { authProvider.saveAuthData(authData) AccountProvider.login( context, @@ -171,5 +172,4 @@ open class AuthWorker @AssistedInject constructor( AccountProvider.logout(context) null } - } } diff --git a/app/src/main/java/com/aurora/store/data/work/CacheWorker.kt b/app/src/main/java/com/aurora/store/data/work/CacheWorker.kt index 45af60afb..076f0db54 100644 --- a/app/src/main/java/com/aurora/store/data/work/CacheWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/CacheWorker.kt @@ -58,19 +58,23 @@ class CacheWorker @AssistedInject constructor( override suspend fun doWork(): Result { Log.i(TAG, "Cleaning cache") - PathUtil.getOldDownloadDirectories(context).filter { it.exists() }.forEach { dir -> // Downloads + PathUtil.getOldDownloadDirectories(context).filter { it.exists() }.forEach { dir -> + // Downloads Log.i(TAG, "Deleting old unused download directory: $dir") dir.deleteRecursively() } - PathUtil.getDownloadDirectory(context).listFiles()?.forEach { download -> // com.example.app + PathUtil.getDownloadDirectory(context).listFiles()?.forEach { download -> + // com.example.app // Delete if the download directory is empty if (download.listFiles().isNullOrEmpty()) { Log.i(TAG, "Removing empty download directory for ${download.name}") - download.deleteRecursively(); return@forEach + download.deleteRecursively() + return@forEach } - download.listFiles()!!.forEach { versionCode -> // 20240325 + download.listFiles()!!.forEach { versionCode -> + // 20240325 if (versionCode.listFiles().isNullOrEmpty()) { // Purge empty non-accessible directory Log.i(TAG, "Removing empty directory for ${download.name}, ${versionCode.name}") diff --git a/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt b/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt index 5562c887c..3f0b40f70 100644 --- a/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt @@ -48,9 +48,6 @@ import com.aurora.store.util.PackageUtil import com.aurora.store.util.PathUtil import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.withContext import java.io.File import java.io.FileOutputStream import java.net.SocketException @@ -60,6 +57,9 @@ import java.security.DigestInputStream import java.security.MessageDigest import kotlin.coroutines.cancellation.CancellationException import kotlin.properties.Delegates +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.withContext /** * An expedited long-running worker to download and trigger installation for given apps. @@ -206,10 +206,13 @@ class DownloadWorker @AssistedInject constructor( private suspend fun onSuccess(): Result { return withContext(NonCancellable) { return@withContext try { - if (BuildConfig.FLAVOR == FLAVOUR_HUAWEI && download.requiresGMS && PackageUtil.hasMicroGCompanion(context)) + if (BuildConfig.FLAVOR == FLAVOUR_HUAWEI && download.requiresGMS && + PackageUtil.hasMicroGCompanion(context) + ) { appInstaller.getMicroGInstaller().install(download) - else + } else { appInstaller.getPreferredInstaller().install(download) + } Result.success() } catch (exception: Exception) { Log.e(TAG, "Failed to install ${download.packageName}", exception) @@ -425,7 +428,10 @@ class DownloadWorker @AssistedInject constructor( } val notification = NotificationUtil.getDownloadNotification( - context, download, icon, exception?.message + context, + download, + icon, + exception?.message ) notificationManager.notify( if (isProgress) NOTIFICATION_ID else download.packageName.hashCode(), @@ -453,7 +459,10 @@ class DownloadWorker @AssistedInject constructor( file.inputStream().use { fis -> DigestInputStream(fis, messageDigest).use { dis -> val buffer = ByteArray(DEFAULT_BUFFER_SIZE) - while (dis.read(buffer) != -1) { /* Just read, digest updates automatically */ + while (dis.read(buffer) != + -1 + ) { + /* Just read, digest updates automatically */ } } } diff --git a/app/src/main/java/com/aurora/store/data/work/ExportWorker.kt b/app/src/main/java/com/aurora/store/data/work/ExportWorker.kt index d4a0706c0..935beea30 100644 --- a/app/src/main/java/com/aurora/store/data/work/ExportWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/ExportWorker.kt @@ -104,6 +104,7 @@ class ExportWorker @AssistedInject constructor( notificationManager = context.getSystemService()!! + @Suppress("ktlint:standard:mixed-condition-operators") if (packageName.isNullOrEmpty() || isDownload && versionCode == -1L) { Log.e(TAG, "Input data is corrupt, bailing out!") notifyStatus(displayName ?: String(), uri, false) @@ -126,12 +127,10 @@ class ExportWorker @AssistedInject constructor( return Result.success() } - override suspend fun getForegroundInfo(): ForegroundInfo { - return ForegroundInfo( - NOTIFICATION_ID_FGS, - NotificationUtil.getExportNotification(context) - ) - } + override suspend fun getForegroundInfo(): ForegroundInfo = ForegroundInfo( + NOTIFICATION_ID_FGS, + NotificationUtil.getExportNotification(context) + ) private fun notifyStatus(packageName: String, uri: Uri, success: Boolean = true) { notificationManager.notify( @@ -157,12 +156,10 @@ class ExportWorker @AssistedInject constructor( bundleAllAPKs(fileList.filterNotNull(), uri) } - private fun copyDownloadedApp(packageName: String, versionCode: Long, uri: Uri) { - return bundleAllAPKs( - PathUtil.getAppDownloadDir(context, packageName, versionCode).listFiles()!!.toList(), - uri - ) - } + private fun copyDownloadedApp(packageName: String, versionCode: Long, uri: Uri) = bundleAllAPKs( + PathUtil.getAppDownloadDir(context, packageName, versionCode).listFiles()!!.toList(), + uri + ) /** * Bundles all the given APKs to a zip file diff --git a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt index bcf1b297e..ff92e1166 100644 --- a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt @@ -32,10 +32,10 @@ import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO import dagger.assisted.Assisted import dagger.assisted.AssistedInject +import java.util.Locale import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json -import java.util.Locale /** * A worker to check for updates for installed apps based on saved authentication data, @@ -61,8 +61,8 @@ class UpdateWorker @AssistedInject constructor( private val notificationID = 100 private val canSelfUpdate = !CertUtil.isFDroidApp(context, BuildConfig.APPLICATION_ID) && - !CertUtil.isAppGalleryApp(context, BuildConfig.APPLICATION_ID) && - BuildType.CURRENT != BuildType.DEBUG + !CertUtil.isAppGalleryApp(context, BuildConfig.APPLICATION_ID) && + BuildType.CURRENT != BuildType.DEBUG private val isAuroraOnlyFilterEnabled: Boolean get() = Preferences.getBoolean(context, Preferences.PREFERENCE_FILTER_AURORA_ONLY, false) @@ -77,14 +77,16 @@ class UpdateWorker @AssistedInject constructor( super.doWork() Log.i(TAG, "Checking for app updates") - val updateMode = UpdateMode.entries[inputData.getInt( - UpdateHelper.UPDATE_MODE, - Preferences.getInteger( - context, - PREFERENCE_UPDATES_AUTO, - UpdateMode.CHECK_AND_INSTALL.ordinal + val updateMode = UpdateMode.entries[ + inputData.getInt( + UpdateHelper.UPDATE_MODE, + Preferences.getInteger( + context, + PREFERENCE_UPDATES_AUTO, + UpdateMode.CHECK_AND_INSTALL.ordinal + ) ) - )] + ] if (updateMode == UpdateMode.DISABLED || !AccountProvider.isLoggedIn(context)) { Log.i(TAG, "Updates are disabled, bailing out!") @@ -107,7 +109,9 @@ class UpdateWorker @AssistedInject constructor( } // Notify and exit if we are only checking for updates or if battery optimizations are enabled - if (updateMode == UpdateMode.CHECK_AND_NOTIFY || !context.isIgnoringBatteryOptimizations()) { + if (updateMode == UpdateMode.CHECK_AND_NOTIFY || + !context.isIgnoringBatteryOptimizations() + ) { Log.i(TAG, "Found ${updates.size} updates, notifying!") notifyUpdates(updates) return Result.success() @@ -123,7 +127,10 @@ class UpdateWorker @AssistedInject constructor( // Notify about apps that cannot be auto-updated if (filteredUpdates.second.isNotEmpty()) { - Log.i(TAG, "Found ${updates.size} updates out of which ${filteredUpdates.second.size} cannot be auto-updated") + Log.i( + TAG, + "Found ${updates.size} updates out of which ${filteredUpdates.second.size} cannot be auto-updated" + ) notifyUpdates(filteredUpdates.second) } @@ -137,12 +144,10 @@ class UpdateWorker @AssistedInject constructor( } } - override suspend fun getForegroundInfo(): ForegroundInfo { - return ForegroundInfo( - notificationID, - NotificationUtil.getUpdateNotification(context) - ) - } + override suspend fun getForegroundInfo(): ForegroundInfo = ForegroundInfo( + notificationID, + NotificationUtil.getUpdateNotification(context) + ) /** * Checks and returns updates for all possible apps @@ -157,12 +162,18 @@ class UpdateWorker @AssistedInject constructor( val filteredPackages = if (isAuroraOnlyFilterEnabled) { packages.filter { CertUtil.isAuroraStoreApp(context, it.packageName) } } else { - packages.filterNot { if (isFDroidFilterEnabled) CertUtil.isFDroidApp(context, it.packageName) else false } - } + packages.filterNot { + if (isFDroidFilterEnabled) { + CertUtil.isFDroidApp(context, it.packageName) + } else { + false + } + } + }.map { it.packageName } - val updates = appDetailsHelper.getAppByPackageName(filteredPackages.map { it.packageName }) + val updates = appDetailsHelper.getAppByPackageName(filteredPackages) .filter { it.displayName.isNotEmpty() } - .filter { PackageUtil.isUpdatable(context, it.packageName, it.versionCode.toLong()) } + .filter { PackageUtil.isUpdatable(context, it.packageName, it.versionCode) } .toMutableList() if (canSelfUpdate) getSelfUpdate()?.let { updates.add(it) } @@ -179,7 +190,9 @@ class UpdateWorker @AssistedInject constructor( return withContext(Dispatchers.IO) { val updateUrl = when (BuildType.CURRENT) { BuildType.RELEASE -> Constants.UPDATE_URL_STABLE + BuildType.NIGHTLY -> Constants.UPDATE_URL_NIGHTLY + else -> { Log.i(TAG, "Self-updates are not available for this build!") return@withContext null @@ -193,6 +206,7 @@ class UpdateWorker @AssistedInject constructor( val isUpdate = when (BuildType.CURRENT) { BuildType.NIGHTLY, BuildType.RELEASE -> selfUpdate.versionCode > BuildConfig.VERSION_CODE + else -> false }