Prompt user to install OpenKeychain when missing (#1005)

* Prompt user to install OpenKeychain when missing

Fixes #996

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* Update changelog

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya
2020-08-10 18:11:16 +05:30
committed by GitHub
parent 3dace243e4
commit 1c4ac91c6c
3 changed files with 68 additions and 3 deletions

View File

@@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file.
- Allow creating nested directories directly - Allow creating nested directories directly
- I keep saying this but for real: error message for wrong SSH/HTTPS password is properly fixed now - I keep saying this but for real: error message for wrong SSH/HTTPS password is properly fixed now
- Fix crash when OpenKeychain is not installed
## [1.10.3] - 2020-07-30 ## [1.10.3] - 2020-07-30

View File

@@ -6,10 +6,13 @@
package com.zeapo.pwdstore.crypto package com.zeapo.pwdstore.crypto
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ActivityNotFoundException
import android.content.ClipData import android.content.ClipData
import android.content.Intent import android.content.Intent
import android.content.IntentSender import android.content.IntentSender
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.format.DateUtils import android.text.format.DateUtils
@@ -17,10 +20,10 @@ import android.view.WindowManager
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import com.github.ajalt.timberkt.Timber.tag import com.github.ajalt.timberkt.Timber.tag
import com.github.ajalt.timberkt.e import com.github.ajalt.timberkt.e
import com.github.ajalt.timberkt.i import com.github.ajalt.timberkt.i
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.zeapo.pwdstore.ClipboardService import com.zeapo.pwdstore.ClipboardService
import com.zeapo.pwdstore.R import com.zeapo.pwdstore.R
@@ -78,6 +81,12 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
private var serviceConnection: OpenPgpServiceConnection? = null private var serviceConnection: OpenPgpServiceConnection? = null
var api: OpenPgpApi? = null var api: OpenPgpApi? = null
/**
* A [OpenPgpServiceConnection.OnBound] instance for the last listener that we wish to bind with
* in case the previous attempt was cancelled due to missing [OPENPGP_PROVIDER] package.
*/
private var previousListener: OpenPgpServiceConnection.OnBound? = null
/** /**
* [onCreate] sets the window up with the right flags to prevent auth leaks through screenshots * [onCreate] sets the window up with the right flags to prevent auth leaks through screenshots
* or recent apps screen. * or recent apps screen.
@@ -98,6 +107,16 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
serviceConnection?.unbindFromService() serviceConnection?.unbindFromService()
previousListener = null
}
/**
* [onResume] controls the flow for resumption of a PGP operation that was previously interrupted
* by the [OPENPGP_PROVIDER] package being missing.
*/
override fun onResume() {
super.onResume()
previousListener?.let { bindToOpenKeychain(it) }
} }
/** /**
@@ -122,8 +141,45 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
* Method for subclasses to initiate binding with [OpenPgpServiceConnection]. * Method for subclasses to initiate binding with [OpenPgpServiceConnection].
*/ */
fun bindToOpenKeychain(onBoundListener: OpenPgpServiceConnection.OnBound) { fun bindToOpenKeychain(onBoundListener: OpenPgpServiceConnection.OnBound) {
serviceConnection = OpenPgpServiceConnection(this, OPENPGP_PROVIDER, onBoundListener) val installed = try {
serviceConnection?.bindToService() packageManager.getPackageInfo(OPENPGP_PROVIDER, 0)
true
} catch (_: PackageManager.NameNotFoundException) {
false
}
if (!installed) {
previousListener = onBoundListener
MaterialAlertDialogBuilder(this)
.setTitle(getString(R.string.openkeychain_not_installed_title))
.setMessage(getString(R.string.openkeychain_not_installed_message))
.setPositiveButton(getString(R.string.openkeychain_not_installed_google_play)) { _, _ ->
try {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(getString(R.string.play_deeplink_template, OPENPGP_PROVIDER))
setPackage("com.android.vending")
}
startActivity(intent)
} catch (_: ActivityNotFoundException) {
}
}
.setNeutralButton(getString(R.string.openkeychain_not_installed_fdroid)) { _, _ ->
try {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(getString(R.string.fdroid_deeplink_template, OPENPGP_PROVIDER))
}
startActivity(intent)
} catch (_: ActivityNotFoundException) {
}
}
.setOnCancelListener { finish() }
.show()
return
} else {
previousListener = null
serviceConnection = OpenPgpServiceConnection(this, OPENPGP_PROVIDER, onBoundListener).also {
it.bindToService()
}
}
} }
/** /**

View File

@@ -375,4 +375,12 @@
<string name="git_push_generic_error">Push was rejected by remote, reason: %1$s</string> <string name="git_push_generic_error">Push was rejected by remote, reason: %1$s</string>
<string name="git_push_other_error">Remote rejected non-fast-forward push. Check receive.denyNonFastForwards variable in config file of destination repository.</string> <string name="git_push_other_error">Remote rejected non-fast-forward push. Check receive.denyNonFastForwards variable in config file of destination repository.</string>
<string name="git_operation_running">Running git operation…</string> <string name="git_operation_running">Running git operation…</string>
<!-- OpenKeychain not installed -->
<string name="openkeychain_not_installed_title">OpenKeychain not installed</string>
<string name="openkeychain_not_installed_message">OpenKeychain is required for Password Store to function, please install it from the stores below</string>
<string name="openkeychain_not_installed_google_play">Google Play</string>
<string name="play_deeplink_template">https://play.google.com/store/apps/details?id=%1$s</string>
<string name="openkeychain_not_installed_fdroid">F-Droid</string>
<string name="fdroid_deeplink_template">https://f-droid.org/en/packages/%1$s/</string>
</resources> </resources>