use of eu.siacs.conversations.entities.DownloadableFile in project Conversations by siacs.
the class XmppConnectionService method attachFileToConversation.
public void attachFileToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) {
if (FileBackend.weOwnFile(this, uri)) {
Log.d(Config.LOGTAG, "trying to attach file that belonged to us");
callback.error(R.string.security_error_invalid_file_access, null);
return;
}
final Message message;
if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED);
} else {
message = new Message(conversation, "", conversation.getNextEncryption());
}
message.setCounterpart(conversation.getNextCounterpart());
message.setType(Message.TYPE_FILE);
mFileAddingExecutor.execute(new Runnable() {
private void processAsFile() {
final String path = getFileBackend().getOriginalPath(uri);
if (path != null) {
message.setRelativeFilePath(path);
getFileBackend().updateFileParams(message);
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
getPgpEngine().encrypt(message, callback);
} else {
callback.success(message);
}
} else {
try {
getFileBackend().copyFileToPrivateStorage(message, uri);
getFileBackend().updateFileParams(message);
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
final PgpEngine pgpEngine = getPgpEngine();
if (pgpEngine != null) {
pgpEngine.encrypt(message, callback);
} else if (callback != null) {
callback.error(R.string.unable_to_connect_to_keychain, null);
}
} else {
callback.success(message);
}
} catch (FileBackend.FileCopyException e) {
callback.error(e.getResId(), message);
}
}
}
private void processAsVideo() throws FileNotFoundException {
Log.d(Config.LOGTAG, "processing file as video");
message.setRelativeFilePath(message.getUuid() + ".mp4");
final DownloadableFile file = getFileBackend().getFile(message);
file.getParentFile().mkdirs();
ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
final ArrayList<Integer> progressTracker = new ArrayList<>();
final UiInformableCallback<Message> informableCallback;
if (callback instanceof UiInformableCallback) {
informableCallback = (UiInformableCallback<Message>) callback;
} else {
informableCallback = null;
}
MediaTranscoder.Listener listener = new MediaTranscoder.Listener() {
@Override
public void onTranscodeProgress(double progress) {
int p = ((int) Math.round(progress * 100) / 20) * 20;
if (!progressTracker.contains(p) && p != 100 && p != 0) {
progressTracker.add(p);
if (informableCallback != null) {
informableCallback.inform(getString(R.string.transcoding_video_progress, p));
}
}
}
@Override
public void onTranscodeCompleted() {
if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
getPgpEngine().encrypt(message, callback);
} else {
callback.success(message);
}
}
@Override
public void onTranscodeCanceled() {
processAsFile();
}
@Override
public void onTranscodeFailed(Exception e) {
Log.d(Config.LOGTAG, "video transcoding failed " + e.getMessage());
processAsFile();
}
};
MediaTranscoder.getInstance().transcodeVideo(fileDescriptor, file.getAbsolutePath(), MediaFormatStrategyPresets.createAndroid720pStrategy(), listener);
}
@Override
public void run() {
final String mimeType = MimeUtils.guessMimeTypeFromUri(XmppConnectionService.this, uri);
if (mimeType != null && mimeType.startsWith("video/") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
try {
processAsVideo();
} catch (Throwable e) {
processAsFile();
}
} else {
processAsFile();
}
}
});
}
use of eu.siacs.conversations.entities.DownloadableFile in project Conversations by siacs.
the class FileBackend method updateFileParams.
public void updateFileParams(Message message, URL url) {
DownloadableFile file = getFile(message);
final String mime = file.getMimeType();
boolean image = message.getType() == Message.TYPE_IMAGE || (mime != null && mime.startsWith("image/"));
boolean video = mime != null && mime.startsWith("video/");
if (image || video) {
try {
Dimensions dimensions = image ? getImageDimensions(file) : getVideoDimensions(file);
if (url == null) {
message.setBody(Long.toString(file.getSize()) + '|' + dimensions.width + '|' + dimensions.height);
} else {
message.setBody(url.toString() + "|" + Long.toString(file.getSize()) + '|' + dimensions.width + '|' + dimensions.height);
}
return;
} catch (NotAVideoFile notAVideoFile) {
Log.d(Config.LOGTAG, "file with mime type " + file.getMimeType() + " was not a video file");
//fall threw
}
}
if (url != null) {
message.setBody(url.toString() + "|" + Long.toString(file.getSize()));
} else {
message.setBody(Long.toString(file.getSize()));
}
}
use of eu.siacs.conversations.entities.DownloadableFile in project Conversations by siacs.
the class ConversationFragment method shareWith.
private void shareWith(Message message) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
if (GeoHelper.isGeoUri(message.getBody())) {
shareIntent.putExtra(Intent.EXTRA_TEXT, message.getBody());
shareIntent.setType("text/plain");
} else {
final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
try {
shareIntent.putExtra(Intent.EXTRA_STREAM, FileBackend.getUriForFile(activity, file));
} catch (SecurityException e) {
Toast.makeText(activity, activity.getString(R.string.no_permission_to_access_x, file.getAbsolutePath()), Toast.LENGTH_SHORT).show();
return;
}
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String mime = message.getMimeType();
if (mime == null) {
mime = "*/*";
}
shareIntent.setType(mime);
}
try {
activity.startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with)));
} catch (ActivityNotFoundException e) {
//This should happen only on faulty androids because normally chooser is always available
Toast.makeText(activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
}
}
use of eu.siacs.conversations.entities.DownloadableFile in project Conversations by siacs.
the class MessageAdapter method openDownloadable.
public void openDownloadable(Message message) {
DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
if (!file.exists()) {
Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show();
return;
}
Intent openIntent = new Intent(Intent.ACTION_VIEW);
String mime = file.getMimeType();
if (mime == null) {
mime = "*/*";
}
Uri uri;
try {
uri = FileBackend.getUriForFile(activity, file);
} catch (SecurityException e) {
Toast.makeText(activity, activity.getString(R.string.no_permission_to_access_x, file.getAbsolutePath()), Toast.LENGTH_SHORT).show();
return;
}
openIntent.setDataAndType(uri, mime);
openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
PackageManager manager = activity.getPackageManager();
List<ResolveInfo> info = manager.queryIntentActivities(openIntent, 0);
if (info.size() == 0) {
openIntent.setDataAndType(uri, "*/*");
}
try {
getContext().startActivity(openIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
}
}
use of eu.siacs.conversations.entities.DownloadableFile in project Conversations by siacs.
the class PgpDecryptionService method executeApi.
private void executeApi(Message message) {
synchronized (message) {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
if (message.getType() == Message.TYPE_TEXT) {
InputStream is = new ByteArrayInputStream(message.getBody().getBytes());
final OutputStream os = new ByteArrayOutputStream();
Intent result = getOpenPgpApi().executeApi(params, is, os);
switch(result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
try {
os.flush();
final String body = os.toString();
if (body == null) {
throw new IOException("body was null");
}
message.setBody(body);
message.setEncryption(Message.ENCRYPTION_DECRYPTED);
final HttpConnectionManager manager = mXmppConnectionService.getHttpConnectionManager();
if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) {
manager.createNewDownloadConnection(message);
}
} catch (IOException e) {
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
}
mXmppConnectionService.updateMessage(message);
break;
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
synchronized (PgpDecryptionService.this) {
PendingIntent pendingIntent = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
messages.addFirst(message);
currentMessage = null;
storePendingIntent(pendingIntent);
}
break;
case OpenPgpApi.RESULT_CODE_ERROR:
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
mXmppConnectionService.updateMessage(message);
break;
}
} else if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
try {
final DownloadableFile inputFile = mXmppConnectionService.getFileBackend().getFile(message, false);
final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true);
outputFile.getParentFile().mkdirs();
outputFile.createNewFile();
InputStream is = new FileInputStream(inputFile);
OutputStream os = new FileOutputStream(outputFile);
Intent result = getOpenPgpApi().executeApi(params, is, os);
switch(result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
URL url = message.getFileParams().url;
mXmppConnectionService.getFileBackend().updateFileParams(message, url);
message.setEncryption(Message.ENCRYPTION_DECRYPTED);
inputFile.delete();
mXmppConnectionService.getFileBackend().updateMediaScanner(outputFile);
mXmppConnectionService.updateMessage(message);
break;
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
synchronized (PgpDecryptionService.this) {
PendingIntent pendingIntent = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
messages.addFirst(message);
currentMessage = null;
storePendingIntent(pendingIntent);
}
break;
case OpenPgpApi.RESULT_CODE_ERROR:
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
mXmppConnectionService.updateMessage(message);
break;
}
} catch (final IOException e) {
message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED);
mXmppConnectionService.updateMessage(message);
}
}
}
notifyIfPending(message);
}
Aggregations