Search in sources :

Example 16 with DialogBuilder

use of de.schildbach.wallet.ui.DialogBuilder in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method sendPayment.

private void sendPayment(final SendRequest sendRequest, final Coin finalAmount) {
    final Wallet wallet = walletActivityViewModel.wallet.getValue();
    new SendCoinsOfflineTask(wallet, backgroundHandler) {

        @Override
        protected void onSuccess(final Transaction transaction) {
            viewModel.sentTransaction.setValue(transaction);
            setState(SendCoinsViewModel.State.SENDING);
            final Address refundAddress = viewModel.paymentIntent.standard == Standard.BIP70 ? wallet.freshAddress(KeyPurpose.REFUND) : null;
            final Payment payment = PaymentProtocol.createPaymentMessage(Collections.singletonList(transaction), finalAmount, refundAddress, null, viewModel.paymentIntent.payeeData);
            if (directPaymentEnableView.isChecked())
                directPay(payment);
            final ListenableFuture<Transaction> future = walletActivityViewModel.broadcastTransaction(transaction);
            future.addListener(() -> {
                // Auto-close the dialog after a short delay
                if (config.getSendCoinsAutoclose())
                    handler.postDelayed(() -> activity.finish(), Constants.AUTOCLOSE_DELAY_MS);
            }, Threading.THREAD_POOL);
            final ComponentName callingActivity = activity.getCallingActivity();
            if (callingActivity != null) {
                log.info("returning result to calling activity: {}", callingActivity.flattenToString());
                final Intent result = new Intent();
                BitcoinIntegration.transactionHashToResult(result, transaction.getTxId().toString());
                if (viewModel.paymentIntent.standard == Standard.BIP70)
                    BitcoinIntegration.paymentToResult(result, payment.toByteArray());
                activity.setResult(Activity.RESULT_OK, result);
            }
        }

        private void directPay(final Payment payment) {
            final DirectPaymentTask.ResultCallback callback = new DirectPaymentTask.ResultCallback() {

                @Override
                public void onResult(final boolean ack) {
                    viewModel.directPaymentAck = ack;
                    if (viewModel.state == SendCoinsViewModel.State.SENDING)
                        setState(SendCoinsViewModel.State.SENT);
                    updateView();
                }

                @Override
                public void onFail(final int messageResId, final Object... messageArgs) {
                    final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_direct_payment_failed_title, viewModel.paymentIntent.paymentUrl + "\n" + getString(messageResId, messageArgs) + "\n\n" + getString(R.string.send_coins_fragment_direct_payment_failed_msg));
                    dialog.setPositiveButton(R.string.button_retry, (d, which) -> directPay(payment));
                    dialog.setNegativeButton(R.string.button_dismiss, null);
                    dialog.show();
                }
            };
            if (viewModel.paymentIntent.isHttpPaymentUrl()) {
                new DirectPaymentTask.HttpPaymentTask(backgroundHandler, callback, viewModel.paymentIntent.paymentUrl, application.httpUserAgent()).send(payment);
            } else if (viewModel.paymentIntent.isBluetoothPaymentUrl() && bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
                new DirectPaymentTask.BluetoothPaymentTask(backgroundHandler, callback, bluetoothAdapter, Bluetooth.getBluetoothMac(viewModel.paymentIntent.paymentUrl)).send(payment);
            }
        }

        @Override
        protected void onInsufficientMoney(final Coin missing) {
            setState(SendCoinsViewModel.State.INPUT);
            final Coin estimated = wallet.getBalance(BalanceType.ESTIMATED);
            final Coin available = wallet.getBalance(BalanceType.AVAILABLE);
            final Coin pending = estimated.subtract(available);
            final MonetaryFormat btcFormat = config.getFormat();
            final StringBuilder msg = new StringBuilder();
            msg.append(getString(R.string.send_coins_fragment_insufficient_money_msg1, btcFormat.format(missing)));
            if (pending.signum() > 0)
                msg.append("\n\n").append(getString(R.string.send_coins_fragment_pending, btcFormat.format(pending)));
            if (viewModel.paymentIntent.mayEditAmount())
                msg.append("\n\n").append(getString(R.string.send_coins_fragment_insufficient_money_msg2));
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_insufficient_money_title, msg);
            if (viewModel.paymentIntent.mayEditAmount()) {
                dialog.setPositiveButton(R.string.send_coins_options_empty, (d, which) -> handleEmpty());
                dialog.setNegativeButton(R.string.button_cancel, null);
            } else {
                dialog.setNeutralButton(R.string.button_dismiss, null);
            }
            dialog.show();
        }

        @Override
        protected void onInvalidEncryptionKey() {
            setState(SendCoinsViewModel.State.INPUT);
            privateKeyBadPasswordView.setVisibility(View.VISIBLE);
            privateKeyPasswordView.requestFocus();
        }

        @Override
        protected void onEmptyWalletFailed() {
            setState(SendCoinsViewModel.State.INPUT);
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_empty_wallet_failed_title, R.string.send_coins_fragment_hint_empty_wallet_failed);
            dialog.setNeutralButton(R.string.button_dismiss, null);
            dialog.show();
        }

        @Override
        protected void onFailure(Exception exception) {
            setState(SendCoinsViewModel.State.FAILED);
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_error_msg, exception.toString());
            dialog.setNeutralButton(R.string.button_dismiss, null);
            dialog.show();
        }
    }.sendCoinsOffline(// send asynchronously
    sendRequest);
}
Also used : Bundle(android.os.Bundle) Transaction(org.bitcoinj.core.Transaction) PackageManager(android.content.pm.PackageManager) Coin(org.bitcoinj.core.Coin) Uri(android.net.Uri) LoggerFactory(org.slf4j.LoggerFactory) ScanActivity(de.schildbach.wallet.ui.scan.ScanActivity) AbstractWalletActivityViewModel(de.schildbach.wallet.ui.AbstractWalletActivityViewModel) Process(android.os.Process) BlockchainState(de.schildbach.wallet.service.BlockchainState) OnFocusChangeListener(android.view.View.OnFocusChangeListener) CheckBox(android.widget.CheckBox) ContentResolver(android.content.ContentResolver) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) PaymentProtocol(org.bitcoinj.protocols.payments.PaymentProtocol) SendRequest(org.bitcoinj.wallet.SendRequest) Handler(android.os.Handler) Map(java.util.Map) Fragment(androidx.fragment.app.Fragment) View(android.view.View) Button(android.widget.Button) R(de.schildbach.wallet.R) AdapterView(android.widget.AdapterView) Configuration(de.schildbach.wallet.Configuration) NdefMessage(android.nfc.NdefMessage) Constants(de.schildbach.wallet.Constants) WalletUtils(de.schildbach.wallet.util.WalletUtils) AddressFormatException(org.bitcoinj.core.AddressFormatException) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) BalanceType(org.bitcoinj.wallet.Wallet.BalanceType) BinaryInputParser(de.schildbach.wallet.ui.InputParser.BinaryInputParser) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) ViewGroup(android.view.ViewGroup) BitcoinIntegration(de.schildbach.wallet.integration.android.BitcoinIntegration) FileNotFoundException(java.io.FileNotFoundException) List(java.util.List) TextView(android.widget.TextView) Nullable(androidx.annotation.Nullable) StreamInputParser(de.schildbach.wallet.ui.InputParser.StreamInputParser) TransactionsAdapter(de.schildbach.wallet.ui.TransactionsAdapter) Address(org.bitcoinj.core.Address) DustySendRequested(org.bitcoinj.wallet.Wallet.DustySendRequested) NfcAdapter(android.nfc.NfcAdapter) AddressAndLabel(de.schildbach.wallet.ui.AddressAndLabel) TextWatcher(android.text.TextWatcher) Joiner(com.google.common.base.Joiner) KeyPurpose(org.bitcoinj.wallet.KeyChain.KeyPurpose) Context(android.content.Context) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) CurrencyAmountView(de.schildbach.wallet.ui.CurrencyAmountView) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Wallet(org.bitcoinj.wallet.Wallet) Filter(android.widget.Filter) Intent(android.content.Intent) Editable(android.text.Editable) MenuItem(android.view.MenuItem) AnimationUtils(android.view.animation.AnimationUtils) ProgressDialogFragment(de.schildbach.wallet.ui.ProgressDialogFragment) VerificationException(org.bitcoinj.core.VerificationException) Nfc(de.schildbach.wallet.util.Nfc) MenuInflater(android.view.MenuInflater) Menu(android.view.Menu) LinkedList(java.util.LinkedList) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) DialogInterface(android.content.DialogInterface) FragmentManager(androidx.fragment.app.FragmentManager) Logger(org.slf4j.Logger) BluetoothAdapter(android.bluetooth.BluetoothAdapter) ViewModelProvider(androidx.lifecycle.ViewModelProvider) ComponentName(android.content.ComponentName) LayoutInflater(android.view.LayoutInflater) Payment(org.bitcoin.protocols.payments.Protos.Payment) Bluetooth(de.schildbach.wallet.util.Bluetooth) CouldNotAdjustDownwards(org.bitcoinj.wallet.Wallet.CouldNotAdjustDownwards) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) AutoCompleteTextView(android.widget.AutoCompleteTextView) CurrencyCalculatorLink(de.schildbach.wallet.ui.CurrencyCalculatorLink) Threading(org.bitcoinj.utils.Threading) AddressBookDao(de.schildbach.wallet.addressbook.AddressBookDao) ArrayAdapter(android.widget.ArrayAdapter) AbstractWalletActivity(de.schildbach.wallet.ui.AbstractWalletActivity) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) HandlerThread(android.os.HandlerThread) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) WalletApplication(de.schildbach.wallet.WalletApplication) DirectPaymentTask(de.schildbach.wallet.offline.DirectPaymentTask) Activity(android.app.Activity) Collections(java.util.Collections) EditText(android.widget.EditText) AddressBookDatabase(de.schildbach.wallet.addressbook.AddressBookDatabase) Standard(de.schildbach.wallet.data.PaymentIntent.Standard) InputStream(java.io.InputStream) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Address(org.bitcoinj.core.Address) Wallet(org.bitcoinj.wallet.Wallet) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) Intent(android.content.Intent) DirectPaymentTask(de.schildbach.wallet.offline.DirectPaymentTask) AddressFormatException(org.bitcoinj.core.AddressFormatException) FileNotFoundException(java.io.FileNotFoundException) VerificationException(org.bitcoinj.core.VerificationException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) Coin(org.bitcoinj.core.Coin) Payment(org.bitcoin.protocols.payments.Protos.Payment) Transaction(org.bitcoinj.core.Transaction) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ComponentName(android.content.ComponentName) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder)

