If possible, open the app store an app was originally installed with
When an app fails to install during restore, we offer the option to manually install it. If this doesn't happen with the same app store, it is likely that the installed app will have a different signature (e.g. Aurora vs. F-Droid). If the signature doesn't match, the data restore will fail. Therefore, we attempt to let the user only use the same store for re-install. There's a known issue that F-Droid doesn't report the proper package name: https://gitlab.com/fdroid/fdroidclient/-/issues/2085
This commit is contained in:
parent
d6cb34c211
commit
1a81e2ddd6
3 changed files with 56 additions and 16 deletions
|
@ -29,6 +29,7 @@ import com.stevesoltys.seedvault.metadata.PackageState.WAS_STOPPED
|
|||
import com.stevesoltys.seedvault.restore.DisplayFragment.RESTORE_APPS
|
||||
import com.stevesoltys.seedvault.restore.DisplayFragment.RESTORE_BACKUP
|
||||
import com.stevesoltys.seedvault.restore.install.ApkRestore
|
||||
import com.stevesoltys.seedvault.restore.install.InstallIntentCreator
|
||||
import com.stevesoltys.seedvault.restore.install.InstallResult
|
||||
import com.stevesoltys.seedvault.settings.SettingsManager
|
||||
import com.stevesoltys.seedvault.transport.TRANSPORT_ID
|
||||
|
@ -88,6 +89,7 @@ internal class RestoreViewModel(
|
|||
switchMap(mChosenRestorableBackup) { backup ->
|
||||
getInstallResult(backup)
|
||||
}
|
||||
internal val installIntentCreator by lazy { InstallIntentCreator(app.packageManager) }
|
||||
|
||||
private val mNextButtonEnabled = MutableLiveData<Boolean>().apply { value = false }
|
||||
internal val nextButtonEnabled: LiveData<Boolean> = mNextButtonEnabled
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.stevesoltys.seedvault.restore.install
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_VIEW
|
||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
|
||||
internal class InstallIntentCreator(
|
||||
private val packageManager: PackageManager
|
||||
) {
|
||||
|
||||
private val installerToPackage = mapOf(
|
||||
"org.fdroid.fdroid" to "org.fdroid.fdroid",
|
||||
"org.fdroid.fdroid.privileged" to "org.fdroid.fdroid",
|
||||
"com.aurora.store" to "com.aurora.store",
|
||||
"com.aurora.services" to "com.aurora.store",
|
||||
"com.android.vending" to "com.android.vending"
|
||||
)
|
||||
private val isPackageInstalled = HashMap<String, Boolean>()
|
||||
|
||||
fun getIntent(packageName: CharSequence, installerPackageName: CharSequence?): Intent {
|
||||
val i = Intent(ACTION_VIEW, Uri.parse("market://details?id=$packageName")).apply {
|
||||
addFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(FLAG_ACTIVITY_CLEAR_TOP)
|
||||
addFlags(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
|
||||
}
|
||||
getIntentPackage(installerPackageName)?.let { i.setPackage(it) }
|
||||
return i
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a package name to restrict the intent to
|
||||
* or null if we can't restrict the intent.
|
||||
*/
|
||||
private fun getIntentPackage(installerPackageName: CharSequence?): String? {
|
||||
if (installerPackageName == null) return null
|
||||
val packageName = installerToPackage[installerPackageName] ?: return null
|
||||
val isInstalled = isPackageInstalled.getOrPut(packageName) {
|
||||
try {
|
||||
packageManager.getPackageInfo(packageName, 0)
|
||||
true
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
return if (isInstalled) packageName else null
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,5 @@
|
|||
package com.stevesoltys.seedvault.restore.install
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.Intent.ACTION_VIEW
|
||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -121,16 +115,8 @@ class InstallProgressFragment : Fragment(), InstallItemListener {
|
|||
}
|
||||
|
||||
override fun onFailedItemClicked(item: ApkInstallResult) {
|
||||
// TODO restrict intent to installer package names to one of:
|
||||
// * "org.fdroid.fdroid" "org.fdroid.fdroid.privileged"
|
||||
// * "com.aurora.store"
|
||||
// * "com.android.vending"
|
||||
val i = Intent(ACTION_VIEW, Uri.parse("market://details?id=${item.packageName}")).apply {
|
||||
addFlags(FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(FLAG_ACTIVITY_CLEAR_TOP)
|
||||
addFlags(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
|
||||
// setPackage("com.aurora.store")
|
||||
}
|
||||
val i =
|
||||
viewModel.installIntentCreator.getIntent(item.packageName, item.installerPackageName)
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue