Search in sources :

Example 31 with SettableFuture

use of org.thoughtcrime.securesms.util.concurrent.SettableFuture in project Signal-Android by WhisperSystems.

the class ConversationParentFragment method initializeDraftFromDatabase.

private ListenableFuture<Boolean> initializeDraftFromDatabase() {
    SettableFuture<Boolean> future = new SettableFuture<>();
    final Context context = requireContext().getApplicationContext();
    new AsyncTask<Void, Void, Pair<Drafts, CharSequence>>() {

        @Override
        protected Pair<Drafts, CharSequence> doInBackground(Void... params) {
            DraftDatabase draftDatabase = SignalDatabase.drafts();
            Drafts results = draftDatabase.getDrafts(threadId);
            Draft mentionsDraft = results.getDraftOfType(Draft.MENTION);
            Spannable updatedText = null;
            if (mentionsDraft != null) {
                String text = results.getDraftOfType(Draft.TEXT).getValue();
                List<Mention> mentions = MentionUtil.bodyRangeListToMentions(context, Base64.decodeOrThrow(mentionsDraft.getValue()));
                UpdatedBodyAndMentions updated = MentionUtil.updateBodyAndMentionsWithDisplayNames(context, text, mentions);
                updatedText = new SpannableString(updated.getBody());
                MentionAnnotation.setMentionAnnotations(updatedText, updated.getMentions());
            }
            draftDatabase.clearDrafts(threadId);
            return new Pair<>(results, updatedText);
        }

        @Override
        protected void onPostExecute(Pair<Drafts, CharSequence> draftsWithUpdatedMentions) {
            Drafts drafts = Objects.requireNonNull(draftsWithUpdatedMentions.first());
            CharSequence updatedText = draftsWithUpdatedMentions.second();
            if (drafts.isEmpty()) {
                future.set(false);
                updateToggleButtonState();
                return;
            }
            AtomicInteger draftsRemaining = new AtomicInteger(drafts.size());
            AtomicBoolean success = new AtomicBoolean(false);
            ListenableFuture.Listener<Boolean> listener = new AssertedSuccessListener<Boolean>() {

                @Override
                public void onSuccess(Boolean result) {
                    success.compareAndSet(false, result);
                    if (draftsRemaining.decrementAndGet() <= 0) {
                        future.set(success.get());
                    }
                }
            };
            for (Draft draft : drafts) {
                try {
                    switch(draft.getType()) {
                        case Draft.TEXT:
                            composeText.setText(updatedText == null ? draft.getValue() : updatedText);
                            listener.onSuccess(true);
                            break;
                        case Draft.LOCATION:
                            attachmentManager.setLocation(SignalPlace.deserialize(draft.getValue()), getCurrentMediaConstraints()).addListener(listener);
                            break;
                        case Draft.IMAGE:
                            setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE).addListener(listener);
                            break;
                        case Draft.AUDIO:
                            setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO).addListener(listener);
                            break;
                        case Draft.VIDEO:
                            setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO).addListener(listener);
                            break;
                        case Draft.QUOTE:
                            SettableFuture<Boolean> quoteResult = new SettableFuture<>();
                            new QuoteRestorationTask(draft.getValue(), quoteResult).execute();
                            quoteResult.addListener(listener);
                            break;
                        case Draft.VOICE_NOTE:
                            draftViewModel.setVoiceNoteDraft(recipient.getId(), draft);
                            break;
                    }
                } catch (IOException e) {
                    Log.w(TAG, e);
                }
            }
            updateToggleButtonState();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    return future;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) EmojiEventListener(org.thoughtcrime.securesms.components.emoji.EmojiEventListener) OnFocusChangeListener(android.view.View.OnFocusChangeListener) OnKeyListener(android.view.View.OnKeyListener) StickerEventListener(org.thoughtcrime.securesms.stickers.StickerEventListener) AssertedSuccessListener(org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener) OnKeyboardShownListener(org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener) OnClickListener(android.view.View.OnClickListener) DraftDatabase(org.thoughtcrime.securesms.database.DraftDatabase) SpannableString(android.text.SpannableString) ArrayList(java.util.ArrayList) IdentityRecordList(org.thoughtcrime.securesms.database.identity.IdentityRecordList) List(java.util.List) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Pair(org.whispersystems.libsignal.util.Pair) Context(android.content.Context) UpdatedBodyAndMentions(org.thoughtcrime.securesms.database.MentionUtil.UpdatedBodyAndMentions) IOException(java.io.IOException) Drafts(org.thoughtcrime.securesms.database.DraftDatabase.Drafts) SpannableString(android.text.SpannableString) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VoiceNoteDraft(org.thoughtcrime.securesms.components.voice.VoiceNoteDraft) Draft(org.thoughtcrime.securesms.database.DraftDatabase.Draft) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Spannable(android.text.Spannable)

Example 32 with SettableFuture

