Search in sources :

Example 71 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class ShareViaAccountActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_manage_accounts);
    setSupportActionBar(findViewById(R.id.toolbar));
    configureActionBar(getSupportActionBar());
    accountListView = findViewById(R.id.account_list);
    this.mAccountAdapter = new AccountAdapter(this, accountList, false);
    accountListView.setAdapter(this.mAccountAdapter);
    accountListView.setOnItemClickListener((arg0, view, position, arg3) -> {
        final Account account = accountList.get(position);
        final String body = getIntent().getStringExtra(EXTRA_BODY);
        try {
            final Jid contact = Jid.of(getIntent().getStringExtra(EXTRA_CONTACT));
            final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, contact, false, false);
            switchToConversation(conversation, body);
        } catch (IllegalArgumentException e) {
        // ignore error
        }
        finish();
    });
}
Also used : Account(eu.siacs.conversations.entities.Account) Jid(eu.siacs.conversations.xmpp.Jid) Conversation(eu.siacs.conversations.entities.Conversation) AccountAdapter(eu.siacs.conversations.ui.adapter.AccountAdapter)

Example 72 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class PgpEngine method encrypt.

public void encrypt(final Message message, final UiCallback<Message> callback) {
    Intent params = new Intent();
    params.setAction(OpenPgpApi.ACTION_ENCRYPT);
    final Conversation conversation = (Conversation) message.getConversation();
    if (conversation.getMode() == Conversation.MODE_SINGLE) {
        long[] keys = { conversation.getContact().getPgpKeyId(), conversation.getAccount().getPgpId() };
        params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, keys);
    } else {
        params.putExtra(OpenPgpApi.EXTRA_KEY_IDS, conversation.getMucOptions().getPgpKeyIds());
    }
    if (!message.needsUploading()) {
        params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
        String body;
        if (message.hasFileOnRemoteHost()) {
            body = message.getFileParams().url;
        } else {
            body = message.getBody();
        }
        InputStream is = new ByteArrayInputStream(body.getBytes());
        final OutputStream os = new ByteArrayOutputStream();
        api.executeApiAsync(params, is, os, result -> {
            switch(result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
                case OpenPgpApi.RESULT_CODE_SUCCESS:
                    try {
                        os.flush();
                        final ArrayList<String> encryptedMessageBody = new ArrayList<>();
                        final String[] lines = os.toString().split("\n");
                        for (int i = 2; i < lines.length - 1; ++i) {
                            if (!lines[i].contains("Version")) {
                                encryptedMessageBody.add(lines[i].trim());
                            }
                        }
                        message.setEncryptedBody(Joiner.on('\n').join(encryptedMessageBody));
                        message.setEncryption(Message.ENCRYPTION_DECRYPTED);
                        mXmppConnectionService.sendMessage(message);
                        callback.success(message);
                    } catch (IOException e) {
                        callback.error(R.string.openpgp_error, message);
                    }
                    break;
                case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
                    callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message);
                    break;
                case OpenPgpApi.RESULT_CODE_ERROR:
                    OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
                    String errorMessage = error != null ? error.getMessage() : null;
                    @StringRes final int res;
                    if (errorMessage != null && errorMessage.startsWith("Bad key for encryption")) {
                        res = R.string.bad_key_for_encryption;
                    } else {
                        res = R.string.openpgp_error;
                    }
                    logError(conversation.getAccount(), error);
                    callback.error(res, message);
                    break;
            }
        });
    } else {
        try {
            DownloadableFile inputFile = this.mXmppConnectionService.getFileBackend().getFile(message, true);
            DownloadableFile outputFile = this.mXmppConnectionService.getFileBackend().getFile(message, false);
            outputFile.getParentFile().mkdirs();
            outputFile.createNewFile();
            final InputStream is = new FileInputStream(inputFile);
            final OutputStream os = new FileOutputStream(outputFile);
            api.executeApiAsync(params, is, os, result -> {
                switch(result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
                    case OpenPgpApi.RESULT_CODE_SUCCESS:
                        try {
                            os.flush();
                        } catch (IOException ignored) {
                        // ignored
                        }
                        FileBackend.close(os);
                        mXmppConnectionService.sendMessage(message);
                        callback.success(message);
                        break;
                    case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
                        callback.userInputRequired(result.getParcelableExtra(OpenPgpApi.RESULT_INTENT), message);
                        break;
                    case OpenPgpApi.RESULT_CODE_ERROR:
                        logError(conversation.getAccount(), result.getParcelableExtra(OpenPgpApi.RESULT_ERROR));
                        callback.error(R.string.openpgp_error, message);
                        break;
                }
            });
        } catch (final IOException e) {
            callback.error(R.string.openpgp_error, message);
        }
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) StringRes(androidx.annotation.StringRes) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) Conversation(eu.siacs.conversations.entities.Conversation) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileOutputStream(java.io.FileOutputStream) OpenPgpError(org.openintents.openpgp.OpenPgpError) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Example 73 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class RtpSessionActivity method switchToConversation.

