Cleanup and retire non-working download options
* External storage download uses external files directory and not the SD card to downloads while the description states otherwise. This is in-accurate and thus dropped (See #985). * Custom download path is broken which was implemented as a workaround for the above (See #1003). * Move downloads storage to internal files directory which is sandboxed and only accessible to us. Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -20,10 +20,8 @@
|
||||
|
||||
package com.aurora.store
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -36,9 +34,7 @@ import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED
|
||||
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED
|
||||
@@ -56,8 +52,6 @@ import com.aurora.Constants
|
||||
import com.aurora.extensions.accentColor
|
||||
import com.aurora.extensions.applyThemeAccent
|
||||
import com.aurora.extensions.isMAndAbove
|
||||
import com.aurora.extensions.isRAndAbove
|
||||
import com.aurora.extensions.toast
|
||||
import com.aurora.store.data.model.NetworkStatus
|
||||
import com.aurora.store.data.providers.NetworkProvider
|
||||
import com.aurora.store.databinding.ActivityMainBinding
|
||||
@@ -76,11 +70,6 @@ class MainActivity : AppCompatActivity() {
|
||||
private lateinit var navController: NavController
|
||||
private lateinit var appConfig: AppBarConfiguration
|
||||
|
||||
private val startForPermissions =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
if (!it) toast(R.string.permissions_denied)
|
||||
}
|
||||
|
||||
// TopLevelFragments
|
||||
private val topLevelFrags = listOf(
|
||||
R.id.appsContainerFragment,
|
||||
@@ -131,21 +120,6 @@ class MainActivity : AppCompatActivity() {
|
||||
attachNavigation()
|
||||
attachDrawer()
|
||||
|
||||
/*Check only if download to external storage is enabled*/
|
||||
if (Preferences.getBoolean(this, Preferences.PREFERENCE_DOWNLOAD_EXTERNAL)) {
|
||||
if (isRAndAbove()) {
|
||||
checkExternalStorageManagerPermission()
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
startForPermissions.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle quick exit from back actions
|
||||
val defaultTab = when (Preferences.getInteger(this, PREFERENCE_DEFAULT_SELECTED_TAB)) {
|
||||
1 -> R.id.gamesContainerFragment
|
||||
@@ -212,6 +186,7 @@ class MainActivity : AppCompatActivity() {
|
||||
navController.navigate(R.id.downloadFragment)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.menu_doze_info -> {
|
||||
navController.navigate(R.id.dozeWarningSheet)
|
||||
return true
|
||||
|
||||
@@ -74,7 +74,7 @@ class SpoofDeviceProvider private constructor(var context: Context) {
|
||||
private val spoofDevicesFromUser: List<Properties>
|
||||
get() {
|
||||
val deviceNames: MutableList<Properties> = ArrayList()
|
||||
val defaultDir = File(PathUtil.getSpoofDirectory(context))
|
||||
val defaultDir = PathUtil.getSpoofDirectory(context)
|
||||
val files = defaultDir.listFiles()
|
||||
if (defaultDir.exists() && files != null) {
|
||||
for (file in files) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import com.aurora.store.data.room.download.DownloadDao
|
||||
import com.aurora.store.data.work.DownloadWorker
|
||||
import com.google.gson.Gson
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
@@ -104,7 +103,7 @@ class DownloadWorkerUtil @Inject constructor(
|
||||
suspend fun clearAllDownloads() {
|
||||
Log.i(TAG, "Clearing all downloads!")
|
||||
downloadDao.deleteAll()
|
||||
File(PathUtil.getDownloadDirectory(context), "Downloads").deleteRecursively()
|
||||
PathUtil.getDownloadDirectory(context).deleteRecursively()
|
||||
}
|
||||
|
||||
suspend fun clearFinishedDownloads() {
|
||||
|
||||
@@ -21,42 +21,22 @@ package com.aurora.store.util
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import com.aurora.extensions.isRAndAbove
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import com.aurora.gplayapi.data.models.File as GPlayFile
|
||||
|
||||
fun Context.getInternalBaseDirectory(): String {
|
||||
return (getExternalFilesDir(null) ?: filesDir).path
|
||||
}
|
||||
|
||||
object PathUtil {
|
||||
|
||||
private const val libraries = "libraries"
|
||||
private const val LIBRARIES = "libraries"
|
||||
private const val DOWNLOADS = "Downloads"
|
||||
private const val SPOOF = "SpoofConfigs"
|
||||
|
||||
fun getDownloadDirectory(context: Context): String {
|
||||
return if (context.isExternalStorageEnable()) {
|
||||
getExternalPath(context)
|
||||
} else {
|
||||
context.getInternalBaseDirectory()
|
||||
}
|
||||
fun getDownloadDirectory(context: Context): File {
|
||||
return File(context.filesDir, DOWNLOADS)
|
||||
}
|
||||
|
||||
fun getPackageDirectory(context: Context, packageName: String): String {
|
||||
return getDownloadDirectory(context) + "/Downloads/$packageName"
|
||||
}
|
||||
|
||||
private fun getVersionDirectory(
|
||||
context: Context,
|
||||
packageName: String,
|
||||
versionCode: Int,
|
||||
sharedLibPackageName: String? = null
|
||||
): String {
|
||||
return if (!sharedLibPackageName.isNullOrBlank()) {
|
||||
getLibDownloadDir(context, packageName, versionCode, sharedLibPackageName).absolutePath
|
||||
} else {
|
||||
getPackageDirectory(context, packageName) + "/$versionCode"
|
||||
}
|
||||
private fun getPackageDirectory(context: Context, packageName: String): File {
|
||||
return File(getDownloadDirectory(context), packageName)
|
||||
}
|
||||
|
||||
fun getAppDownloadDir(context: Context, packageName: String, versionCode: Int): File {
|
||||
@@ -71,7 +51,7 @@ object PathUtil {
|
||||
): File {
|
||||
return File(
|
||||
getAppDownloadDir(context, packageName, versionCode).absolutePath,
|
||||
"$libraries/$sharedLibPackageName"
|
||||
"$LIBRARIES/$sharedLibPackageName"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,19 +62,15 @@ object PathUtil {
|
||||
file: GPlayFile,
|
||||
sharedLibPackageName: String? = null
|
||||
): String {
|
||||
return getVersionDirectory(
|
||||
context,
|
||||
packageName,
|
||||
versionCode,
|
||||
sharedLibPackageName
|
||||
) + "/${file.name}"
|
||||
val downloadDir = if (!sharedLibPackageName.isNullOrBlank()) {
|
||||
getLibDownloadDir(context, packageName, versionCode, sharedLibPackageName)
|
||||
} else {
|
||||
File(getPackageDirectory(context, packageName), versionCode.toString())
|
||||
}
|
||||
return File(downloadDir, file.name).absolutePath
|
||||
}
|
||||
|
||||
fun getZipFile(
|
||||
context: Context,
|
||||
packageName: String,
|
||||
versionCode: Int
|
||||
): File {
|
||||
fun getZipFile(context: Context, packageName: String, versionCode: Int): File {
|
||||
return File(
|
||||
getAppDownloadDir(
|
||||
context,
|
||||
@@ -104,67 +80,27 @@ object PathUtil {
|
||||
)
|
||||
}
|
||||
|
||||
fun getExternalPath(context: Context): String {
|
||||
val defaultDir =
|
||||
File("${Environment.getExternalStorageDirectory().absolutePath}/Aurora/Store")
|
||||
|
||||
if (!defaultDir.exists())
|
||||
defaultDir.mkdirs()
|
||||
|
||||
return Preferences.getString(
|
||||
context,
|
||||
Preferences.PREFERENCE_DOWNLOAD_DIRECTORY,
|
||||
defaultDir.absolutePath
|
||||
)
|
||||
}
|
||||
|
||||
private fun getObbDownloadPath(packageName: String): String {
|
||||
return Environment.getExternalStorageDirectory()
|
||||
.toString() + "/Android/obb/" + packageName
|
||||
}
|
||||
|
||||
fun getObbDownloadDir(packageName: String): File {
|
||||
return File(
|
||||
Environment.getExternalStorageDirectory().absolutePath,
|
||||
"/Android/obb/$packageName"
|
||||
)
|
||||
return File(Environment.getExternalStorageDirectory(), "/Android/obb/$packageName")
|
||||
}
|
||||
|
||||
fun getObbDownloadFile(packageName: String, file: GPlayFile): String {
|
||||
val obbDir = getObbDownloadPath(packageName)
|
||||
return "$obbDir/${file.name}"
|
||||
return File(getObbDownloadDir(packageName), file.name).absolutePath
|
||||
}
|
||||
|
||||
fun needsStorageManagerPerm(fileList: List<GPlayFile>): Boolean {
|
||||
return fileList.any { it.type == GPlayFile.FileType.OBB || it.type == GPlayFile.FileType.PATCH }
|
||||
}
|
||||
|
||||
fun getSpoofDirectory(context: Context): String {
|
||||
return "${context.getInternalBaseDirectory()}/SpoofConfigs"
|
||||
fun getSpoofDirectory(context: Context): File {
|
||||
return File(context.filesDir, SPOOF)
|
||||
}
|
||||
|
||||
fun getNewEmptySpoofConfig(context: Context): File {
|
||||
val file = File("${getSpoofDirectory(context)}/${UUID.randomUUID()}.properties")
|
||||
val file = File(getSpoofDirectory(context), "${UUID.randomUUID()}.properties")
|
||||
file.parentFile?.mkdirs()
|
||||
file.createNewFile()
|
||||
return file
|
||||
}
|
||||
|
||||
fun canWriteToDirectory(context: Context, directoryPath: String): Boolean {
|
||||
val directory = if (directoryPath.startsWith("/")) {
|
||||
File(directoryPath)
|
||||
} else {
|
||||
File(context.getExternalFilesDir(null), directoryPath)
|
||||
}
|
||||
|
||||
return if (isRAndAbove()) {
|
||||
Environment.isExternalStorageManager() && directory.exists() && directory.canWrite()
|
||||
} else {
|
||||
isExternalStorageAccessible(context) && directory.exists() && directory.canWrite()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.isExternalStorageEnable(): Boolean {
|
||||
return Preferences.getBoolean(this, Preferences.PREFERENCE_DOWNLOAD_EXTERNAL)
|
||||
}
|
||||
|
||||
@@ -48,9 +48,6 @@ object Preferences {
|
||||
|
||||
const val INSTALLATION_ABANDON_SESSION = "INSTALLATION_ABANDON_SESSION"
|
||||
|
||||
const val PREFERENCE_DOWNLOAD_EXTERNAL = "PREFERENCE_DOWNLOAD_EXTERNAL"
|
||||
const val PREFERENCE_DOWNLOAD_DIRECTORY = "PREFERENCE_DOWNLOAD_DIRECTORY"
|
||||
|
||||
const val PREFERENCE_TOS_READ = "PREFERENCE_TOS_READ"
|
||||
|
||||
const val PREFERENCE_INSECURE_ANONYMOUS = "PREFERENCE_INSECURE_ANONYMOUS"
|
||||
|
||||
@@ -77,7 +77,6 @@ import com.aurora.store.util.PackageUtil
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.ShortcutManagerUtil
|
||||
import com.aurora.store.util.isExternalStorageEnable
|
||||
import com.aurora.store.view.custom.RatingView
|
||||
import com.aurora.store.view.epoxy.controller.DetailsCarouselController
|
||||
import com.aurora.store.view.epoxy.controller.GenericCarouselController
|
||||
@@ -545,7 +544,7 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
updateActionState(State.PROGRESS)
|
||||
|
||||
if (PathUtil.needsStorageManagerPerm(app.fileList) || requireContext().isExternalStorageEnable()) {
|
||||
if (PathUtil.needsStorageManagerPerm(app.fileList)) {
|
||||
if (isRAndAbove()) {
|
||||
if (!Environment.isExternalStorageManager()) {
|
||||
startForStorageManagerResult.launch(
|
||||
|
||||
@@ -31,13 +31,10 @@ import com.aurora.extensions.isSAndAbove
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.work.UpdateWorker
|
||||
import com.aurora.store.databinding.FragmentOnboardingBinding
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT_SELECTED_TAB
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DOWNLOAD_DIRECTORY
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_DOWNLOAD_EXTERNAL
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_AURORA_ONLY
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_FDROID
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_FILTER_GOOGLE
|
||||
@@ -161,10 +158,6 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) {
|
||||
save(PREFERENCE_FILTER_GOOGLE, false)
|
||||
save(PREFERENCE_FILTER_SEARCH, true)
|
||||
|
||||
/*Downloader*/
|
||||
save(PREFERENCE_DOWNLOAD_EXTERNAL, false)
|
||||
save(PREFERENCE_DOWNLOAD_DIRECTORY, PathUtil.getExternalPath(requireContext()))
|
||||
|
||||
/*Network*/
|
||||
save(PREFERENCE_INSECURE_ANONYMOUS, false)
|
||||
save(PREFERENCE_PROXY_ENABLED, false)
|
||||
|
||||
@@ -19,61 +19,16 @@
|
||||
|
||||
package com.aurora.store.view.ui.preferences
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import com.aurora.extensions.isRAndAbove
|
||||
import com.aurora.extensions.toast
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.isExternalStorageAccessible
|
||||
import com.aurora.store.util.save
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DownloadPreference : PreferenceFragmentCompat() {
|
||||
private lateinit var startForStorageManagerResult: ActivityResultLauncher<Intent>
|
||||
private lateinit var startForPermissions: ActivityResultLauncher<String>
|
||||
|
||||
private var downloadDirectoryPreference: Preference? = null
|
||||
private var downloadExternalPreference: SwitchPreferenceCompat? = null
|
||||
private var autoDeletePreference: SwitchPreferenceCompat? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
startForStorageManagerResult =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
val state = isRAndAbove() && Environment.isExternalStorageManager()
|
||||
if (state) {
|
||||
downloadDirectoryPreference?.summary =
|
||||
PathUtil.getExternalPath(requireContext())
|
||||
} else {
|
||||
notifyPermissionState(isRAndAbove() && Environment.isExternalStorageManager())
|
||||
}
|
||||
}
|
||||
|
||||
startForPermissions =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
if (it) {
|
||||
notifyPermissionState(it)
|
||||
} else {
|
||||
downloadExternalPreference?.isChecked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.preferences_download, rootKey)
|
||||
@@ -86,67 +41,5 @@ class DownloadPreference : PreferenceFragmentCompat() {
|
||||
title = getString(R.string.pref_app_download)
|
||||
setNavigationOnClickListener { findNavController().navigateUp() }
|
||||
}
|
||||
|
||||
downloadDirectoryPreference = findPreference(Preferences.PREFERENCE_DOWNLOAD_DIRECTORY)
|
||||
downloadExternalPreference = findPreference(Preferences.PREFERENCE_DOWNLOAD_EXTERNAL)
|
||||
autoDeletePreference = findPreference(Preferences.PREFERENCE_AUTO_DELETE)
|
||||
|
||||
downloadDirectoryPreference?.let { preference ->
|
||||
preference.summary = PathUtil.getExternalPath(requireContext())
|
||||
preference.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { it, newValue ->
|
||||
if (PathUtil.canWriteToDirectory(requireContext(), newValue.toString())) {
|
||||
it.summary = newValue.toString()
|
||||
save(Preferences.PREFERENCE_DOWNLOAD_DIRECTORY, newValue.toString())
|
||||
true
|
||||
} else {
|
||||
toast(R.string.pref_download_directory_error)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
downloadExternalPreference?.let { switchPreferenceCompat ->
|
||||
switchPreferenceCompat.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||
val checked = newValue.toString().toBoolean()
|
||||
|
||||
if (checked) {
|
||||
if (isRAndAbove() && !Environment.isExternalStorageManager()) {
|
||||
startForStorageManagerResult.launch(
|
||||
Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||
)
|
||||
}
|
||||
|
||||
if (!isRAndAbove() && !isExternalStorageAccessible(requireContext())) {
|
||||
startForPermissions.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
autoDeletePreference?.let {
|
||||
if (checked) {
|
||||
it.isEnabled = true
|
||||
} else {
|
||||
it.isEnabled = false
|
||||
it.isChecked = true
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyPermissionState(state: Boolean) {
|
||||
if (state) {
|
||||
toast(R.string.toast_permission_granted)
|
||||
} else {
|
||||
toast(R.string.permissions_denied)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
startForStorageManagerResult.unregister()
|
||||
startForPermissions.unregister()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.aurora.store.data.event.BusEvent
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.databinding.FragmentUpdatesBinding
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.isExternalStorageEnable
|
||||
import com.aurora.store.view.epoxy.views.UpdateHeaderViewModel_
|
||||
import com.aurora.store.view.epoxy.views.app.AppUpdateViewModel_
|
||||
import com.aurora.store.view.epoxy.views.app.NoAppViewModel_
|
||||
@@ -203,9 +202,7 @@ class UpdatesFragment : BaseFragment(R.layout.fragment_updates) {
|
||||
this.app = app
|
||||
viewModel.updateAllEnqueued = updateAll
|
||||
|
||||
if (PathUtil.needsStorageManagerPerm(app.fileList) ||
|
||||
requireContext().isExternalStorageEnable()
|
||||
) {
|
||||
if (PathUtil.needsStorageManagerPerm(app.fileList)) {
|
||||
if (isRAndAbove()) {
|
||||
if (!Environment.isExternalStorageManager()) {
|
||||
startForStorageManagerResult.launch(
|
||||
|
||||
Reference in New Issue
Block a user