Detailed changes
@@ -111,7 +111,7 @@ public class BobTransfer implements Transferable {
outputStream.close();
finish(file);
- } catch (IOException e) {
+ } catch (final IOException | XmppConnectionService.BlockedMediaException e) {
finish(null);
xmppConnectionService.showErrorToastInUi(R.string.download_failed_could_not_write_file);
}
@@ -34,4 +34,5 @@
<string name="moderate_message">Moderate</string>
<string name="moderate_reason">Moderation Reason</string>
<string name="unable_to_moderate">Unable to Moderate</string>
+ <string name="block_media">Block Media</string>
</resources>
@@ -201,6 +201,10 @@ public class HttpDownloadConnection implements Transferable {
Log.w(Config.LOGTAG, "Failed to rename downloaded file: " + e);
file = tmp;
message.setRelativeFilePath(file.getAbsolutePath());
+ } catch (final XmppConnectionService.BlockedMediaException e) {
+ file = tmp;
+ tmp.delete();
+ message.setDeleted(true);
}
message.setTransferable(null);
mXmppConnectionService.updateMessage(message);
@@ -756,8 +756,13 @@ public class FileBackend {
extension = "oga";
}
- setupRelativeFilePath(message, uri, extension);
- copyFileToPrivateStorage(mXmppConnectionService.getFileBackend().getFile(message), uri);
+ try {
+ setupRelativeFilePath(message, uri, extension);
+ copyFileToPrivateStorage(mXmppConnectionService.getFileBackend().getFile(message), uri);
+ } catch (final XmppConnectionService.BlockedMediaException e) {
+ message.setRelativeFilePath(null);
+ message.setDeleted(true);
+ }
}
private String getExtensionFromUri(final Uri uri) {
@@ -903,12 +908,17 @@ public class FileBackend {
throw new FileCopyException(R.string.error_file_not_found);
} catch (final IOException e) {
throw new FileCopyException(R.string.error_io_exception);
+ } catch (final XmppConnectionService.BlockedMediaException e) {
+ tmp.delete();
+ message.setRelativeFilePath(null);
+ message.setDeleted(true);
+ return;
}
tmp.renameTo(getFile(message));
updateFileParams(message, null, false);
}
- public void setupRelativeFilePath(final Message message, final Uri uri, final String extension) throws FileCopyException {
+ public void setupRelativeFilePath(final Message message, final Uri uri, final String extension) throws FileCopyException, XmppConnectionService.BlockedMediaException {
try {
setupRelativeFilePath(message, mXmppConnectionService.getContentResolver().openInputStream(uri), extension);
} catch (final FileNotFoundException e) {
@@ -926,7 +936,7 @@ public class FileBackend {
}
}
- public void setupRelativeFilePath(final Message message, final InputStream is, final String extension) throws IOException {
+ public void setupRelativeFilePath(final Message message, final InputStream is, final String extension) throws IOException, XmppConnectionService.BlockedMediaException {
message.setRelativeFilePath(getStorageLocation(is, extension).getAbsolutePath());
}
@@ -936,7 +946,7 @@ public class FileBackend {
setupRelativeFilePath(message, filename, mime);
}
- public File getStorageLocation(final InputStream is, final String extension) throws IOException {
+ public File getStorageLocation(final InputStream is, final String extension) throws IOException, XmppConnectionService.BlockedMediaException {
final String mime = MimeUtils.guessMimeTypeFromExtension(extension);
Cid[] cids = calculateCids(is);
@@ -1796,7 +1806,7 @@ public class FileBackend {
for (int i = 0; i < cids.length; i++) {
mXmppConnectionService.saveCid(cids[i], file);
}
- } catch (final IOException e) { }
+ } catch (final IOException | XmppConnectionService.BlockedMediaException e) { }
}
}
@@ -64,6 +64,8 @@ import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpServiceConnection;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@@ -559,10 +561,22 @@ public class XmppConnectionService extends Service {
return this.databaseBackend.getFileForCid(cid);
}
- public void saveCid(Cid cid, File file) {
+ public void saveCid(Cid cid, File file) throws BlockedMediaException {
+ if (this.databaseBackend.isBlockedMedia(cid)) {
+ throw new BlockedMediaException();
+ }
this.databaseBackend.saveCid(cid, file);
}
+ public void blockMedia(File f) {
+ try {
+ Cid[] cids = getFileBackend().calculateCids(new FileInputStream(f));
+ for (Cid cid : cids) {
+ blockMedia(cid);
+ }
+ } catch (final IOException e) { }
+ }
+
public void blockMedia(Cid cid) {
this.databaseBackend.blockMedia(cid);
}
@@ -5027,10 +5041,22 @@ public class XmppConnectionService extends Service {
sendIqPacket(account, set, null);
}
+ public void evictPreview(File f) {
+ if (mBitmapCache.remove(f.getAbsolutePath()) != null) {
+ Log.d(Config.LOGTAG, "deleted cached preview");
+ }
+ if (mDrawableCache.remove(f.getAbsolutePath()) != null) {
+ Log.d(Config.LOGTAG, "deleted cached preview");
+ }
+ }
+
public void evictPreview(String uuid) {
if (mBitmapCache.remove(uuid) != null) {
Log.d(Config.LOGTAG, "deleted cached preview");
}
+ if (mDrawableCache.remove(uuid) != null) {
+ Log.d(Config.LOGTAG, "deleted cached preview");
+ }
}
public interface OnMamPreferencesFetched {
@@ -5154,4 +5180,6 @@ public class XmppConnectionService extends Service {
return Objects.hashCode(id, media, reconnecting);
}
}
+
+ public static class BlockedMediaException extends Exception { }
}
@@ -1439,6 +1439,7 @@ public class ConversationFragment extends XmppFragment
MenuItem saveAsSticker = menu.findItem(R.id.save_as_sticker);
MenuItem downloadFile = menu.findItem(R.id.download_file);
MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission);
+ MenuItem blockMedia = menu.findItem(R.id.block_media);
MenuItem deleteFile = menu.findItem(R.id.delete_file);
MenuItem showErrorMessage = menu.findItem(R.id.show_error_message);
onlyThisThread.setVisible(!conversation.getLockThread() && m.getThread() != null);
@@ -1503,6 +1504,7 @@ public class ConversationFragment extends XmppFragment
|| !path.startsWith("/")
|| FileBackend.inConversationsDirectory(requireActivity(), path)) {
saveAsSticker.setVisible(true);
+ blockMedia.setVisible(true);
deleteFile.setVisible(true);
deleteFile.setTitle(
activity.getString(
@@ -1577,6 +1579,23 @@ public class ConversationFragment extends XmppFragment
case R.id.retry_decryption:
retryDecryption(selectedMessage);
return true;
+ case R.id.block_media:
+ new AlertDialog.Builder(activity)
+ .setTitle(R.string.block_media)
+ .setMessage("Do you really want to block this media in all messages?")
+ .setPositiveButton(R.string.yes, (dialog, whichButton) -> {
+ File f = activity.xmppConnectionService.getFileBackend().getFile(selectedMessage);
+ activity.xmppConnectionService.blockMedia(f);
+ if (activity.xmppConnectionService.getFileBackend().deleteFile(selectedMessage)) {
+ selectedMessage.setDeleted(true);
+ activity.xmppConnectionService.evictPreview(f);
+ activity.xmppConnectionService.updateMessage(selectedMessage, false);
+ activity.onConversationsListItemUpdated();
+ refresh();
+ }
+ })
+ .setNegativeButton(R.string.no, null).show();
+ return true;
case R.id.delete_file:
deleteFile(selectedMessage);
return true;
@@ -2038,6 +2057,7 @@ public class ConversationFragment extends XmppFragment
if (writeGranted(grantResults, permissions)) {
if (activity != null && activity.xmppConnectionService != null) {
activity.xmppConnectionService.getBitmapCache().evictAll();
+ activity.xmppConnectionService.getDrawableCache().evictAll();
activity.xmppConnectionService.restartFileObserver();
}
refresh();
@@ -2385,7 +2405,7 @@ public class ConversationFragment extends XmppFragment
(dialog, which) -> {
if (activity.xmppConnectionService.getFileBackend().deleteFile(message)) {
message.setDeleted(true);
- activity.xmppConnectionService.evictPreview(message.getUuid());
+ activity.xmppConnectionService.evictPreview(activity.xmppConnectionService.getFileBackend().getFile(message));
activity.xmppConnectionService.updateMessage(message, false);
activity.onConversationsListItemUpdated();
refresh();
@@ -38,6 +38,7 @@ import eu.siacs.conversations.entities.TransferablePlaceholder;
import eu.siacs.conversations.parser.IqParser;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.AbstractConnectionManager;
+import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.MimeUtils;
import eu.siacs.conversations.xml.Element;
@@ -138,6 +139,11 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
} catch (final IOException e) {
finalFile = file;
message.setRelativeFilePath(finalFile.getAbsolutePath());
+ } catch (final XmppConnectionService.BlockedMediaException e) {
+ finalFile = file;
+ file.delete();
+ message.setRelativeFilePath(null);
+ message.setDeleted(true);
}
xmppConnectionService.getFileBackend().updateFileParams(message, null, false);
@@ -66,6 +66,10 @@
android:id="@+id/cancel_transmission"
android:title="@string/cancel_transmission"
android:visible="false" />
+ <item
+ android:id="@+id/block_media"
+ android:title="Block Media"
+ android:visible="false" />
<item
android:id="@+id/delete_file"
android:title="@string/delete_x_file"