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:
Torsten Grote 2020-10-09 11:44:10 -03:00 committed by Chirayu Desai
parent d6cb34c211
commit 1a81e2ddd6
3 changed files with 56 additions and 16 deletions

View file

@ -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

View file

@ -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
}
}

View file

@ -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)
}