use of org.thoughtcrime.securesms.util.concurrent.SettableFuture in project Signal-Android by WhisperSystems.

the class ConversationParentFragment method initializeDraft.

// /// Initializers
private ListenableFuture<Boolean> initializeDraft(@NonNull ConversationIntents.Args args) {
    final SettableFuture<Boolean> result = new SettableFuture<>();
    final CharSequence draftText = args.getDraftText();
    final Uri draftMedia = requireActivity().getIntent().getData();
    final String draftContentType = requireActivity().getIntent().getType();
    final MediaType draftMediaType = MediaType.from(draftContentType);
    final List<Media> mediaList = args.getMedia();
    final StickerLocator stickerLocator = args.getStickerLocator();
    final boolean borderless = args.isBorderless();
    if (stickerLocator != null && draftMedia != null) {
        Log.d(TAG, "Handling shared sticker.");
        sendSticker(stickerLocator, Objects.requireNonNull(draftContentType), draftMedia, 0, true);
        return new SettableFuture<>(false);
    }
    if (draftMedia != null && draftContentType != null && borderless) {
        SimpleTask.run(getLifecycle(), () -> getKeyboardImageDetails(draftMedia), details -> sendKeyboardImage(draftMedia, draftContentType, details));
        return new SettableFuture<>(false);
    }
    if (!Util.isEmpty(mediaList)) {
        Log.d(TAG, "Handling shared Media.");
        Intent sendIntent = MediaSelectionActivity.editor(requireContext(), sendButton.getSelectedTransport(), mediaList, recipient.getId(), draftText);
        startActivityForResult(sendIntent, MEDIA_SENDER);
        return new SettableFuture<>(false);
    }
    if (draftText != null) {
        composeText.setText("");
        composeText.append(draftText);
        result.set(true);
    }
    if (draftMedia != null && draftMediaType != null) {
        Log.d(TAG, "Handling shared Data.");
        return setMedia(draftMedia, draftMediaType);
    }
    if (draftText == null && draftMedia == null && draftMediaType == null) {
        return initializeDraftFromDatabase();
    } else {
        updateToggleButtonState();
        result.set(false);
    }
    return result;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) Media(org.thoughtcrime.securesms.mediasend.Media) StickerLocator(org.thoughtcrime.securesms.stickers.StickerLocator) MediaType(org.thoughtcrime.securesms.mms.SlideFactory.MediaType) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) SpannableString(android.text.SpannableString) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Uri(android.net.Uri)

Example 33 with SettableFuture

use of org.thoughtcrime.securesms.util.concurrent.SettableFuture in project Signal-Android by WhisperSystems.

the class ConversationParentFragment method sendMediaMessage.

private ListenableFuture<Void> sendMediaMessage(@NonNull RecipientId recipientId, final boolean forceSms, @NonNull String body, SlideDeck slideDeck, QuoteModel quote, List<Contact> contacts, List<LinkPreview> previews, List<Mention> mentions, final long expiresIn, final boolean viewOnce, final int subscriptionId, final boolean initiating, final boolean clearComposeBox, @Nullable final String metricId) {
    if (!isDefaultSms && (!isSecureText || forceSms) && recipient.get().hasSmsAddress()) {
        showDefaultSmsPrompt();
        return new SettableFuture<>(null);
    }
    final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isServiceIdOnly();
    final long thread = this.threadId;
    if (sendPush) {
        MessageUtil.SplitResult splitMessage = MessageUtil.getSplitMessage(requireContext(), body, sendButton.getSelectedTransport().calculateCharacters(body).maxPrimaryMessageSize);
        body = splitMessage.getBody();
        if (splitMessage.getTextSlide().isPresent()) {
            slideDeck.addSlide(splitMessage.getTextSlide().get());
        }
    }
    OutgoingMediaMessage outgoingMessageCandidate = new OutgoingMediaMessage(Recipient.resolved(recipientId), slideDeck, body, System.currentTimeMillis(), subscriptionId, expiresIn, viewOnce, distributionType, quote, contacts, previews, mentions);
    final SettableFuture<Void> future = new SettableFuture<>();
    final Context context = requireContext().getApplicationContext();
    final OutgoingMediaMessage outgoingMessage;
    if (sendPush) {
        outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate);
        ApplicationDependencies.getTypingStatusSender().onTypingStopped(thread);
    } else {
        outgoingMessage = outgoingMessageCandidate;
    }
    Permissions.with(this).request(Manifest.permission.SEND_SMS, Manifest.permission.READ_SMS).ifNecessary(!sendPush).withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_sms_permission_in_order_to_send_an_sms)).onAllGranted(() -> {
        if (clearComposeBox) {
            inputPanel.clearQuote();
            attachmentManager.clear(glideRequests, false);
            silentlySetComposeText("");
        }
        final long id = fragment.stageOutgoingMessage(outgoingMessage);
        SimpleTask.run(() -> {
            return MessageSender.send(context, outgoingMessage, thread, forceSms, metricId, null);
        }, result -> {
            sendComplete(result);
            future.set(null);
        });
    }).onAnyDenied(() -> future.set(null)).execute();
    return future;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) Context(android.content.Context) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) MessageUtil(org.thoughtcrime.securesms.util.MessageUtil) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage)