private void switchToConversation() {
    final Contact contact = getWith();
    final Conversation conversation = xmppConnectionService.findOrCreateConversation(contact.getAccount(), contact.getJid(), false, true);
    switchToConversation(conversation);
}
Also used : Conversation(eu.siacs.conversations.entities.Conversation) Contact(eu.siacs.conversations.entities.Contact)

Example 74 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class RtpSessionActivity method recordVoiceMail.

private void recordVoiceMail(final View view) {
    final Intent intent = getIntent();
    final Account account = extractAccount(intent);
    final Jid with = Jid.ofEscaped(intent.getStringExtra(EXTRA_WITH));
    final Conversation conversation = xmppConnectionService.findOrCreateConversation(account, with, false, true);
    final Intent launchIntent = new Intent(this, ConversationsActivity.class);
    launchIntent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION);
    launchIntent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
    launchIntent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    launchIntent.putExtra(ConversationsActivity.EXTRA_POST_INIT_ACTION, ConversationsActivity.POST_ACTION_RECORD_VOICE);
    startActivity(launchIntent);
    finish();
}
Also used : Account(eu.siacs.conversations.entities.Account) Jid(eu.siacs.conversations.xmpp.Jid) Intent(android.content.Intent) Conversation(eu.siacs.conversations.entities.Conversation)

Example 75 with Conversation

use of eu.siacs.conversations.entities.Conversation in project Conversations by siacs.

the class MessageAdapter method getView.

