Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/iNPUTmice/Conversations.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2022-08-09 10:40:01 +0300
committerDaniel Gultsch <daniel@gultsch.de>2022-08-09 10:40:04 +0300
commitb3a3f2b9308deadd5ab1af55e1e66b0e7b704ba5 (patch)
treee31535986aa7377b760ddc21530f828b0f3e8a99
parent5aeed638444dad5d710350900e159e0dca9f5503 (diff)
try to detect if a container contains video or audio
fixes #4321
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/FileBackend.java31
-rw-r--r--src/main/java/eu/siacs/conversations/services/XmppConnectionService.java6
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java153
-rw-r--r--src/main/java/eu/siacs/conversations/utils/MimeUtils.java18
-rw-r--r--src/main/java/eu/siacs/conversations/utils/UIHelper.java4
-rw-r--r--src/main/res/values/strings.xml1
6 files changed, 159 insertions, 54 deletions
diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
index faeca6308..c3093f2cf 100644
--- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
@@ -1496,6 +1496,7 @@ public class FileBackend {
DownloadableFile file = getFile(message);
final String mime = file.getMimeType();
final boolean privateMessage = message.isPrivateMessage();
+ final boolean ambiguous = MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime);
final boolean image =
message.getType() == Message.TYPE_IMAGE
|| (mime != null && mime.startsWith("image/"));
@@ -1507,7 +1508,21 @@ public class FileBackend {
body.append(url);
}
body.append('|').append(file.getSize());
- if (image || video || pdf) {
+ if (ambiguous) {
+ try {
+ final Dimensions dimensions = getVideoDimensions(file);
+ if (dimensions.valid()) {
+ Log.d(Config.LOGTAG,"ambiguous file "+mime+" is video");
+ body.append('|').append(dimensions.width).append('|').append(dimensions.height);
+ } else {
+ Log.d(Config.LOGTAG,"ambiguous file "+mime+" is audio");
+ body.append("|0|0|").append(getMediaRuntime(file));
+ }
+ } catch (final NotAVideoFile e) {
+ Log.d(Config.LOGTAG,"ambiguous file "+mime+" is audio");
+ body.append("|0|0|").append(getMediaRuntime(file));
+ }
+ } else if (image || video || pdf) {
try {
final Dimensions dimensions;
if (video) {
@@ -1537,14 +1552,16 @@ public class FileBackend {
: (image ? Message.TYPE_IMAGE : Message.TYPE_FILE));
}
- private int getMediaRuntime(File file) {
+ private int getMediaRuntime(final File file) {
try {
- MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
+ final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(file.toString());
- return Integer.parseInt(
- mediaMetadataRetriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_DURATION));
- } catch (RuntimeException e) {
+ final String value = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ if (Strings.isNullOrEmpty(value)) {
+ return 0;
+ }
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
return 0;
}
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index a6823e670..b15d9bccb 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1384,6 +1384,7 @@ public class XmppConnectionService extends Service {
final Intent intent = new Intent(this, EventReceiver.class);
intent.setAction(ACTION_POST_CONNECTIVITY_CHANGE);
try {
+ //TODO add immutable flag
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMillis, pendingIntent);
@@ -1430,7 +1431,8 @@ public class XmppConnectionService extends Service {
final Intent intent = new Intent(this, EventReceiver.class);
intent.setAction(ACTION_IDLE_PING);
try {
- PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+ //TODO add immutable flag
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingIntent);
} catch (RuntimeException e) {
Log.d(Config.LOGTAG, "unable to schedule alarm for idle ping", e);
@@ -1443,7 +1445,7 @@ public class XmppConnectionService extends Service {
connection.setOnStatusChangedListener(this.statusListener);
connection.setOnPresencePacketReceivedListener(this.mPresenceParser);
connection.setOnUnregisteredIqPacketReceivedListener(this.mIqParser);
- connection.setOnJinglePacketReceivedListener(((a, jp) -> mJingleConnectionManager.deliverPacket(a, jp)));
+ connection.setOnJinglePacketReceivedListener((mJingleConnectionManager::deliverPacket));
connection.setOnBindListener(this.mOnBindListener);
connection.setOnMessageAcknowledgeListener(this.mOnMessageAcknowledgedListener);
connection.addOnAdvancedStreamFeaturesAvailableListener(this.mMessageArchiveService);
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
index 662120d84..9822ac004 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
@@ -11,6 +11,7 @@ import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.google.common.base.Optional;
+import com.google.common.base.Strings;
import java.util.List;
@@ -24,11 +25,13 @@ import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
+import eu.siacs.conversations.utils.MimeUtils;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
-public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
+public class ConversationAdapter
+ extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
private final XmppActivity activity;
private final List<Conversation> conversations;
@@ -39,11 +42,15 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
this.conversations = conversations;
}
-
@NonNull
@Override
public ConversationViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- return new ConversationViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.conversation_list_row, parent, false));
+ return new ConversationViewHolder(
+ DataBindingUtil.inflate(
+ LayoutInflater.from(parent.getContext()),
+ R.layout.conversation_list_row,
+ parent,
+ false));
}
@Override
@@ -54,15 +61,18 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
}
CharSequence name = conversation.getName();
if (name instanceof Jid) {
- viewHolder.binding.conversationName.setText(IrregularUnicodeDetector.style(activity, (Jid) name));
+ viewHolder.binding.conversationName.setText(
+ IrregularUnicodeDetector.style(activity, (Jid) name));
} else {
viewHolder.binding.conversationName.setText(name);
}
if (conversation == ConversationFragment.getConversation(activity)) {
- viewHolder.binding.frame.setBackgroundColor(StyledAttributes.getColor(activity, R.attr.color_background_tertiary));
+ viewHolder.binding.frame.setBackgroundColor(
+ StyledAttributes.getColor(activity, R.attr.color_background_tertiary));
} else {
- viewHolder.binding.frame.setBackgroundColor(StyledAttributes.getColor(activity, R.attr.color_background_primary));
+ viewHolder.binding.frame.setBackgroundColor(
+ StyledAttributes.getColor(activity, R.attr.color_background_primary));
}
Message message = conversation.getLatestMessage();
@@ -92,31 +102,70 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
} else {
final boolean fileAvailable = !message.isDeleted();
final boolean showPreviewText;
- if (fileAvailable && (message.isFileOrImage() || message.treatAsDownloadable() || message.isGeoUri())) {
+ if (fileAvailable
+ && (message.isFileOrImage()
+ || message.treatAsDownloadable()
+ || message.isGeoUri())) {
final int imageResource;
if (message.isGeoUri()) {
- imageResource = activity.getThemeResource(R.attr.ic_attach_location, R.drawable.ic_attach_location);
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_location, R.drawable.ic_attach_location);
showPreviewText = false;
} else {
- //TODO move this into static MediaPreview method and use same icons as in MediaAdapter
+ // TODO move this into static MediaPreview method and use same icons as in
+ // MediaAdapter
final String mime = message.getMimeType();
- switch (mime == null ? "" : mime.split("/")[0]) {
- case "image":
- imageResource = activity.getThemeResource(R.attr.ic_attach_photo, R.drawable.ic_attach_photo);
- showPreviewText = false;
- break;
- case "video":
- imageResource = activity.getThemeResource(R.attr.ic_attach_videocam, R.drawable.ic_attach_videocam);
+ if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
+ final Message.FileParams fileParams = message.getFileParams();
+ if (fileParams.width > 0 && fileParams.height > 0) {
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_videocam,
+ R.drawable.ic_attach_videocam);
showPreviewText = false;
- break;
- case "audio":
- imageResource = activity.getThemeResource(R.attr.ic_attach_record, R.drawable.ic_attach_record);
+ } else if (fileParams.runtime > 0) {
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_record, R.drawable.ic_attach_record);
showPreviewText = false;
- break;
- default:
- imageResource = activity.getThemeResource(R.attr.ic_attach_document, R.drawable.ic_attach_document);
+ } else {
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_document,
+ R.drawable.ic_attach_document);
showPreviewText = true;
- break;
+ }
+ } else {
+ switch (Strings.nullToEmpty(mime).split("/")[0]) {
+ case "image":
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_photo, R.drawable.ic_attach_photo);
+ showPreviewText = false;
+ break;
+ case "video":
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_videocam,
+ R.drawable.ic_attach_videocam);
+ showPreviewText = false;
+ break;
+ case "audio":
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_record,
+ R.drawable.ic_attach_record);
+ showPreviewText = false;
+ break;
+ default:
+ imageResource =
+ activity.getThemeResource(
+ R.attr.ic_attach_document,
+ R.drawable.ic_attach_document);
+ showPreviewText = true;
+ break;
+ }
}
}
viewHolder.binding.conversationLastmsgImg.setImageResource(imageResource);
@@ -125,13 +174,18 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
viewHolder.binding.conversationLastmsgImg.setVisibility(View.GONE);
showPreviewText = true;
}
- final Pair<CharSequence, Boolean> preview = UIHelper.getMessagePreview(activity, message, viewHolder.binding.conversationLastmsg.getCurrentTextColor());
+ final Pair<CharSequence, Boolean> preview =
+ UIHelper.getMessagePreview(
+ activity,
+ message,
+ viewHolder.binding.conversationLastmsg.getCurrentTextColor());
if (showPreviewText) {
viewHolder.binding.conversationLastmsg.setText(UIHelper.shorten(preview.first));
} else {
viewHolder.binding.conversationLastmsgImg.setContentDescription(preview.first);
}
- viewHolder.binding.conversationLastmsg.setVisibility(showPreviewText ? View.VISIBLE : View.GONE);
+ viewHolder.binding.conversationLastmsg.setVisibility(
+ showPreviewText ? View.VISIBLE : View.GONE);
if (preview.second) {
if (isRead) {
viewHolder.binding.conversationLastmsg.setTypeface(null, Typeface.ITALIC);
@@ -152,7 +206,8 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
if (message.getStatus() == Message.STATUS_RECEIVED) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
viewHolder.binding.senderName.setVisibility(View.VISIBLE);
- viewHolder.binding.senderName.setText(UIHelper.getMessageDisplayName(message).split("\\s+")[0] + ':');
+ viewHolder.binding.senderName.setText(
+ UIHelper.getMessageDisplayName(message).split("\\s+")[0] + ':');
} else {
viewHolder.binding.senderName.setVisibility(View.GONE);
}
@@ -164,33 +219,47 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
}
}
-
final Optional<OngoingRtpSession> ongoingCall;
if (conversation.getMode() == Conversational.MODE_MULTI) {
ongoingCall = Optional.absent();
} else {
- ongoingCall = activity.xmppConnectionService.getJingleConnectionManager().getOngoingRtpConnection(conversation.getContact());
+ ongoingCall =
+ activity.xmppConnectionService
+ .getJingleConnectionManager()
+ .getOngoingRtpConnection(conversation.getContact());
}
if (ongoingCall.isPresent()) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- final int ic_ongoing_call = activity.getThemeResource(R.attr.ic_ongoing_call_hint, R.drawable.ic_phone_in_talk_black_18dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_ongoing_call);
+ final int ic_ongoing_call =
+ activity.getThemeResource(
+ R.attr.ic_ongoing_call_hint, R.drawable.ic_phone_in_talk_black_18dp);
+ viewHolder.binding.notificationStatus.setImageResource(ic_ongoing_call);
} else {
- final long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
+ final long muted_till =
+ conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
if (muted_till == Long.MAX_VALUE) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_off = activity.getThemeResource(R.attr.icon_notifications_off, R.drawable.ic_notifications_off_black_24dp);
+ int ic_notifications_off =
+ activity.getThemeResource(
+ R.attr.icon_notifications_off,
+ R.drawable.ic_notifications_off_black_24dp);
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_off);
} else if (muted_till >= System.currentTimeMillis()) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_paused = activity.getThemeResource(R.attr.icon_notifications_paused, R.drawable.ic_notifications_paused_black_24dp);
+ int ic_notifications_paused =
+ activity.getThemeResource(
+ R.attr.icon_notifications_paused,
+ R.drawable.ic_notifications_paused_black_24dp);
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_paused);
} else if (conversation.alwaysNotify()) {
viewHolder.binding.notificationStatus.setVisibility(View.GONE);
} else {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_none = activity.getThemeResource(R.attr.icon_notifications_none, R.drawable.ic_notifications_none_black_24dp);
+ int ic_notifications_none =
+ activity.getThemeResource(
+ R.attr.icon_notifications_none,
+ R.drawable.ic_notifications_none_black_24dp);
viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
}
}
@@ -201,9 +270,16 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
} else {
timestamp = conversation.getLatestMessage().getTimeSent();
}
- viewHolder.binding.pinnedOnTop.setVisibility(conversation.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP,false) ? View.VISIBLE : View.GONE);
- viewHolder.binding.conversationLastupdate.setText(UIHelper.readableTimeDifference(activity, timestamp));
- AvatarWorkerTask.loadAvatar(conversation, viewHolder.binding.conversationImage, R.dimen.avatar_on_conversation_overview);
+ viewHolder.binding.pinnedOnTop.setVisibility(
+ conversation.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP, false)
+ ? View.VISIBLE
+ : View.GONE);
+ viewHolder.binding.conversationLastupdate.setText(
+ UIHelper.readableTimeDifference(activity, timestamp));
+ AvatarWorkerTask.loadAvatar(
+ conversation,
+ viewHolder.binding.conversationImage,
+ R.dimen.avatar_on_conversation_overview);
viewHolder.itemView.setOnClickListener(v -> listener.onConversationClick(v, conversation));
}
@@ -216,7 +292,6 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
this.listener = listener;
}
-
public void insert(Conversation c, int position) {
conversations.add(position, c);
notifyDataSetChanged();
@@ -238,7 +313,5 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
super(binding.getRoot());
this.binding = binding;
}
-
}
-
}
diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java
index 90f27f65f..d112a9224 100644
--- a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java
+++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java
@@ -22,12 +22,14 @@ import android.provider.OpenableColumns;
import android.util.Log;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -40,6 +42,13 @@ import eu.siacs.conversations.services.ExportBackupService;
* Used to implement java.net.URLConnection and android.webkit.MimeTypeMap.
*/
public final class MimeUtils {
+
+ public static final List<String> AMBIGUOUS_CONTAINER_FORMATS = ImmutableList.of(
+ "application/ogg",
+ "video/3gpp", // .3gp files can contain audio, video or both
+ "video/3gpp2"
+ );
+
private static final Map<String, String> mimeTypeToExtensionMap = new HashMap<>();
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<>();
@@ -225,7 +234,12 @@ public final class MimeUtils {
add("application/x-xcf", "xcf");
add("application/x-xfig", "fig");
add("application/xhtml+xml", "xhtml");
+ add("video/3gpp", "3gpp");
+ add("video/3gpp", "3gp");
+ add("video/3gpp2", "3gpp2");
+ add("video/3gpp2", "3g2");
add("audio/3gpp", "3gpp");
+ add("audio/3gpp", "3gp");
add("audio/aac", "aac");
add("audio/aac-adts", "aac");
add("audio/amr", "amr");
@@ -365,10 +379,6 @@ public final class MimeUtils {
add("text/x-tex", "cls");
add("text/x-vcalendar", "vcs");
add("text/x-vcard", "vcf");
- add("video/3gpp", "3gpp");
- add("video/3gpp", "3gp");
- add("video/3gpp2", "3gpp2");
- add("video/3gpp2", "3g2");
add("video/avi", "avi");
add("video/dl", "dl");
add("video/dv", "dif");
diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
index 26732b501..b70bfc558 100644
--- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java
+++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java
@@ -477,8 +477,10 @@ public class UIHelper {
public static String getFileDescriptionString(final Context context, final Message message) {
final String mime = message.getMimeType();
- if (mime == null) {
+ if (Strings.isNullOrEmpty(mime)) {
return context.getString(R.string.file);
+ } else if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
+ return context.getString(R.string.multimedia_file);
} else if (mime.startsWith("audio/")) {
return context.getString(R.string.audio);
} else if (mime.startsWith("video/")) {
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index ee5cbce81..8b1fd1de3 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -415,6 +415,7 @@
<string name="video">video</string>
<string name="image">image</string>
<string name="vector_graphic">vector graphic</string>
+ <string name="multimedia_file">multimedia file</string>
<string name="pdf_document">PDF document</string>
<string name="apk">Android App</string>
<string name="vcard">Contact</string>