Search in sources :

Example 1 with DownloadableFile

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();
            }
        }
    });
}
Also used : OnPhoneContactsLoadedListener(eu.siacs.conversations.utils.OnPhoneContactsLoadedListener) OnBindListener(eu.siacs.conversations.xmpp.OnBindListener) OnRenameListener(eu.siacs.conversations.entities.MucOptions.OnRenameListener) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message) FileNotFoundException(java.io.FileNotFoundException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) PgpEngine(eu.siacs.conversations.crypto.PgpEngine) MediaTranscoder(net.ypresto.androidtranscoder.MediaTranscoder) ParcelFileDescriptor(android.os.ParcelFileDescriptor) FileDescriptor(java.io.FileDescriptor) UiInformableCallback(eu.siacs.conversations.ui.UiInformableCallback) OtrException(net.java.otr4j.OtrException) FileNotFoundException(java.io.FileNotFoundException) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) CertificateException(java.security.cert.CertificateException) ParcelFileDescriptor(android.os.ParcelFileDescriptor) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Example 2 with DownloadableFile

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()));
    }
}
Also used : DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Example 3 with DownloadableFile

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();
    }
}
Also used : ActivityNotFoundException(android.content.ActivityNotFoundException) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Example 4 with DownloadableFile

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();
    }
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) PackageManager(android.content.pm.PackageManager) ActivityNotFoundException(android.content.ActivityNotFoundException) Intent(android.content.Intent) SpannableString(android.text.SpannableString) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile) Uri(android.net.Uri)

Example 5 with DownloadableFile

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);
}
Also used : FileInputStream(java.io.FileInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) FileOutputStream(java.io.FileOutputStream) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) URL(java.net.URL) ByteArrayInputStream(java.io.ByteArrayInputStream) FileOutputStream(java.io.FileOutputStream) HttpConnectionManager(eu.siacs.conversations.http.HttpConnectionManager) PendingIntent(android.app.PendingIntent) DownloadableFile(eu.siacs.conversations.entities.DownloadableFile)

Aggregations

DownloadableFile (eu.siacs.conversations.entities.DownloadableFile)9 Intent (android.content.Intent)4 PendingIntent (android.app.PendingIntent)3 ActivityNotFoundException (android.content.ActivityNotFoundException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 FileInputStream (java.io.FileInputStream)2 FileNotFoundException (java.io.FileNotFoundException)2 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 PackageManager (android.content.pm.PackageManager)1 ResolveInfo (android.content.pm.ResolveInfo)1 Bitmap (android.graphics.Bitmap)1 Uri (android.net.Uri)1 ParcelFileDescriptor (android.os.ParcelFileDescriptor)1 SpannableString (android.text.SpannableString)1 PgpEngine (eu.siacs.conversations.crypto.PgpEngine)1 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)1