@Override
public View getView(int position, View view, ViewGroup parent) {
    final Message message = getItem(position);
    final boolean omemoEncryption = message.getEncryption() == Message.ENCRYPTION_AXOLOTL;
    final boolean isInValidSession = message.isValidInSession() && (!omemoEncryption || message.isTrusted());
    final Conversational conversation = message.getConversation();
    final Account account = conversation.getAccount();
    final int type = getItemViewType(position);
    ViewHolder viewHolder;
    if (view == null) {
        viewHolder = new ViewHolder();
        switch(type) {
            case DATE_SEPARATOR:
                view = activity.getLayoutInflater().inflate(R.layout.message_date_bubble, parent, false);
                viewHolder.status_message = view.findViewById(R.id.message_body);
                viewHolder.message_box = view.findViewById(R.id.message_box);
                viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
                break;
            case RTP_SESSION:
                view = activity.getLayoutInflater().inflate(R.layout.message_rtp_session, parent, false);
                viewHolder.status_message = view.findViewById(R.id.message_body);
                viewHolder.message_box = view.findViewById(R.id.message_box);
                viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
                break;
            case SENT:
                view = activity.getLayoutInflater().inflate(R.layout.message_sent, parent, false);
                viewHolder.message_box = view.findViewById(R.id.message_box);
                viewHolder.contact_picture = view.findViewById(R.id.message_photo);
                viewHolder.download_button = view.findViewById(R.id.download_button);
                viewHolder.indicator = view.findViewById(R.id.security_indicator);
                viewHolder.edit_indicator = view.findViewById(R.id.edit_indicator);
                viewHolder.image = view.findViewById(R.id.message_image);
                viewHolder.messageBody = view.findViewById(R.id.message_body);
                viewHolder.time = view.findViewById(R.id.message_time);
                viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
                viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
                break;
            case RECEIVED:
                view = activity.getLayoutInflater().inflate(R.layout.message_received, parent, false);
                viewHolder.message_box = view.findViewById(R.id.message_box);
                viewHolder.contact_picture = view.findViewById(R.id.message_photo);
                viewHolder.download_button = view.findViewById(R.id.download_button);
                viewHolder.indicator = view.findViewById(R.id.security_indicator);
                viewHolder.edit_indicator = view.findViewById(R.id.edit_indicator);
                viewHolder.image = view.findViewById(R.id.message_image);
                viewHolder.messageBody = view.findViewById(R.id.message_body);
                viewHolder.time = view.findViewById(R.id.message_time);
                viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
                viewHolder.encryption = view.findViewById(R.id.message_encryption);
                viewHolder.audioPlayer = view.findViewById(R.id.audio_player);
                break;
            case STATUS:
                view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false);
                viewHolder.contact_picture = view.findViewById(R.id.message_photo);
                viewHolder.status_message = view.findViewById(R.id.status_message);
                viewHolder.load_more_messages = view.findViewById(R.id.load_more_messages);
                break;
            default:
                throw new AssertionError("Unknown view type");
        }
        view.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) view.getTag();
        if (viewHolder == null) {
            return view;
        }
    }
    boolean darkBackground = type == RECEIVED && (!isInValidSession || mUseGreenBackground) || activity.isDarkTheme();
    if (type == DATE_SEPARATOR) {
        if (UIHelper.today(message.getTimeSent())) {
            viewHolder.status_message.setText(R.string.today);
        } else if (UIHelper.yesterday(message.getTimeSent())) {
            viewHolder.status_message.setText(R.string.yesterday);
        } else {
            viewHolder.status_message.setText(DateUtils.formatDateTime(activity, message.getTimeSent(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
        }
        viewHolder.message_box.setBackgroundResource(activity.isDarkTheme() ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white);
        return view;
    } else if (type == RTP_SESSION) {
        final boolean isDarkTheme = activity.isDarkTheme();
        final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
        final RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody());
        final long duration = rtpSessionStatus.duration;
        if (received) {
            if (duration > 0) {
                viewHolder.status_message.setText(activity.getString(R.string.incoming_call_duration, TimeFrameUtils.resolve(activity, duration)));
            } else if (rtpSessionStatus.successful) {
                viewHolder.status_message.setText(R.string.incoming_call);
            } else {
                viewHolder.status_message.setText(activity.getString(R.string.missed_call_timestamp, UIHelper.readableTimeDifferenceFull(activity, message.getTimeSent())));
            }
        } else {
            if (duration > 0) {
                viewHolder.status_message.setText(activity.getString(R.string.outgoing_call_duration, TimeFrameUtils.resolve(activity, duration)));
            } else {
                viewHolder.status_message.setText(R.string.outgoing_call);
            }
        }
        viewHolder.indicatorReceived.setImageResource(RtpSessionStatus.getDrawable(received, rtpSessionStatus.successful, isDarkTheme));
        viewHolder.indicatorReceived.setAlpha(isDarkTheme ? 0.7f : 0.57f);
        viewHolder.message_box.setBackgroundResource(isDarkTheme ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white);
        return view;
    } else if (type == STATUS) {
        if ("LOAD_MORE".equals(message.getBody())) {
            viewHolder.status_message.setVisibility(View.GONE);
            viewHolder.contact_picture.setVisibility(View.GONE);
            viewHolder.load_more_messages.setVisibility(View.VISIBLE);
            viewHolder.load_more_messages.setOnClickListener(v -> loadMoreMessages((Conversation) message.getConversation()));
        } else {
            viewHolder.status_message.setVisibility(View.VISIBLE);
            viewHolder.load_more_messages.setVisibility(View.GONE);
            viewHolder.status_message.setText(message.getBody());
            boolean showAvatar;
            if (conversation.getMode() == Conversation.MODE_SINGLE) {
                showAvatar = true;
                AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message);
            } else if (message.getCounterpart() != null || message.getTrueCounterpart() != null || (message.getCounterparts() != null && message.getCounterparts().size() > 0)) {
                showAvatar = true;
                AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message);
            } else {
                showAvatar = false;
            }
            if (showAvatar) {
                viewHolder.contact_picture.setAlpha(0.5f);
                viewHolder.contact_picture.setVisibility(View.VISIBLE);
            } else {
                viewHolder.contact_picture.setVisibility(View.GONE);
            }
        }
        return view;
    } else {
        AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar);
    }
    resetClickListener(viewHolder.message_box, viewHolder.messageBody);
    viewHolder.contact_picture.setOnClickListener(v -> {
        if (MessageAdapter.this.mOnContactPictureClickedListener != null) {
            MessageAdapter.this.mOnContactPictureClickedListener.onContactPictureClicked(message);
        }
    });
    viewHolder.contact_picture.setOnLongClickListener(v -> {
        if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) {
            MessageAdapter.this.mOnContactPictureLongClickedListener.onContactPictureLongClicked(v, message);
            return true;
        } else {
            return false;
        }
    });
    final Transferable transferable = message.getTransferable();
    final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
    if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
        if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
            displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
        } else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) {
            displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
        } else {
            displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground);
        }
    } else if (message.isFileOrImage() && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) {
        if (message.getFileParams().width > 0 && message.getFileParams().height > 0) {
            displayMediaPreviewMessage(viewHolder, message, darkBackground);
        } else if (message.getFileParams().runtime > 0) {
            displayAudioMessage(viewHolder, message, darkBackground);
        } else {
            displayOpenableMessage(viewHolder, message, darkBackground);
        }
    } else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
        if (account.isPgpDecryptionServiceConnected()) {
            if (conversation instanceof Conversation && !account.hasPendingPgpIntent((Conversation) conversation)) {
                displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), darkBackground);
            } else {
                displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground);
            }
        } else {
            displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain), darkBackground);
            viewHolder.message_box.setOnClickListener(this::promptOpenKeychainInstall);
            viewHolder.messageBody.setOnClickListener(this::promptOpenKeychainInstall);
        }
    } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
        displayInfoMessage(viewHolder, activity.getString(R.string.decryption_failed), darkBackground);
    } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_NOT_FOR_THIS_DEVICE) {
        displayInfoMessage(viewHolder, activity.getString(R.string.not_encrypted_for_this_device), darkBackground);
    } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL_FAILED) {
        displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground);
    } else {
        if (message.isGeoUri()) {
            displayLocationMessage(viewHolder, message, darkBackground);
        } else if (message.bodyIsOnlyEmojis() && message.getType() != Message.TYPE_PRIVATE) {
            displayEmojiMessage(viewHolder, message.getBody().trim(), darkBackground);
        } else if (message.treatAsDownloadable()) {
            try {
                final URI uri = new URI(message.getBody());
                displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize_on_host, UIHelper.getFileDescriptionString(activity, message), uri.getHost()), darkBackground);
            } catch (Exception e) {
                displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
            }
        } else {
            displayTextMessage(viewHolder, message, darkBackground, type);
        }
    }
    if (type == RECEIVED) {
        if (isInValidSession) {
            int bubble;
            if (!mUseGreenBackground) {
                bubble = activity.getThemeResource(R.attr.message_bubble_received_monochrome, R.drawable.message_bubble_received_white);
            } else {
                bubble = activity.getThemeResource(R.attr.message_bubble_received_green, R.drawable.message_bubble_received);
            }
            viewHolder.message_box.setBackgroundResource(bubble);
            viewHolder.encryption.setVisibility(View.GONE);
        } else {
            viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning);
            viewHolder.encryption.setVisibility(View.VISIBLE);
            if (omemoEncryption && !message.isTrusted()) {
                viewHolder.encryption.setText(R.string.not_trusted);
            } else {
                viewHolder.encryption.setText(CryptoHelper.encryptionTypeToText(message.getEncryption()));
            }
        }
    }
    displayStatus(viewHolder, message, type, darkBackground);
    return view;
}
Also used : Conversational(eu.siacs.conversations.entities.Conversational) Account(eu.siacs.conversations.entities.Account) Message(eu.siacs.conversations.entities.Message) RtpSessionStatus(eu.siacs.conversations.entities.RtpSessionStatus) Transferable(eu.siacs.conversations.entities.Transferable) Conversation(eu.siacs.conversations.entities.Conversation) URI(java.net.URI)

Aggregations

Conversation (eu.siacs.conversations.entities.Conversation)110 Account (eu.siacs.conversations.entities.Account)27 Message (eu.siacs.conversations.entities.Message)24 Jid (eu.siacs.conversations.xmpp.Jid)22 Contact (eu.siacs.conversations.entities.Contact)17 MucOptions (eu.siacs.conversations.entities.MucOptions)10 Intent (android.content.Intent)9 Element (eu.siacs.conversations.xml.Element)9 PendingIntent (android.app.PendingIntent)8 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)8 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)8 Uri (android.net.Uri)7 Conversational (eu.siacs.conversations.entities.Conversational)7 InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)7 SuppressLint (android.annotation.SuppressLint)6 SpannableString (android.text.SpannableString)6 XmppConnection (eu.siacs.conversations.xmpp.XmppConnection)6 Jid (eu.siacs.conversations.xmpp.jid.Jid)6 ArrayList (java.util.ArrayList)6 Fragment (android.app.Fragment)4