diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 55f9bc1ade..7b0b31b8ba 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/build.gradle b/app/build.gradle index 8e6dd8de35..c427d23465 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,8 +50,8 @@ dependencies { implementation 'com.android.support:cardview-v7:27.1.1' implementation 'com.android.support:support-v4:27.1.1' implementation 'com.google.zxing:core:3.3.2' - implementation 'com.google.dagger:dagger:2.13' - annotationProcessor 'com.google.dagger:dagger-compiler:2.13' +// implementation 'com.google.dagger:dagger:2.13' +// annotationProcessor 'com.google.dagger:dagger-compiler:2.13' implementation 'com.madgag.spongycastle:core:1.56.0.0' implementation 'com.madgag.spongycastle:prov:1.56.0.0' implementation 'com.scottyab:rootbeer-lib:0.0.6' @@ -61,7 +61,8 @@ dependencies { implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'info.hoang8f:android-segmented:1.0.6' implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.android.volley:volley:1.1.0' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +// androidTestImplementation 'com.android.support.test:runner:1.0.2' +// androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/AppController.java b/app/src/main/java/com/tangem/AppController.java index 67a16b238b..08fe6ab7a2 100644 --- a/app/src/main/java/com/tangem/AppController.java +++ b/app/src/main/java/com/tangem/AppController.java @@ -2,9 +2,21 @@ package com.tangem; import android.app.Application; import android.support.v7.app.AppCompatDelegate; +import android.text.TextUtils; + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.VolleyLog; +import com.android.volley.toolbox.Volley; public class AppController extends Application { - private static final String TAG = "." + AppController.class.getSimpleName(); + + public static final String TAG = "fragment." + AppController.class.getSimpleName(); + + /** + * Global request queue for Volley + */ + private RequestQueue mRequestQueue; /** * A singleton instance of the application class for easy access in other places @@ -22,20 +34,64 @@ public class AppController extends Application { @Override public void onCreate() { super.onCreate(); - // init the singleton + // initialize the singleton sInstance = this; } /** - * @return singleton instance + * @return SeoPult singleton instance */ public static synchronized AppController getInstance() { return sInstance; } - @Override - public void onTerminate() { - super.onTerminate(); + /** + * @return The Volley Request queue, the queue will be created if it is null + */ + public RequestQueue getRequestQueue() { + // lazy initialize the request queue, the queue instance will be created when it is accessed for the first time + if (mRequestQueue == null) + mRequestQueue = Volley.newRequestQueue(getApplicationContext()); + + return mRequestQueue; + } + + /** + * Adds the specified request to the global queue, if tag is specified + * then it is used else Default TAG is used. + * + * @param req + * @param tag + */ + public void addToRequestQueue(Request req, String tag) { + // set the default tag if tag is empty + req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); + VolleyLog.d("Adding request to queue: %s", req.getUrl()); + getRequestQueue().add(req); + } + + /** + * Adds the specified request to the global queue using the Default TAG. + * + * @param req + */ + public void addToRequestQueue(Request req) { + // set the default tag if tag is empty + req.setTag(TAG); + + getRequestQueue().add(req); + } + + /** + * Cancels all pending requests by the specified TAG, it is important + * to specify a TAG so that the pending/ongoing requests can be cancelled. + * + * @param tag + */ + public void cancelPendingRequests(Object tag) { + if (mRequestQueue != null) { + mRequestQueue.cancelAll(tag); + } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/DI/AppComponent.java b/app/src/main/java/com/tangem/DI/AppComponent.java deleted file mode 100644 index abc8d6ad21..0000000000 --- a/app/src/main/java/com/tangem/DI/AppComponent.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.DI; - -import com.tangem.AppController; - -import javax.inject.Singleton; - -import dagger.Component; - -@Singleton -@Component(modules = {AppModule.class}) -public interface AppComponent { - - void inject(AppController appController); - -} diff --git a/app/src/main/java/com/tangem/DI/AppModule.java b/app/src/main/java/com/tangem/DI/AppModule.java deleted file mode 100644 index 45b6c7a682..0000000000 --- a/app/src/main/java/com/tangem/DI/AppModule.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.DI; - -import dagger.Module; - -@Module -public class AppModule { - -} diff --git a/app/src/main/java/com/tangem/DI/NfcManagerComponent.java b/app/src/main/java/com/tangem/DI/NfcManagerComponent.java deleted file mode 100644 index 786586c6b5..0000000000 --- a/app/src/main/java/com/tangem/DI/NfcManagerComponent.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.DI; - -import com.tangem.domain.cardReader.NfcManager; - -//@Component -public interface NfcManagerComponent { -// NfcManager getNfcManager(Activity activity, NfcAdapter.ReaderCallback readerCallback); - NfcManager getNfcManager(); - -} diff --git a/app/src/main/java/com/tangem/data/network/Server.java b/app/src/main/java/com/tangem/data/network/Server.java new file mode 100644 index 0000000000..c19c11c167 --- /dev/null +++ b/app/src/main/java/com/tangem/data/network/Server.java @@ -0,0 +1,29 @@ +package com.tangem.data.network; + +import java.util.HashMap; +import java.util.Map; + +public class Server { + + public static Map getHeader() { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + return headers; + } + + public static class API { + private static final String URL_TANGEM = ServerURL.API_TANGEM; + + public static class Method { + /** + * https://tangem-webapp.appspot.com/ + */ + public static final String INFO_VERIFY = URL_TANGEM + "info/version"; + + public static final String CARD_VERIFY = URL_TANGEM + "card/verify"; + public static final String CARD_VALIDATE = URL_TANGEM + "card/validate"; + public static final String CARD_ACTIVATE = URL_TANGEM + "card/activate"; + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/data/network/ServerURL.java b/app/src/main/java/com/tangem/data/network/ServerURL.java new file mode 100644 index 0000000000..ef4e5957e9 --- /dev/null +++ b/app/src/main/java/com/tangem/data/network/ServerURL.java @@ -0,0 +1,11 @@ +package com.tangem.data.network; + +public class ServerURL { + public static final String API_TANGEM = "https://tangem-webapp.appspot.com/"; + +} + + + + + diff --git a/app/src/main/java/com/tangem/data/network/VolleyHelper.kt b/app/src/main/java/com/tangem/data/network/VolleyHelper.kt new file mode 100644 index 0000000000..003d129677 --- /dev/null +++ b/app/src/main/java/com/tangem/data/network/VolleyHelper.kt @@ -0,0 +1,54 @@ +package com.tangem.data.network + +import android.content.Context +import android.content.Intent +import android.support.v7.app.AlertDialog +import com.android.volley.AuthFailureError +import com.android.volley.DefaultRetryPolicy +import com.android.volley.Request +import com.android.volley.toolbox.StringRequest +import com.google.gson.GsonBuilder +import com.google.gson.JsonParser +import com.tangem.AppController +import com.tangem.wallet.R + +class VolleyHelper { + + fun doRequest(context: Context, url: String, params: Map) { + val stringRequest = object : StringRequest(Request.Method.POST, url, + { response -> + val data = GsonBuilder().setPrettyPrinting().create().toJson(JsonParser().parse(response)) + val builder = AlertDialog.Builder(context) + builder.setTitle("sxsx") + .setMessage(data) + .setPositiveButton(R.string.ok, null) + .setNeutralButton(R.string.send) { _, _ -> + val intent = Intent(Intent.ACTION_SEND) + intent.type = "text/html" + intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("digest2003@mail.ru")) + intent.putExtra(Intent.EXTRA_SUBJECT, url) + intent.putExtra(Intent.EXTRA_TEXT, data) + context.startActivity(Intent.createChooser(intent, "Send gson")) + } + val alert = builder.create() + alert.show() + }, + { error -> val networkResponse = error.networkResponse }) { + + + @Throws(AuthFailureError::class) + override fun getHeaders(): Map { + return Server.getHeader() + } + + @Throws(AuthFailureError::class) + override fun getParams(): Map { + return params + } + } + + stringRequest.retryPolicy = DefaultRetryPolicy(60000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT) + AppController.getInstance().addToRequestQueue(stringRequest) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/data/network/request/VerificationServerProtocol.java b/app/src/main/java/com/tangem/data/network/request/VerificationServerProtocol.java index 0b008ac56d..fb44ee170b 100644 --- a/app/src/main/java/com/tangem/data/network/request/VerificationServerProtocol.java +++ b/app/src/main/java/com/tangem/data/network/request/VerificationServerProtocol.java @@ -22,20 +22,19 @@ import java.util.Locale; public class VerificationServerProtocol { - public static class Request - { - public Request(CustomCommand command, Class answerClass) - { - this.command=command; - this.answerClass=answerClass; + public static class Request { + public Request(CustomCommand command, Class answerClass) { + this.command = command; + this.answerClass = answerClass; } + public String error; public CustomCommand command; public CustomAnswer answer; public Type answerClass; public void doPost(String hostURL) throws IOException { - URL url = new URL(hostURL+"/"+command.getURL()); + URL url = new URL(hostURL + "/" + command.getURL()); URLConnection con = url.openConnection(); HttpURLConnection http = (HttpURLConnection) con; try { @@ -60,8 +59,7 @@ public class VerificationServerProtocol { answer = getGson().fromJson(br, answerClass); } } - } - finally { + } finally { http.disconnect(); } } @@ -70,8 +68,7 @@ public class VerificationServerProtocol { static abstract class CustomCommand { public abstract String getURL(); - public byte[] toBytes() - { + public byte[] toBytes() { return getGson().toJson(this).getBytes(StandardCharsets.UTF_8); } @@ -121,15 +118,14 @@ public class VerificationServerProtocol { public ResultItem[] results; } - public static Request prepare(TangemCard card) - { - Command c=new Command(); - c.requests=new RequestItem[1]; - c.requests[0]=new RequestItem(); - c.requests[0].CID=Util.bytesToHex(card.getCID()); - c.requests[0].publicKey=Util.bytesToHex(card.getCardPublicKey()); + public static Request prepare(TangemCard card) { + Command c = new Command(); + c.requests = new RequestItem[1]; + c.requests[0] = new RequestItem(); + c.requests[0].CID = Util.bytesToHex(card.getCID()); + c.requests[0].publicKey = Util.bytesToHex(card.getCardPublicKey()); - return new Request(c,Answer.class); + return new Request(c, Answer.class); } } @@ -154,6 +150,7 @@ public class VerificationServerProtocol { public ResultItem(RequestItem request) { CID = request.CID; } + public String error; public String CID; public Integer previousCounter; @@ -164,14 +161,13 @@ public class VerificationServerProtocol { public ResultItem[] results; } - public Request prepare(TangemCard card, int ValidationCounter, byte[] ValidationSignature) - { - Command c=new Command(); - c.requests=new RequestItem[1]; - c.requests[0].CID= Util.bytesToHex(card.getCID()); - c.requests[0].counter=ValidationCounter; - c.requests[0].signature=Util.bytesToHex(ValidationSignature); - return new Request(new Command(),Answer.class); + public Request prepare(TangemCard card, int ValidationCounter, byte[] ValidationSignature) { + Command c = new Command(); + c.requests = new RequestItem[1]; + c.requests[0].CID = Util.bytesToHex(card.getCID()); + c.requests[0].counter = ValidationCounter; + c.requests[0].signature = Util.bytesToHex(ValidationSignature); + return new Request(new Command(), Answer.class); } } diff --git a/app/src/main/java/com/tangem/data/network/task/VerificationServerTask.java b/app/src/main/java/com/tangem/data/network/task/VerificationServerTask.java index 6e83e322ac..f7bc34a080 100644 --- a/app/src/main/java/com/tangem/data/network/task/VerificationServerTask.java +++ b/app/src/main/java/com/tangem/data/network/task/VerificationServerTask.java @@ -8,35 +8,34 @@ import java.util.ArrayList; import java.util.List; public class VerificationServerTask extends AsyncTask> { - public static final String hostURL ="https://tangem-webapp.appspot.com"; + public static final String hostURL = "https://tangem-webapp.appspot.com"; - public VerificationServerTask() { - - } - - protected List doInBackground(VerificationServerProtocol.Request... requests) { - List result = new ArrayList<>(); - for (int i = 0; i < requests.length; i++) { - result.add(requests[i]); - } - - for (VerificationServerProtocol.Request request : result) { - try { - request.doPost(hostURL); - } catch (Exception e) { - request.error = e.getMessage(); - if( request.error==null || request.error.isEmpty() ) - { - request.error = e.getClass().getName(); - } - } - } - - return result; - } - - public String getValidationNodeDescription() { - return hostURL; - } + public VerificationServerTask() { } + + protected List doInBackground(VerificationServerProtocol.Request... requests) { + List result = new ArrayList<>(); + for (int i = 0; i < requests.length; i++) { + result.add(requests[i]); + } + + for (VerificationServerProtocol.Request request : result) { + try { + request.doPost(hostURL); + } catch (Exception e) { + request.error = e.getMessage(); + if (request.error == null || request.error.isEmpty()) { + request.error = e.getClass().getName(); + } + } + } + + return result; + } + + public String getValidationNodeDescription() { + return hostURL; + } + +} diff --git a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java index b19f5b80fd..486c2a8db1 100644 --- a/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java +++ b/app/src/main/java/com/tangem/presentation/fragment/LoadedWallet.java @@ -30,6 +30,8 @@ import android.widget.TextView; import android.widget.Toast; import com.google.zxing.WriterException; +import com.tangem.data.network.Server; +import com.tangem.data.network.VolleyHelper; import com.tangem.data.network.request.ElectrumRequest; import com.tangem.data.network.request.ExchangeRequest; import com.tangem.data.network.request.InfuraRequest; @@ -63,7 +65,9 @@ import com.tangem.util.Util; import com.tangem.util.UtilHelper; import com.tangem.wallet.R; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Timer; import java.util.TimerTask; @@ -88,21 +92,23 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre public SwipeRefreshLayout mSwipeRefreshLayout; private RelativeLayout rlProgressBar; - private TextView tvCardID, tvBalance, tvBalanceLine1, tvBalanceLine2,tvOffline, tvBalanceEquivalent, tvWallet, tvInputs, tvError, tvMessage, tvIssuer, tvBlockchain, tvValidationNode, tvHeader, tvCaution; -// private ProgressBar progressBar; + private TextView tvCardID, tvBalance, tvBalanceLine1, tvBalanceLine2, tvOffline, tvBalanceEquivalent, tvWallet, tvInputs, tvError, tvMessage, tvIssuer, tvBlockchain, tvValidationNode, tvHeader, tvCaution; + // private ProgressBar progressBar; private ImageView ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion; private AppCompatButton btnExtract; -// public List updateTasks = new ArrayList<>(); + // public List updateTasks = new ArrayList<>(); private boolean lastReadSuccess = true; private VerifyCardTask verifyCardTask = null; private int requestPIN2Count = 0; private Timer timerHideErrorAndMessage = null; private String newPIN = "", newPIN2 = ""; private CardProtocol mCardProtocol; -// private int scanTimes = 0; + // private int scanTimes = 0; OnlineVerifyTask onlineVerifyTask; + private static final String URL_CARD_VALIDATE = Server.API.Method.CARD_VALIDATE; + public LoadedWallet() { } @@ -122,7 +128,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre super.onPostExecute(requests); // Log.i("OnlineVerifyTask", "onPostExecute[" + String.valueOf(updateTasks.size()) + "]"); // updateTasks.remove(this); - onlineVerifyTask=null; + onlineVerifyTask = null; for (VerificationServerProtocol.Request request : requests) { if (request.error == null) { @@ -139,10 +145,18 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre } } // if (updateTasks.size() == 0) - mSwipeRefreshLayout.setRefreshing(false); + mSwipeRefreshLayout.setRefreshing(false); } } + private void requestCardValidate() { + Map params = new HashMap<>(); + params.put("Content-Type", "application/json"); + params.put("CID", Util.bytesToHex(mCard.getCID())); + params.put("publicKey", Util.bytesToHex(mCard.getCardPublicKey())); + new VolleyHelper().doRequest(getContext(), URL_CARD_VALIDATE, params); + } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -153,6 +167,8 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre mCard.LoadFromBundle(Objects.requireNonNull(getActivity().getIntent().getExtras()).getBundle(TangemCard.EXTRA_CARD)); lastTag = getActivity().getIntent().getParcelableExtra(Main.EXTRA_LAST_DISCOVERED_TAG); + +// requestCardValidate(); } @Override @@ -215,7 +231,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre mSwipeRefreshLayout.postDelayed(this::onRefresh, 1000); } - if ( (mCard.isOnlineVerified()==null || !mCard.isOnlineVerified()) && onlineVerifyTask ==null) { + if ((mCard.isOnlineVerified() == null || !mCard.isOnlineVerified()) && onlineVerifyTask == null) { onlineVerifyTask = new OnlineVerifyTask(); // updateTasks.add(onlineVerifyTask); onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard)); @@ -508,7 +524,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain()); - if ( (mCard.isOnlineVerified()==null || !mCard.isOnlineVerified()) && onlineVerifyTask ==null) { + if ((mCard.isOnlineVerified() == null || !mCard.isOnlineVerified()) && onlineVerifyTask == null) { onlineVerifyTask = new OnlineVerifyTask(); // updateTasks.add(onlineVerifyTask); onlineVerifyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, VerificationServerProtocol.Verify.prepare(mCard)); @@ -547,7 +563,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre String nodeAddress = Objects.requireNonNull(engine).GetNode(mCard); int nodePort = engine.GetNodePort(mCard); - UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(LoadedWallet.this,nodeAddress, nodePort, data); + UpdateWalletInfoTask updateWalletInfoTask = new UpdateWalletInfoTask(LoadedWallet.this, nodeAddress, nodePort, data); // updateTasks.add(updateWalletInfoTask); updateWalletInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.ListUnspent(mCard.getWallet()) @@ -608,7 +624,6 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre } - public Intent prepareResultIntent() { Intent data = new Intent(); data.putExtra("UID", mCard.getUID()); @@ -750,7 +765,7 @@ public class LoadedWallet extends Fragment implements SwipeRefreshLayout.OnRefre validator.Check(mCard); tvBalanceLine1.setText(validator.GetFirstLine()); tvBalanceLine2.setText(validator.GetSecondLine()); - tvBalanceLine1.setTextColor(ContextCompat.getColor(Objects.requireNonNull(getContext()),validator.GetColor())); + tvBalanceLine1.setTextColor(ContextCompat.getColor(Objects.requireNonNull(getContext()), validator.GetColor())); } if (engine.HasBalanceInfo(mCard) || mCard.getOfflineBalance() == null) { diff --git a/app/src/main/java/com/tangem/util/Util.java b/app/src/main/java/com/tangem/util/Util.java index 7bf0fd2132..08ffe3eced 100644 --- a/app/src/main/java/com/tangem/util/Util.java +++ b/app/src/main/java/com/tangem/util/Util.java @@ -243,7 +243,7 @@ public class Util { } //This prints all non-control characters common to all parts of ISO/IEC 8859 - //See EMV book 4 Annex B: Table 36: Common Character Set + //See EMV book 4 Annex B: Table 36: VolleyHelper Character Set public static String getSafePrintChars(byte[] byteArray) { if (byteArray == null) { return "";