Example 34 with SettableFuture

use of org.thoughtcrime.securesms.util.concurrent.SettableFuture in project Signal-Android by WhisperSystems.

the class ConversationParentFragment method initializeIdentityRecords.

private ListenableFuture<Boolean> initializeIdentityRecords() {
    final SettableFuture<Boolean> future = new SettableFuture<>();
    final Context context = requireContext().getApplicationContext();
    if (SignalStore.account().getAci() == null || SignalStore.account().getPni() == null) {
        Log.w(TAG, "Not registered! Skipping initializeIdentityRecords()");
        future.set(false);
        return future;
    }
    new AsyncTask<Recipient, Void, Pair<IdentityRecordList, String>>() {

        @Override
        @NonNull
        protected Pair<IdentityRecordList, String> doInBackground(Recipient... params) {
            List<Recipient> recipients;
            if (params[0].isGroup()) {
                recipients = SignalDatabase.groups().getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
            } else {
                recipients = Collections.singletonList(params[0]);
            }
            long startTime = System.currentTimeMillis();
            IdentityRecordList identityRecordList = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients);
            Log.i(TAG, String.format(Locale.US, "Loaded %d identities in %d ms", recipients.size(), System.currentTimeMillis() - startTime));
            String message = null;
            if (identityRecordList.isUnverified()) {
                message = IdentityUtil.getUnverifiedBannerDescription(context, identityRecordList.getUnverifiedRecipients());
            }
            return new Pair<>(identityRecordList, message);
        }

        @Override
        protected void onPostExecute(@NonNull Pair<IdentityRecordList, String> result) {
            Log.i(TAG, "Got identity records: " + result.first().isUnverified());
            identityRecords = result.first();
            if (result.second() != null) {
                Log.d(TAG, "Replacing banner...");
                unverifiedBannerView.get().display(result.second(), result.first().getUnverifiedRecords(), new UnverifiedClickedListener(), new UnverifiedDismissedListener());
            } else if (unverifiedBannerView.resolved()) {
                Log.d(TAG, "Clearing banner...");
                unverifiedBannerView.get().hide();
            }
            titleView.setVerified(isSecureText && identityRecords.isVerified());
            future.set(true);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, recipient.get());
    return future;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) Context(android.content.Context) LiveRecipient(org.thoughtcrime.securesms.recipients.LiveRecipient) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SpannableString(android.text.SpannableString) IdentityRecordList(org.thoughtcrime.securesms.database.identity.IdentityRecordList) NonNull(androidx.annotation.NonNull) ArrayList(java.util.ArrayList) IdentityRecordList(org.thoughtcrime.securesms.database.identity.IdentityRecordList) List(java.util.List) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Pair(org.whispersystems.libsignal.util.Pair)

Example 35 with SettableFuture

use of org.thoughtcrime.securesms.util.concurrent.SettableFuture in project Signal-Android by WhisperSystems.

the class IdentityUtil method getRemoteIdentityKey.

public static ListenableFuture<Optional<IdentityRecord>> getRemoteIdentityKey(final Context context, final Recipient recipient) {
    final SettableFuture<Optional<IdentityRecord>> future = new SettableFuture<>();
    final RecipientId recipientId = recipient.getId();
    SimpleTask.run(SignalExecutors.BOUNDED, () -> ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipientId), future::set);
    return future;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Optional(org.whispersystems.libsignal.util.guava.Optional)

Aggregations

SettableFuture (org.thoughtcrime.securesms.util.concurrent.SettableFuture)37 Context (android.content.Context)9 Animation (android.view.animation.Animation)8 ExecutionException (java.util.concurrent.ExecutionException)8 SdpObserver (org.webrtc.SdpObserver)8 SessionDescription (org.webrtc.SessionDescription)8 ScaleAnimation (android.view.animation.ScaleAnimation)6 TranslateAnimation (android.view.animation.TranslateAnimation)6 Bitmap (android.graphics.Bitmap)4 NonNull (android.support.annotation.NonNull)4 OvershootInterpolator (android.view.animation.OvershootInterpolator)4 IOException (java.io.IOException)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 DraftDatabase (org.thoughtcrime.securesms.database.DraftDatabase)4 Drafts (org.thoughtcrime.securesms.database.DraftDatabase.Drafts)4 Recipient (org.thoughtcrime.securesms.recipients.Recipient)4 SuppressLint (android.annotation.SuppressLint)3 SpannableString (android.text.SpannableString)3 List (java.util.List)3 VoiceNoteDraft (org.thoughtcrime.securesms.components.voice.VoiceNoteDraft)3