Example 17 with DialogBuilder

use of de.schildbach.wallet.ui.DialogBuilder in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method initStateFromBitcoinUri.

private void initStateFromBitcoinUri(final Uri bitcoinUri) {
    final String input = bitcoinUri.toString();
    new StringInputParser(input) {

        @Override
        protected void handlePaymentIntent(final PaymentIntent paymentIntent) {
            updateStateFrom(paymentIntent);
        }

        @Override
        protected void handlePrivateKey(final PrefixedChecksummedBytes key) {
            throw new UnsupportedOperationException();
        }

        @Override
        protected void handleDirectTransaction(final Transaction transaction) throws VerificationException {
            throw new UnsupportedOperationException();
        }

        @Override
        protected void error(final int messageResId, final Object... messageArgs) {
            final DialogBuilder dialog = DialogBuilder.dialog(activity, 0, messageResId, messageArgs);
            dialog.singleDismissButton(activityDismissListener);
            dialog.show();
        }
    }.parse();
}
Also used : PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) Transaction(org.bitcoinj.core.Transaction) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) VerificationException(org.bitcoinj.core.VerificationException) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder)

Example 18 with DialogBuilder

use of de.schildbach.wallet.ui.DialogBuilder in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method requestPaymentRequest.

private void requestPaymentRequest() {
    final String paymentRequestHost;
    if (!Bluetooth.isBluetoothUrl(viewModel.paymentIntent.paymentRequestUrl))
        paymentRequestHost = Uri.parse(viewModel.paymentIntent.paymentRequestUrl).getHost();
    else
        paymentRequestHost = Bluetooth.decompressMac(Bluetooth.getBluetoothMac(viewModel.paymentIntent.paymentRequestUrl));
    viewModel.progress.setValue(getString(R.string.send_coins_fragment_request_payment_request_progress, paymentRequestHost));
    setState(SendCoinsViewModel.State.REQUEST_PAYMENT_REQUEST);
    final RequestPaymentRequestTask.ResultCallback callback = new RequestPaymentRequestTask.ResultCallback() {

        @Override
        public void onPaymentIntent(final PaymentIntent paymentIntent) {
            viewModel.progress.setValue(null);
            if (viewModel.paymentIntent.isExtendedBy(paymentIntent)) {
                // success
                setState(SendCoinsViewModel.State.INPUT);
                updateStateFrom(paymentIntent);
                updateView();
                handler.post(dryrunRunnable);
            } else {
                final List<String> reasons = new LinkedList<>();
                if (!viewModel.paymentIntent.equalsAddress(paymentIntent))
                    reasons.add("address");
                if (!viewModel.paymentIntent.equalsAmount(paymentIntent))
                    reasons.add("amount");
                if (reasons.isEmpty())
                    reasons.add("unknown");
                final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_request_payment_request_failed_title, R.string.send_coins_fragment_request_payment_request_failed_message, paymentRequestHost, Joiner.on(", ").join(reasons));
                dialog.singleDismissButton((d, which) -> handleCancel());
                dialog.show();
                log.info("BIP72 trust check failed: {}", reasons);
            }
        }

        @Override
        public void onFail(final int messageResId, final Object... messageArgs) {
            viewModel.progress.setValue(null);
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_request_payment_request_failed_title, messageResId, messageArgs);
            dialog.setPositiveButton(R.string.button_retry, (d, which) -> requestPaymentRequest());
            dialog.setNegativeButton(R.string.button_dismiss, (d, which) -> {
                if (!viewModel.paymentIntent.hasOutputs())
                    handleCancel();
                else
                    setState(SendCoinsViewModel.State.INPUT);
            });
            dialog.show();
        }
    };
    if (!Bluetooth.isBluetoothUrl(viewModel.paymentIntent.paymentRequestUrl))
        new RequestPaymentRequestTask.HttpRequestTask(backgroundHandler, callback, application.httpUserAgent()).requestPaymentRequest(viewModel.paymentIntent.paymentRequestUrl);
    else
        new RequestPaymentRequestTask.BluetoothRequestTask(backgroundHandler, callback, bluetoothAdapter).requestPaymentRequest(viewModel.paymentIntent.paymentRequestUrl);
}
Also used : PaymentIntent(de.schildbach.wallet.data.PaymentIntent) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) LinkedList(java.util.LinkedList)

