Updated on 2026-08-14

This commit is contained in:
Tangem 2018-05-29 16:11:22 +03:00
parent 8c17a8d4f0
commit b19c306250
70 changed files with 6149 additions and 6206 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,362 @@
package com.tangem.presentation.fragment;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class VerifyCardActivityFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener, NfcAdapter.ReaderCallback {
Tangem_Card mCard;
TextView tvCardID, tvManufacturer, tvRegistrationDate, tvCardIdentity, tvLastSigned, tvRemainingSignatures, tvReusable, tvOk, tvError, tvMessage,
tvIssuer, tvIssuerData, tvFeatures, tvBlockchain, tvSignedTx, tvSigningMethod, tvFirmware, tvWalletIdentity, tvWallet;
ImageView ivBlockchain, ivPIN, ivPIN2orSecurityDelay, ivDeveloperVersion;
SwipeRefreshLayout mSwipeRefreshLayout;
private NfcManager mNfcManager;
public VerifyCardActivityFragment() {
}
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_verify_card, container, false);
mNfcManager = new NfcManager(this.getActivity(), this);
// SwipeRefreshLayout
mSwipeRefreshLayout = v.findViewById(R.id.swipe_container);
mSwipeRefreshLayout.setOnRefreshListener(this);
mCard = new Tangem_Card(getActivity().getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getActivity().getIntent().getExtras().getBundle("Card"));
tvCardID = v.findViewById(R.id.tvCardID);
tvLastSigned = v.findViewById(R.id.tvLastSigned);
tvRemainingSignatures = v.findViewById(R.id.tvRemainingSignatures);
tvReusable = v.findViewById(R.id.tvReusable);
tvManufacturer = v.findViewById(R.id.tvManufacturerInfo);
tvCardIdentity = v.findViewById(R.id.tvCardIdentity);
tvRegistrationDate = v.findViewById(R.id.tvCardRegistredDate);
ivBlockchain = v.findViewById(R.id.imgBlockchain);
ivPIN = v.findViewById(R.id.imgPIN);
ivPIN2orSecurityDelay = v.findViewById(R.id.imgPIN2orSecurityDelay);
ivDeveloperVersion = v.findViewById(R.id.imgDeveloperVersion);
tvError = v.findViewById(R.id.tvError);
tvMessage = v.findViewById(R.id.tvMessage);
tvIssuer = v.findViewById(R.id.tvIssuer);
tvIssuerData = v.findViewById(R.id.tvIssuerData);
tvFirmware = v.findViewById(R.id.tvFirmware);
tvFeatures = v.findViewById(R.id.tvFeatures);
tvBlockchain = v.findViewById(R.id.tvBlockchain);
tvSignedTx = v.findViewById(R.id.tvSignedTx);
tvSigningMethod = v.findViewById(R.id.tvSigningMethod);
tvOk = v.findViewById(R.id.tvOk);
if (tvOk != null) {
tvOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent data = prepareResultIntent();
data.putExtra("modification", "update");
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
});
}
tvWallet = v.findViewById(R.id.tvWallet);
tvWalletIdentity = v.findViewById(R.id.tvWalletIdentity);
UpdateViews();
// if (NeedUpdate) {
// mSwipeRefreshLayout.setRefreshing(true);
// mSwipeRefreshLayout.postDelayed(new Runnable() {
// @Override
// public void run() {
// onRefresh();
// }
// }, 1000);
// }
return v;
}
void UpdateViews() {
try {
if (timerHideErrorAndMessage != null) {
timerHideErrorAndMessage.cancel();
timerHideErrorAndMessage = null;
}
tvCardID.setText(mCard.getCIDDescription());
if (mCard.getError() == null || mCard.getError().isEmpty()) {
tvError.setVisibility(View.GONE);
tvError.setText("");
} else {
tvError.setVisibility(View.VISIBLE);
tvError.setText(mCard.getError());
}
if (mCard.getMessage() == null || mCard.getMessage().isEmpty()) {
tvMessage.setVisibility(View.GONE);
tvMessage.setText("");
} else {
tvMessage.setVisibility(View.VISIBLE);
tvMessage.setText(mCard.getMessage());
}
tvManufacturer.setText(mCard.getManufacturer().getOfficialName());
if (mCard.isManufacturerConfirmed() && mCard.isCardPublicKeyValid()) {
tvCardIdentity.setText("Attested");
tvCardIdentity.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
} else {
tvCardIdentity.setText("Not confirmed");
tvCardIdentity.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
}
tvIssuer.setText(mCard.getIssuerDescription());
tvIssuerData.setText(mCard.getIssuerDataDescription());
tvRegistrationDate.setText(mCard.getPersonalizationDateTimeDescription());
//tvBlockchain.setText(mCard.getBlockchain().getOfficialName());
tvBlockchain.setText(mCard.getBlockchainName());
ivBlockchain.setImageResource(mCard.getBlockchain().getImageResource(this.getContext(), mCard.getTokenSymbol()));
if (mCard.isReusable()) {
tvReusable.setText("Reusable");
} else {
tvReusable.setText("One-off banknote");
}
tvSigningMethod.setText(mCard.getSigningMethod().getDescription());
if (mCard.getStatus() == Tangem_Card.Status.Loaded || mCard.getStatus() == Tangem_Card.Status.Purged) {
tvLastSigned.setText(mCard.getLastSignedDescription());
if (mCard.getRemainingSignatures() == 0) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("None");
} else if (mCard.getRemainingSignatures() == 1) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("Last one!");
} else if (mCard.getRemainingSignatures() > 1000) {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText("Unlimited");
} else {
tvRemainingSignatures.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
tvRemainingSignatures.setText(String.valueOf(mCard.getRemainingSignatures()));
}
tvSignedTx.setText(String.valueOf(mCard.getMaxSignatures() - mCard.getRemainingSignatures()));
} else {
tvLastSigned.setText("");
tvRemainingSignatures.setText("");
tvSignedTx.setText("");
}
tvFirmware.setText(mCard.getFirmwareVersion());
String features = "";
if (mCard.allowSwapPIN() && mCard.allowSwapPIN2()) {
features += "Allows change PIN1 and PIN2\n";
} else if (mCard.allowSwapPIN()) {
features += "Allows change PIN1\n";
} else if (mCard.allowSwapPIN2()) {
features += "Allows change PIN2\n";
} else {
features += "Fixed PIN1 and PIN2\n";
}
if (mCard.needCVC()) {
features += "Requires CVC\n";
}
if (mCard.supportDynamicNDEF()) {
features += "Dynamic NDEF for iOS\n";
} else if (mCard.supportNDEF()) {
features += "NDEF\n";
}
if (mCard.supportBlock()) {
features += "Blockable\n";
}
if (mCard.supportOnlyOneCommandAtTime()) {
features += "Atomic command mode";
}
if (features.endsWith("\n")) {
features = features.substring(0, features.length() - 1);
}
tvFeatures.setText(features);
if (mCard.useDefaultPIN1()) {
ivPIN.setImageResource(R.drawable.unlock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by default PIN1 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN.setImageResource(R.drawable.lock_pin1);
ivPIN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by user's PIN1 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.getPauseBeforePIN2() > 0 && (mCard.useDefaultPIN2() || !mCard.useSmartSecurityDelay())) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.timer);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), String.format("This banknote will enforce %.0f seconds security delay for all operations requiring PIN2 code", mCard.getPauseBeforePIN2() / 1000.0), Toast.LENGTH_LONG).show();
}
});
} else if (mCard.useDefaultPIN2()) {
ivPIN2orSecurityDelay.setImageResource(R.drawable.unlock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by default PIN2 code", Toast.LENGTH_LONG).show();
}
});
} else {
ivPIN2orSecurityDelay.setImageResource(R.drawable.lock_pin2);
ivPIN2orSecurityDelay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "This banknote is protected by user's PIN2 code", Toast.LENGTH_LONG).show();
}
});
}
if (mCard.useDevelopersFirmware()) {
ivDeveloperVersion.setImageResource(R.drawable.ic_developer_version);
ivDeveloperVersion.setVisibility(View.VISIBLE);
ivDeveloperVersion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "Unlocked banknote, only for development use", Toast.LENGTH_LONG).show();
}
});
} else {
ivDeveloperVersion.setVisibility(View.INVISIBLE);
}
if (mCard.getStatus() == Tangem_Card.Status.Loaded) {
tvWallet.setText(mCard.getShortWalletString());
if (mCard.isWalletPublicKeyValid()) {
tvWalletIdentity.setText("Possession proved");
tvWalletIdentity.setTextColor(getResources().getColor(R.color.confirmed, getActivity().getTheme()));
} else {
tvWalletIdentity.setText("Possession NOT proved");
tvWalletIdentity.setTextColor(getResources().getColor(R.color.not_confirmed, getActivity().getTheme()));
}
} else {
tvWallet.setText("not available");
tvWalletIdentity.setText("-- -- --");
}
timerHideErrorAndMessage = new Timer();
timerHideErrorAndMessage.schedule(new TimerTask() {
@Override
public void run() {
tvError.post(new Runnable() {
@Override
public void run() {
tvMessage.setVisibility(View.GONE);
tvError.setVisibility(View.GONE);
mCard.setError(null);
mCard.setMessage(null);
}
});
}
}, 5000);
} catch (Exception e) {
e.printStackTrace();
}
}
Timer timerHideErrorAndMessage = null;
public Intent prepareResultIntent() {
Intent data = new Intent();
data.putExtra("UID", mCard.getUID());
data.putExtra("Card", mCard.getAsBundle());
return data;
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
@Override
public void onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(), "Ignore discovered tag!");
mNfcManager.IgnoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,152 @@
package com.tangem.presentation.fragment;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.tangem.wallet.R;
import com.tangem.wallet.Tangem_Card;
import java.util.Hashtable;
import static android.content.Context.CLIPBOARD_SERVICE;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link WalletInfoFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class WalletInfoFragment extends Fragment {
// TODO: Rename and change types of parameters
private Tangem_Card mCard;
private OnFragmentInteractionListener mListener;
public WalletInfoFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @return A new instance of fragment WalletInfoFragment.
*/
// TODO: Rename and change types and number of parameters
public static WalletInfoFragment newInstance(Tangem_Card card) {
WalletInfoFragment fragment = new WalletInfoFragment();
Bundle args = new Bundle();
args.putString("UID",card.getUID());
card.SaveToBundle(args);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mCard = new Tangem_Card(getArguments().getString("UID"));
mCard.LoadFromBundle(getArguments());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View result=inflater.inflate(R.layout.fragment_wallet_info, container, false);
ImageView mImage= (ImageView)result.findViewById(R.id.qrWallet);
try {
mImage.setImageBitmap(generateQrCode(mCard.getWallet()));
} catch (WriterException e) {
e.printStackTrace();
}
TextView mText=(TextView)result.findViewById(R.id.strWallet);
mText.setText(mCard.getWallet());
mText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TextView mText = (TextView) view;
ClipboardManager clipboard = (ClipboardManager)getActivity().getSystemService(CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText(mText.getText(), mText.getText()));
Toast.makeText(getContext(),"Copied to clipboard",Toast.LENGTH_LONG).show();
}
});
return result;
}
public static Bitmap generateQrCode(String myCodeText) throws WriterException {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // H = 30% damage
QRCodeWriter qrCodeWriter = new QRCodeWriter();
int size = 256;
BitMatrix bitMatrix = qrCodeWriter.encode(myCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
int width = bitMatrix.getWidth();
Bitmap bmp = Bitmap.createBitmap(width, width, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
bmp.setPixel(y, x, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
return bmp;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
// void onFragmentInteraction(Uri uri);
}
}