diff --git a/app/src/main/java/com/tangem/data/network/Server.java b/app/src/main/java/com/tangem/data/network/Server.java index aa9b5835b7..8638e2e1dd 100644 --- a/app/src/main/java/com/tangem/data/network/Server.java +++ b/app/src/main/java/com/tangem/data/network/Server.java @@ -11,8 +11,8 @@ public class Server { public static class Method { public static final String VERIFY = URL_TANGEM + "verify"; - public static final String VERIFY_AND_GET_ARTWORK = URL_TANGEM + "verify-and-get-artwork"; - public static final String ARTWORK = URL_TANGEM + "artwork"; + public static final String VERIFY_AND_GET_ARTWORK = URL_TANGEM + "card/verify-and-get-artwork"; + public static final String ARTWORK = URL_TANGEM + "card/artwork"; } } diff --git a/app/src/main/java/com/tangem/data/network/ServerApiHelper.java b/app/src/main/java/com/tangem/data/network/ServerApiHelper.java index 6446705aad..e3df2ad909 100644 --- a/app/src/main/java/com/tangem/data/network/ServerApiHelper.java +++ b/app/src/main/java/com/tangem/data/network/ServerApiHelper.java @@ -28,6 +28,7 @@ import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -252,9 +253,18 @@ public class ServerApiHelper { } public void cardVerifyAndGetArtwork(TangemCard card) { + + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); + logging.setLevel(HttpLoggingInterceptor.Level.BODY); + + OkHttpClient httpClient = new OkHttpClient.Builder(). + addInterceptor(logging). + build(); + Retrofit retrofit = new Retrofit.Builder() .baseUrl(Server.ApiTangem.URL_TANGEM) .addConverterFactory(GsonConverterFactory.create()) + .client(httpClient) .build(); TangemApi tangemApi = retrofit.create(TangemApi.class); @@ -290,41 +300,41 @@ public class ServerApiHelper { private ArtworkListener artworkListener; public interface ArtworkListener { - void onArtwork(InputStream inputStream); + void onArtwork(String artworkId, InputStream inputStream, Instant updateDate); } public void setArtworkListener(ArtworkListener listener) { artworkListener = listener; } - public void requestArtwork() { + public void requestArtwork(String artworkId, Instant updateDate, TangemCard card) { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient httpClient = new OkHttpClient.Builder(). addInterceptor(logging). -// addInterceptor(new AuthorizationInterceptor()). - build(); + build(); Retrofit retrofit = new Retrofit.Builder() - .baseUrl(Server.ApiUpdateVersion.URL_UPDATE_VERSION) + .baseUrl(Server.ApiTangem.URL_TANGEM) .addConverterFactory(GsonConverterFactory.create()) .client(httpClient) .build(); - UpdateVersionApi updateVersionApi = retrofit.create(UpdateVersionApi.class); + TangemApi tangemApi = retrofit.create(TangemApi.class); - Call call = updateVersionApi.getLastVersion(); + Call call = tangemApi.getArtwork(artworkId, Util.bytesToHex(card.getCID()), Util.bytesToHex(card.getCardPublicKey())); call.enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { - Log.i(TAG, "lastVersion onResponse " + response.code()); - if (response.code() == 200) { - String stringResponse; + Log.i(TAG, "getArtwork onResponse " + response.code()); + if (response.code() == 200 ) { try { - stringResponse = response.body().string(); - lastVersionListener.onLastVersion(stringResponse); - } catch (IOException e) { + ResponseBody body=response.body(); + if ( body!= null) { + artworkListener.onArtwork(artworkId, body.byteStream(), updateDate); + } + } catch (Exception e) { e.printStackTrace(); } } @@ -332,14 +342,13 @@ public class ServerApiHelper { @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e(TAG, "lastVersion onFailure " + t.getMessage()); + Log.e(TAG, "getArtwork onFailure " + t.getMessage()); } }); } - /** * HTTP * Used in Crypto-currency course diff --git a/app/src/main/java/com/tangem/data/network/ServerURL.java b/app/src/main/java/com/tangem/data/network/ServerURL.java index 0f7627ec4f..67fa260b8a 100644 --- a/app/src/main/java/com/tangem/data/network/ServerURL.java +++ b/app/src/main/java/com/tangem/data/network/ServerURL.java @@ -1,7 +1,7 @@ package com.tangem.data.network; public class ServerURL { - public static final String API_TANGEM = "https://tangem-services.appspot.com"; //TODO: "https://verify.tangem.com/"; + public static final String API_TANGEM = "https://tangem-services.appspot.com/"; //TODO: "https://verify.tangem.com/"; public static final String API_COINMARKETCAP = "https://api.coinmarketcap.com/"; public static final String API_INFURA = "https://mainnet.infura.io/"; public static final String API_ESTIMATEFEE = " https://estimatefee.com/"; diff --git a/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt b/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt index 7c162aae2b..5d58b694d0 100644 --- a/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt +++ b/app/src/main/java/com/tangem/data/network/model/CardVerifyAndGetArtwork.kt @@ -25,19 +25,29 @@ class CardVerifyAndGetArtwork { ) { data class Item( - var error: String = "", + var error: String? = null, var CID: String = "", var passed: Boolean = false, var batch: String = "", var artworkId: String = "", var artworkHash: String = "", - var update_date: String = "" + var updateDate: String = "" ) { fun getUpdateDate(): Instant? { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - return LocalDateTime.parse(update_date, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toInstant(ZoneOffset.UTC) - }else{ - return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(update_date).toInstant() + return try { + LocalDateTime.parse(updateDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toInstant(ZoneOffset.UTC) + } catch (e: Exception) { + e.printStackTrace() + null + } + } else { + return try { + SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(updateDate).toInstant() + } catch (e: Exception) { + e.printStackTrace() + null + } } } } diff --git a/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt b/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt index 8f1931adc5..ea0898e1f0 100644 --- a/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt +++ b/app/src/main/java/com/tangem/domain/wallet/ArtworksStorage.kt @@ -26,7 +26,7 @@ data class ArtworksStorage( init { if (artworksFile.exists()) { - artworksFile.bufferedReader().use { artworks = Gson().fromJson(it, object : TypeToken>() {}.type) } + artworksFile.bufferedReader().use { artworks = Gson().fromJson(it, object : TypeToken>() {}.type) } } else { artworks = HashMap() putResourceArtworkToCatalog("card_default", false) @@ -34,7 +34,7 @@ data class ArtworksStorage( putResourceArtworkToCatalog("card_btc_005", true) } if (batchesFile.exists()) { - batchesFile.bufferedReader().use { batches = Gson().fromJson(it, object : TypeToken>() {}.type) } + batchesFile.bufferedReader().use { batches = Gson().fromJson(it, object : TypeToken>() {}.type) } } else { batches = HashMap() @@ -62,15 +62,7 @@ data class ArtworksStorage( } } - fun checkNeedUpdateArtwork(batch: String, artworkId: String, artworkHash: String, updateDate: Instant?): Boolean { - val batchInfo = batches[batch] - if (batchInfo == null) { - putBatchToCatalog(batch, artworkId) - return true - } - if (batchInfo.artworkId != artworkId) { - putBatchToCatalog(batch, artworkId) - } + fun checkNeedUpdateArtwork(artworkId: String, artworkHash: String, updateDate: Instant?): Boolean { val artwork = artworks[artworkId] ?: return true if (artwork.hash == artworkHash) return false @@ -80,10 +72,23 @@ data class ArtworksStorage( return artwork.updateDate == null || artwork.updateDate < updateDate } + fun checkBatchArtworkChanged(batch: String, artworkId: String): Boolean { + val batchInfo = batches[batch] + if (batchInfo == null) { + putBatchToCatalog(batch, artworkId) + return true + } + if (batchInfo.artworkId != artworkId) { + putBatchToCatalog(batch, artworkId) + return true + } + return false + } + fun updateArtwork(artworkId: String, inputStream: InputStream, updateDate: Instant) { val data = inputStream.readBytes() cache.saveBitmap(artworkId, data) - putArtworkToCatalog(artworkId, data, updateDate, true) + putArtworkToCatalog(artworkId, false, data, updateDate, true) } private fun putBatchToCatalog(batch: String, artworkId: String, forceSave: Boolean = true) { @@ -96,12 +101,12 @@ data class ArtworksStorage( @SuppressLint("ResourceType") private fun putResourceArtworkToCatalog(artworkId: String, forceSave: Boolean) { - context.resources.openRawResource(R.drawable.card_default).use { putArtworkToCatalog(artworkId, it.readBytes(), null, forceSave) } + context.resources.openRawResource(R.drawable.card_default).use { putArtworkToCatalog(artworkId, true, it.readBytes(), null, forceSave) } } - private fun putArtworkToCatalog(artworkId: String, data: ByteArray, instant: Instant?, forceSave: Boolean = true) { + private fun putArtworkToCatalog(artworkId: String, isResource: Boolean, data: ByteArray, instant: Instant?, forceSave: Boolean = true) { val artworkInfo = ArtworkInfo( - false, Util.bytesToHex(Util.calculateSHA256(data)), instant + isResource, Util.bytesToHex(Util.calculateSHA256(data)), instant ) artworks[artworkId] = artworkInfo if (forceSave) { diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt index 26f7f31acb..b8ee91dd04 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.kt @@ -80,10 +80,11 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific private var timerRepeatRefresh: Timer? = null - private val artworksStorage: ArtworksStorage = ArtworksStorage(context!!) + private lateinit var artworksStorage: ArtworksStorage override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + nfcManager = NfcManager(activity, this) serverApiHelper = ServerApiHelper() @@ -94,6 +95,8 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific card!!.loadFromBundle(activity!!.intent.extras.getBundle(TangemCard.EXTRA_CARD)) lastTag = activity!!.intent.getParcelableExtra(MainActivity.EXTRA_LAST_DISCOVERED_TAG) + + artworksStorage = ArtworksStorage(context!!) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -226,17 +229,34 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific //// Log.i(TAG, "setCardVerify " + it.results!![0].passed) // } serverApiHelper!!.setCardVerifyAndGetArtworkListener { - card!!.isOnlineVerified = it.results!![0].passed srlLoadedWallet!!.isRefreshing = false - val result=it.results!![0] - if( artworksStorage.checkNeedUpdateArtwork(result.batch, result.artworkId, result.artworkHash, result.getUpdateDate() ) ) - { + val result = it.results!![0] + if (result.error != null) { + Log.e(TAG, "Can't verify card: ${result.error}") + card!!.isOnlineVerified = false + return@setCardVerifyAndGetArtworkListener + } + card!!.isOnlineVerified = result.passed + if (!result.passed) return@setCardVerifyAndGetArtworkListener + + if (artworksStorage.checkBatchArtworkChanged(result.batch, result.artworkId)) { + Log.w(TAG, "Batch ${result.batch} artwork changed to '${result.artworkId}'") + ivTangemCard.setImageBitmap(artworksStorage.getBatchBitmap(card!!.batch)) + } + if (artworksStorage.checkNeedUpdateArtwork(result.artworkId, result.artworkHash, result.getUpdateDate())) { + Log.w(TAG, "Artwork '${result.artworkId}' updated, need download") + serverApiHelper!!.requestArtwork(result.artworkId, result.getUpdateDate(), card!!) } // Log.i(TAG, "setCardVerify " + it.results!![0].passed) } + serverApiHelper!!.setArtworkListener { artworkId, inputStream, updateDate -> + Log.w(TAG, "Artwork '$artworkId' downloaded") + artworksStorage.updateArtwork(artworkId, inputStream, updateDate) + ivTangemCard.setImageBitmap(artworksStorage.getBatchBitmap(card!!.batch)) + } // request rate info listener serverApiHelper!!.setRateInfoData {