summaryrefslogtreecommitdiff
path: root/app/src/main/java/net/taler
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/net/taler')
-rw-r--r--app/src/main/java/net/taler/wallet/payment/ContractTerms.kt6
-rw-r--r--app/src/main/java/net/taler/wallet/payment/PaymentManager.kt21
-rw-r--r--app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt16
3 files changed, 39 insertions, 4 deletions
diff --git a/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt b/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
index a9f75ed..da91dea 100644
--- a/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
+++ b/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
@@ -29,20 +29,22 @@ data class ContractTerms(
)
interface Product {
- val id: String
+ val id: String?
val description: String
val price: Amount
val location: String?
+ val image: String?
}
@JsonIgnoreProperties("totalPrice")
data class ContractProduct(
@JsonProperty("product_id")
- override val id: String,
+ override val id: String?,
override val description: String,
override val price: Amount,
@JsonProperty("delivery_location")
override val location: String?,
+ override val image: String?,
val quantity: Int
) : Product {
diff --git a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
index a00a686..ee0edaf 100644
--- a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
+++ b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
@@ -26,6 +26,9 @@ import net.taler.wallet.Amount
import net.taler.wallet.TAG
import net.taler.wallet.backend.WalletBackendApi
import org.json.JSONObject
+import java.net.MalformedURLException
+
+val REGEX_PRODUCT_IMAGE = Regex("^data:image/(jpeg|png);base64,([A-Za-z0-9+/=]+)$")
class PaymentManager(
private val walletBackendApi: WalletBackendApi,
@@ -61,7 +64,12 @@ class PaymentManager(
}
else -> {
val status = result.getString("status")
- mPayStatus.postValue(getPayStatusUpdate(status, result))
+ try {
+ mPayStatus.postValue(getPayStatusUpdate(status, result))
+ } catch (e: Exception) {
+ Log.e(TAG, "Error getting PayStatusUpdate", e)
+ mPayStatus.postValue(PayStatus.Error(e.message ?: "unknown error"))
+ }
}
}
}
@@ -80,7 +88,16 @@ class PaymentManager(
}
private fun getContractTerms(json: JSONObject): ContractTerms {
- return mapper.readValue(json.getString("contractTermsRaw"))
+ val terms: ContractTerms = mapper.readValue(json.getString("contractTermsRaw"))
+ // validate product images
+ terms.products.forEach { product ->
+ product.image?.let { image ->
+ if (REGEX_PRODUCT_IMAGE.matchEntire(image) == null) {
+ throw MalformedURLException("Invalid image data URL for ${product.description}")
+ }
+ }
+ }
+ return terms
}
@UiThread
diff --git a/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt b/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
index 3a0dca6..8519dcb 100644
--- a/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
+++ b/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
@@ -16,9 +16,14 @@
package net.taler.wallet.payment
+import android.graphics.BitmapFactory.decodeByteArray
+import android.util.Base64
import android.view.LayoutInflater
import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
@@ -50,11 +55,22 @@ internal class ProductAdapter : RecyclerView.Adapter<ProductViewHolder>() {
internal inner class ProductViewHolder(v: View) : ViewHolder(v) {
private val quantity: TextView = v.findViewById(R.id.quantity)
+ private val image: ImageView = v.findViewById(R.id.image)
private val name: TextView = v.findViewById(R.id.name)
private val price: TextView = v.findViewById(R.id.price)
fun bind(product: ContractProduct) {
quantity.text = product.quantity.toString()
+ if (product.image == null) {
+ image.visibility = GONE
+ } else {
+ image.visibility = VISIBLE
+ // product.image was validated before, so non-null below
+ val match = REGEX_PRODUCT_IMAGE.matchEntire(product.image)!!
+ val decodedString = Base64.decode(match.groups[2]!!.value, Base64.DEFAULT)
+ val bitmap = decodeByteArray(decodedString, 0, decodedString.size)
+ image.setImageBitmap(bitmap)
+ }
name.text = product.description
price.text = product.totalPrice.toString()
}