1
0
Fork 1

Initial support for XEP-0221 (Cheogram) (Experimental)

This commit is contained in:
Arne 2023-05-25 13:02:18 +02:00
parent b2167d1bd0
commit 6310c44316
6 changed files with 86 additions and 9 deletions

View file

@ -63,7 +63,14 @@
<implements rdf:resource="https://xmpp.org/rfcs/rfc7590.html"/>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0221.html"/>
<xmpp:status>partial</xmpp:status>
<xmpp:version>1.0</xmpp:version>
<xmpp:note xml:lang='en'>When used with XEP-0050, images over HTTPS only</xmpp:note>
</xmpp:SupportedXep>
</implements>
<implements>
<xmpp:SupportedXep>
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0224.html"/>

View file

@ -3,6 +3,8 @@ package eu.siacs.conversations.entities;
import static eu.siacs.conversations.entities.Bookmark.printableValue;
import android.content.Intent;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.ui.UriHandlerActivity;
import android.content.DialogInterface;
import android.content.Context;
@ -10,6 +12,8 @@ import android.annotation.SuppressLint;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.net.Uri;
import android.graphics.drawable.Drawable;
import android.util.LruCache;
import android.telephony.PhoneNumberUtils;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.Bitmap;
@ -2029,6 +2033,42 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
setTextOrHide(binding.label, field.getLabel());
setTextOrHide(binding.desc, field.getDesc());
Element media = field.el.findChild("media", "urn:xmpp:media-element");
if (media == null) {
binding.mediaImage.setVisibility(View.GONE);
} else {
final LruCache<String, Drawable> cache = xmppConnectionService.getDrawableCache();
final HttpConnectionManager httpManager = xmppConnectionService.getHttpConnectionManager();
for (Element uriEl : media.getChildren()) {
if (!"uri".equals(uriEl.getName())) continue;
if (!"urn:xmpp:media-element".equals(uriEl.getNamespace())) continue;
String mimeType = uriEl.getAttribute("type");
String uriS = uriEl.getContent();
if (mimeType == null || uriS == null) continue;
Uri uri = Uri.parse(uriS);
if (mimeType.startsWith("image/") && "https".equals(uri.getScheme())) {
final Drawable d = cache.get(uri.toString());
if (d == null) {
int size = (int)(xmppConnectionService.getResources().getDisplayMetrics().density * 288);
Message dummy = new Message(Conversation.this, uri.toString(), Message.ENCRYPTION_NONE);
dummy.setFileParams(new Message.FileParams(uri.toString()));
httpManager.createNewDownloadConnection(dummy, true, (file) -> {
if (file == null) {
dummy.getTransferable().start();
} else {
try {
xmppConnectionService.getFileBackend().getThumbnail(file, xmppConnectionService.getResources(), size, false, uri.toString());
} catch (final Exception e) { }
}
});
} else {
binding.mediaImage.setImageDrawable(d);
binding.mediaImage.setVisibility(View.VISIBLE);
}
}
}
}
Element validate = field.el.findChild("validate", "http://jabber.org/protocol/xdata-validate");
String datatype = validate == null ? null : validate.getAttribute("datatype");

View file

@ -23,6 +23,8 @@ import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.utils.Consumer;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@ -84,6 +86,10 @@ public class HttpConnectionManager extends AbstractConnectionManager {
}
public void createNewDownloadConnection(final Message message, boolean interactive) {
createNewDownloadConnection(message, interactive, null);
}
public void createNewDownloadConnection(final Message message, boolean interactive, Consumer<DownloadableFile> cb) {
synchronized (this.downloadConnections) {
for (HttpDownloadConnection connection : this.downloadConnections) {
if (connection.getMessage() == message) {
@ -91,7 +97,7 @@ public class HttpConnectionManager extends AbstractConnectionManager {
return;
}
}
final HttpDownloadConnection connection = new HttpDownloadConnection(message, this);
final HttpDownloadConnection connection = new HttpDownloadConnection(message, this, cb);
connection.init(interactive);
this.downloadConnections.add(connection);
}

View file

@ -20,6 +20,7 @@ import java.util.Locale;
import javax.net.ssl.SSLHandshakeException;
import eu.siacs.conversations.utils.Consumer;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.DownloadableFile;
@ -48,13 +49,14 @@ public class HttpDownloadConnection implements Transferable {
private boolean acceptedAutomatically = false;
private int mProgress = 0;
private Call mostRecentCall;
final private Consumer<DownloadableFile> cb;
private final SimpleDateFormat fileDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US);
HttpDownloadConnection(Message message, HttpConnectionManager manager) {
HttpDownloadConnection(Message message, HttpConnectionManager manager, Consumer<DownloadableFile> cb) {
this.message = message;
this.mHttpConnectionManager = manager;
this.mXmppConnectionService = manager.getXmppConnectionService();
this.cb = cb;
}
@Override
@ -206,7 +208,7 @@ public class HttpDownloadConnection implements Transferable {
}
private void finish() {
boolean notify = acceptedAutomatically && !message.isRead();
boolean notify = acceptedAutomatically && !message.isRead() && cb == null;
if (message.getEncryption() == Message.ENCRYPTION_PGP) {
notify = message.getConversation().getAccount().getPgpDecryptionService().decrypt(message, notify);
}
@ -228,6 +230,7 @@ public class HttpDownloadConnection implements Transferable {
message.setDeleted(true);
}
message.setTransferable(null);
cb.accept(file);
mXmppConnectionService.updateMessage(message);
mHttpConnectionManager.finishConnection(this);
final boolean notifyAfterScan = notify;
@ -344,7 +347,11 @@ public class HttpDownloadConnection implements Transferable {
} else {
changeStatus(STATUS_OFFER);
HttpDownloadConnection.this.acceptedAutomatically = false;
HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message);
if (cb == null) {
HttpDownloadConnection.this.mXmppConnectionService.getNotificationService().push(message);
} else {
cb.accept(null);
}
}
}

View file

@ -2450,11 +2450,15 @@ public class FileBackend {
}
public Drawable getThumbnail(DownloadableFile file, Resources res, int size, boolean cacheOnly) throws IOException {
return getThumbnail(file, res, size, cacheOnly, file.getAbsolutePath());
}
public Drawable getThumbnail(DownloadableFile file, Resources res, int size, boolean cacheOnly, String cacheKey) throws IOException {
final LruCache<String, Drawable> cache = mXmppConnectionService.getDrawableCache();
Drawable thumbnail = cache.get(file.getAbsolutePath());
Drawable thumbnail = cache.get(cacheKey);
if ((thumbnail == null) && (!cacheOnly)) {
synchronized (THUMBNAIL_LOCK) {
thumbnail = cache.get(file.getAbsolutePath());
thumbnail = cache.get(cacheKey);
if (thumbnail != null) {
return thumbnail;
}
@ -2469,7 +2473,7 @@ public class FileBackend {
throw new FileNotFoundException();
}
}
cache.put(file.getAbsolutePath(), thumbnail);
cache.put(cacheKey, thumbnail);
}
}
return thumbnail;

View file

@ -16,6 +16,19 @@
android:paddingBottom="4dp"
android:textAppearance="@style/TextAppearance.Conversations.Caption" />
<ImageView
android:id="@+id/media_image"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginTop="8dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:background="@color/black87"
android:longClickable="false"
android:scaleType="centerCrop"/>
<ListView
android:id="@+id/values"
android:layout_width="fill_parent"