Safepoint Check EMV
This commit is contained in:
parent
2ea0792d28
commit
f48e3e64a4
@ -98,47 +98,66 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
case EMV_FINAL_APP_SELECT:
|
||||
importFinalAppSelectStatus(0);
|
||||
break;
|
||||
|
||||
case EMV_APP_SELECT:
|
||||
String[] candiNames = (String[]) msg.obj;
|
||||
showAppSelectDialog(candiNames);
|
||||
break;
|
||||
|
||||
case EMV_CONFIRM_CARD_NO:
|
||||
// ✅ Tampilkan UI konfirmasi, JANGAN langsung import
|
||||
showCardNumberConfirmation();
|
||||
break;
|
||||
|
||||
case EMV_CERT_VERIFY:
|
||||
// ✅ Tampilkan UI sertifikat, JANGAN langsung import
|
||||
showCertificateVerification();
|
||||
break;
|
||||
|
||||
case EMV_SHOW_PIN_PAD:
|
||||
dismissLoadingDialog();
|
||||
android.util.Log.d(TAG, "Initializing PIN pad...");
|
||||
initPinPad();
|
||||
break;
|
||||
|
||||
case EMV_ONLINE_PROCESS:
|
||||
mockOnlineProcess();
|
||||
break;
|
||||
|
||||
case EMV_SIGNATURE:
|
||||
importSignatureStatus(0);
|
||||
break;
|
||||
|
||||
case PIN_CLICK_PIN:
|
||||
android.util.Log.d(TAG, "PIN input confirmed");
|
||||
importPinInputStatus(0);
|
||||
break;
|
||||
|
||||
case PIN_CLICK_CONFIRM:
|
||||
android.util.Log.d(TAG, "PIN confirm without input (bypass)");
|
||||
importPinInputStatus(2);
|
||||
break;
|
||||
|
||||
case PIN_CLICK_CANCEL:
|
||||
showToast("User cancelled PIN input");
|
||||
showToast("PIN input cancelled by user");
|
||||
importPinInputStatus(1);
|
||||
break;
|
||||
|
||||
case PIN_ERROR:
|
||||
showToast("PIN Error: " + msg.obj + " -- " + msg.arg1);
|
||||
android.util.Log.e(TAG, "PIN Error: " + msg.obj + " -- " + msg.arg1);
|
||||
showToast("PIN Error: " + msg.obj);
|
||||
importPinInputStatus(3);
|
||||
break;
|
||||
|
||||
case EMV_TRANS_FAIL:
|
||||
resetUI();
|
||||
showToast("Transaction failed: " + msg.obj + " -- " + msg.arg1);
|
||||
break;
|
||||
|
||||
case EMV_TRANS_SUCCESS:
|
||||
resetUI();
|
||||
getTlvData(); // Get complete card data
|
||||
showToast("Transaction successful: " + msg.obj + " -- " + msg.arg1);
|
||||
showToast("Transaction successful!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -382,22 +401,63 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void switchCheckCard() {
|
||||
android.util.Log.d(TAG, "switchCheckCard called, checkingCard: " + checkingCard);
|
||||
android.util.Log.d(TAG, "switchCheckCard called, mProcessStep: " + mProcessStep);
|
||||
|
||||
try {
|
||||
if (checkingCard) {
|
||||
android.util.Log.d(TAG, "Stopping card check");
|
||||
stopCardCheck();
|
||||
// Handle berbagai process steps
|
||||
if (mProcessStep == 0) {
|
||||
// Initial state - start/stop card scanning
|
||||
if (checkingCard) {
|
||||
android.util.Log.d(TAG, "Stopping card check");
|
||||
stopCardCheck();
|
||||
} else {
|
||||
android.util.Log.d(TAG, "Starting card check");
|
||||
startCardCheck();
|
||||
}
|
||||
} else if (mProcessStep == EMV_CONFIRM_CARD_NO) {
|
||||
// ✅ Handle card number confirmation
|
||||
android.util.Log.d(TAG, "User confirmed card number");
|
||||
showLoadingDialog("Processing card confirmation...");
|
||||
btnCheckCard.setText("Processing...");
|
||||
|
||||
// ✅ Import card number status dan reset process step
|
||||
importCardNoStatus(0);
|
||||
|
||||
} else if (mProcessStep == EMV_CERT_VERIFY) {
|
||||
// ✅ Handle certificate verification
|
||||
android.util.Log.d(TAG, "User confirmed certificate");
|
||||
showLoadingDialog("Processing certificate...");
|
||||
btnCheckCard.setText("Processing...");
|
||||
|
||||
// ✅ Import certificate status
|
||||
importCertStatus(0);
|
||||
|
||||
} else {
|
||||
android.util.Log.d(TAG, "Starting card check");
|
||||
startCardCheck();
|
||||
android.util.Log.w(TAG, "Unknown process step: " + mProcessStep);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
android.util.Log.e(TAG, "Error in switchCheckCard: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
updateUI("Error: " + e.getMessage(), false);
|
||||
resetUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void showLoadingDialog(String message) {
|
||||
runOnUiThread(() -> {
|
||||
if (tvResult != null) {
|
||||
tvResult.setText(message + "...");
|
||||
}
|
||||
android.util.Log.d(TAG, "Loading: " + message);
|
||||
});
|
||||
}
|
||||
|
||||
private void dismissLoadingDialog() {
|
||||
// Method ini bisa kosong atau implement actual dialog dismissal
|
||||
android.util.Log.d(TAG, "Loading dismissed");
|
||||
}
|
||||
|
||||
private void startCardCheck() {
|
||||
try {
|
||||
if (isEMVMode) {
|
||||
@ -860,22 +920,38 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void showCardNumberConfirmation() {
|
||||
tvResult.setText("Card Number: " + maskCardNumber(mCardNo) + "\n\nPlease confirm card number");
|
||||
btnCheckCard.setText("Confirm");
|
||||
btnCheckCard.setOnClickListener(v -> {
|
||||
importCardNoStatus(0);
|
||||
btnCheckCard.setText("Processing...");
|
||||
btnCheckCard.setOnClickListener(null);
|
||||
runOnUiThread(() -> {
|
||||
dismissLoadingDialog(); // Pastikan loading dialog ditutup
|
||||
|
||||
String displayText = "Card Number: " + maskCardNumber(mCardNo) +
|
||||
"\n\nPlease confirm this card number to continue";
|
||||
tvResult.setText(displayText);
|
||||
|
||||
// ✅ HANYA ubah text button, JANGAN ubah listener
|
||||
btnCheckCard.setText("Confirm Card Number");
|
||||
|
||||
// ✅ Set process step untuk onClick handler
|
||||
mProcessStep = EMV_CONFIRM_CARD_NO;
|
||||
|
||||
android.util.Log.d(TAG, "Card number confirmation UI updated, waiting for user input");
|
||||
});
|
||||
}
|
||||
|
||||
private void showCertificateVerification() {
|
||||
tvResult.setText("Certificate Info: " + mCertInfo + "\n\nPlease confirm certificate");
|
||||
btnCheckCard.setText("Confirm");
|
||||
btnCheckCard.setOnClickListener(v -> {
|
||||
importCertStatus(0);
|
||||
btnCheckCard.setText("Processing...");
|
||||
btnCheckCard.setOnClickListener(null);
|
||||
runOnUiThread(() -> {
|
||||
dismissLoadingDialog();
|
||||
|
||||
String displayText = "Certificate Information:\n" + mCertInfo +
|
||||
"\n\nPlease confirm certificate to continue";
|
||||
tvResult.setText(displayText);
|
||||
|
||||
// ✅ HANYA ubah text button
|
||||
btnCheckCard.setText("Confirm Certificate");
|
||||
|
||||
// ✅ Set process step
|
||||
mProcessStep = EMV_CERT_VERIFY;
|
||||
|
||||
android.util.Log.d(TAG, "Certificate verification UI updated, waiting for user input");
|
||||
});
|
||||
}
|
||||
|
||||
@ -1437,61 +1513,115 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
|
||||
// ====== PIN PAD METHODS ======
|
||||
private void initPinPad() {
|
||||
android.util.Log.e(TAG, "========== PIN PAD INITIALIZATION ==========");
|
||||
try {
|
||||
// Validate components
|
||||
if (mPinPadOptV2 == null) {
|
||||
throw new IllegalStateException("PIN Pad service not available");
|
||||
}
|
||||
|
||||
// Validate card number
|
||||
if (mCardNo == null || mCardNo.length() < 13) {
|
||||
throw new IllegalArgumentException("Invalid card number for PIN");
|
||||
}
|
||||
|
||||
PinPadConfigV2 pinPadConfig = new PinPadConfigV2();
|
||||
pinPadConfig.setPinPadType(0);
|
||||
pinPadConfig.setPinType(mPinType);
|
||||
pinPadConfig.setOrderNumKey(false);
|
||||
byte[] panBytes = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1).getBytes("US-ASCII");
|
||||
pinPadConfig.setPan(panBytes);
|
||||
pinPadConfig.setTimeout(60 * 1000);
|
||||
pinPadConfig.setPinKeyIndex(12);
|
||||
pinPadConfig.setMaxInput(12);
|
||||
pinPadConfig.setMinInput(0);
|
||||
pinPadConfig.setKeySystem(0);
|
||||
pinPadConfig.setAlgorithmType(0);
|
||||
|
||||
// Use the correct PAN format (last 12 digits excluding check digit)
|
||||
String panForPin = mCardNo.substring(mCardNo.length() - 13, mCardNo.length() - 1);
|
||||
byte[] panBytes = panForPin.getBytes("US-ASCII");
|
||||
pinPadConfig.setPan(panBytes);
|
||||
|
||||
pinPadConfig.setTimeout(60 * 1000);
|
||||
pinPadConfig.setPinKeyIndex(12); // Make sure this matches your key index
|
||||
pinPadConfig.setMaxInput(12);
|
||||
pinPadConfig.setMinInput(0); // Allow bypass
|
||||
pinPadConfig.setKeySystem(0); // 0 = international, 1 = domestic
|
||||
pinPadConfig.setAlgorithmType(0); // 0 = 3DES, 1 = SM4
|
||||
|
||||
// Update UI
|
||||
runOnUiThread(() -> {
|
||||
updateUI("PIN Input Required\n\nPIN pad is ready\nPlease enter your PIN on the device", false);
|
||||
btnCheckCard.setText("PIN Pad Active");
|
||||
btnCheckCard.setEnabled(false);
|
||||
});
|
||||
|
||||
// Initialize PIN pad
|
||||
mPinPadOptV2.initPinPad(pinPadConfig, mPinPadListener);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
mHandler.obtainMessage(PIN_ERROR, Integer.MIN_VALUE, Integer.MIN_VALUE, "initPinPad() failure").sendToTarget();
|
||||
android.util.Log.e(TAG, "PIN pad initialization failed: " + e.getMessage());
|
||||
mHandler.obtainMessage(PIN_ERROR, -1, -1,
|
||||
"PIN Error: " + e.getMessage()).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private final PinPadListenerV2 mPinPadListener = new PinPadListenerV2.Stub() {
|
||||
@Override
|
||||
public void onPinLength(int len) {
|
||||
android.util.Log.d(TAG, "onPinLength:" + len);
|
||||
mHandler.obtainMessage(PIN_CLICK_NUMBER, len).sendToTarget();
|
||||
public void onPinLength(int len) throws RemoteException {
|
||||
android.util.Log.d(TAG, "PIN input length: " + len);
|
||||
runOnUiThread(() -> {
|
||||
String dots = "";
|
||||
for (int i = 0; i < len; i++) {
|
||||
dots += "• ";
|
||||
}
|
||||
tvResult.setText("PIN Input: " + dots + "\n\nEntering PIN... (" + len + " digits)");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirm(int i, byte[] pinBlock) {
|
||||
public void onConfirm(int i, byte[] pinBlock) throws RemoteException {
|
||||
android.util.Log.d(TAG, "PIN input confirmed");
|
||||
|
||||
runOnUiThread(() -> {
|
||||
btnCheckCard.setEnabled(true);
|
||||
btnCheckCard.setText("Processing...");
|
||||
tvResult.setText("PIN confirmed, processing...");
|
||||
});
|
||||
|
||||
if (pinBlock != null) {
|
||||
String hexStr = ByteUtil.bytes2HexStr(pinBlock);
|
||||
android.util.Log.d(TAG, "onConfirm pin block:" + hexStr);
|
||||
android.util.Log.d(TAG, "PIN block received: " + hexStr);
|
||||
mHandler.obtainMessage(PIN_CLICK_PIN, pinBlock).sendToTarget();
|
||||
} else {
|
||||
android.util.Log.d(TAG, "PIN bypass confirmed");
|
||||
mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
android.util.Log.d(TAG, "onCancel");
|
||||
public void onCancel() throws RemoteException {
|
||||
android.util.Log.d(TAG, "PIN input cancelled by user");
|
||||
|
||||
runOnUiThread(() -> {
|
||||
btnCheckCard.setEnabled(true);
|
||||
btnCheckCard.setText("Start Scanning");
|
||||
tvResult.setText("PIN input cancelled");
|
||||
});
|
||||
|
||||
mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int code) {
|
||||
android.util.Log.e(TAG, "onError:" + code);
|
||||
public void onError(int code) throws RemoteException {
|
||||
android.util.Log.e(TAG, "PIN pad error: " + code);
|
||||
String msg = AidlErrorCodeV2.valueOf(code).getMsg();
|
||||
|
||||
runOnUiThread(() -> {
|
||||
btnCheckCard.setEnabled(true);
|
||||
btnCheckCard.setText("Start Scanning");
|
||||
tvResult.setText("PIN error: " + msg);
|
||||
});
|
||||
|
||||
mHandler.obtainMessage(PIN_ERROR, code, code, msg).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHover(int event, byte[] data) throws RemoteException {
|
||||
android.util.Log.d(TAG, "onHover(), event:" + event + ", data:" + ByteUtil.bytes2HexStr(data));
|
||||
android.util.Log.d(TAG, "PIN pad hover event: " + event);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1543,9 +1673,12 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
|
||||
private void resetUI() {
|
||||
runOnUiThread(() -> {
|
||||
mProcessStep = 0;
|
||||
mProcessStep = 0; // ✅ Reset process step ke initial state
|
||||
btnCheckCard.setText("Start Scanning");
|
||||
|
||||
// ✅ Reset click listener ke original method
|
||||
btnCheckCard.setOnClickListener(v -> switchCheckCard());
|
||||
|
||||
dismissAppSelectDialog();
|
||||
updateModeDisplay();
|
||||
|
||||
@ -1556,6 +1689,8 @@ public class CreditCardActivity extends AppCompatActivity {
|
||||
if (btnClearData != null) {
|
||||
btnClearData.setVisibility(android.view.View.GONE);
|
||||
}
|
||||
|
||||
android.util.Log.d(TAG, "UI reset to initial state");
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user