diff --git a/app/src/main/java/com/example/bdkipoc/kredit/CreditCardActivity.java b/app/src/main/java/com/example/bdkipoc/kredit/CreditCardActivity.java index 2df7feb..d91f3bf 100644 --- a/app/src/main/java/com/example/bdkipoc/kredit/CreditCardActivity.java +++ b/app/src/main/java/com/example/bdkipoc/kredit/CreditCardActivity.java @@ -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"); }); }