Example 19 with DialogBuilder

use of de.schildbach.wallet.ui.DialogBuilder in project bitcoin-wallet by bitcoin-wallet.

the class MaintenanceDialogFragment method onCreateDialog.

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
    final View view = LayoutInflater.from(activity).inflate(R.layout.maintenance_dialog, null);
    Coin value = Coin.ZERO;
    Coin fee = Coin.ZERO;
    for (final Transaction tx : determineMaintenanceTransactions()) {
        value = value.add(tx.getValueSentFromMe(wallet));
        fee = fee.add(tx.getFee());
    }
    final TextView messageView = view.findViewById(R.id.maintenance_dialog_message);
    final MonetaryFormat format = application.getConfiguration().getFormat();
    messageView.setText(getString(R.string.maintenance_dialog_message, format.format(value), format.format(fee)));
    passwordGroup = view.findViewById(R.id.maintenance_dialog_password_group);
    passwordView = view.findViewById(R.id.maintenance_dialog_password);
    passwordView.setText(null);
    badPasswordView = view.findViewById(R.id.maintenance_dialog_bad_password);
    final DialogBuilder builder = DialogBuilder.custom(activity, R.string.maintenance_dialog_title, view);
    // dummies, just to make buttons show
    builder.setPositiveButton(R.string.maintenance_dialog_button_move, null);
    builder.setNegativeButton(R.string.button_dismiss, null);
    builder.setCancelable(false);
    final AlertDialog dialog = builder.create();
    dialog.setCanceledOnTouchOutside(false);
    dialog.setOnShowListener(d -> {
        positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
        negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        positiveButton.setTypeface(Typeface.DEFAULT_BOLD);
        positiveButton.setOnClickListener(v -> {
            log.info("user decided to do maintenance");
            handleGo();
        });
        negativeButton.setOnClickListener(v -> {
            log.info("user decided to dismiss");
            dismissAllowingStateLoss();
        });
        passwordView.addTextChangedListener(textWatcher);
        MaintenanceDialogFragment.this.dialog = dialog;
        updateView();
    });
    log.info("showing maintenance dialog");
    return dialog;
}
Also used : AlertDialog(android.app.AlertDialog) Coin(org.bitcoinj.core.Coin) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Transaction(org.bitcoinj.core.Transaction) TextView(android.widget.TextView) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) View(android.view.View) TextView(android.widget.TextView)

Example 20 with DialogBuilder

use of de.schildbach.wallet.ui.DialogBuilder in project bitcoin-wallet by bitcoin-wallet.

the class RaiseFeeDialogFragment method onCreateDialog.

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
    final View view = LayoutInflater.from(activity).inflate(R.layout.raise_fee_dialog, null);
    messageView = view.findViewById(R.id.raise_fee_dialog_message);
    passwordGroup = view.findViewById(R.id.raise_fee_dialog_password_group);
    passwordView = view.findViewById(R.id.raise_fee_dialog_password);
    passwordView.setText(null);
    badPasswordView = view.findViewById(R.id.raise_fee_dialog_bad_password);
    final DialogBuilder builder = DialogBuilder.custom(activity, R.string.raise_fee_dialog_title, view);
    // dummies, just to make buttons show
    builder.setPositiveButton(R.string.raise_fee_dialog_button_raise, null);
    builder.setNegativeButton(R.string.button_dismiss, null);
    builder.setCancelable(false);
    final AlertDialog dialog = builder.create();
    dialog.setCanceledOnTouchOutside(false);
    dialog.setOnShowListener(d -> {
        positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
        negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        positiveButton.setTypeface(Typeface.DEFAULT_BOLD);
        positiveButton.setOnClickListener(v -> handleGo());
        negativeButton.setOnClickListener(v -> dismissAllowingStateLoss());
        passwordView.addTextChangedListener(textWatcher);
        RaiseFeeDialogFragment.this.dialog = dialog;
        updateView();
    });
    log.info("showing raise fee dialog");
    return dialog;
}
Also used : AlertDialog(android.app.AlertDialog) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) View(android.view.View) TextView(android.widget.TextView)

Aggregations

DialogBuilder (de.schildbach.wallet.ui.DialogBuilder)20 DialogInterface (android.content.DialogInterface)8 View (android.view.View)8 OnClickListener (android.content.DialogInterface.OnClickListener)7 PaymentIntent (de.schildbach.wallet.data.PaymentIntent)7 TextView (android.widget.TextView)6 AlertDialog (android.app.AlertDialog)5 Transaction (org.bitcoinj.core.Transaction)5 StringInputParser (de.schildbach.wallet.ui.InputParser.StringInputParser)4 IOException (java.io.IOException)4 InputStream (java.io.InputStream)4 Coin (org.bitcoinj.core.Coin)4 VerificationException (org.bitcoinj.core.VerificationException)4 MonetaryFormat (org.bitcoinj.utils.MonetaryFormat)4 Wallet (org.bitcoinj.wallet.Wallet)4 FileInputStream (java.io.FileInputStream)3 Activity (android.app.Activity)2 Context (android.content.Context)2 Intent (android.content.Intent)2 PackageManager (android.content.pm.PackageManager)2