package eu.siacs.conversations.persistance; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Environment; import android.webkit.MimeTypeMap; import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; import de.thedevstack.conversationsplus.exceptions.FileCopyException; import de.thedevstack.conversationsplus.utils.StreamUtil; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; public final class FileBackend { private static final SimpleDateFormat imageDateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); public static DownloadableFile getFile(Message message) { return getFile(message, true); } public static DownloadableFile getFile(Message message, boolean decrypted) { String path = message.getRelativeFilePath(); String extension; if (path != null && !path.isEmpty()) { String[] parts = path.split("\\."); extension = "."+parts[parts.length - 1]; } else { if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_TEXT) { extension = ".png"; } else { extension = ""; } path = message.getUuid()+extension; } final boolean encrypted = !decrypted && (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED); if (encrypted) { return new DownloadableFile(getConversationsFileDirectory()+message.getUuid()+extension+".pgp"); } else { if (path.startsWith("/")) { return new DownloadableFile(path); } else { if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension)) { return new DownloadableFile(getConversationsImageDirectory() + path); } else { return new DownloadableFile(getConversationsFileDirectory() + path); } } } } public static String getConversationsFileDirectory() { return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + ConversationsPlusPreferences.fileTransferFolder() + File.separator; } public static String getConversationsImageDirectory() { return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + ConversationsPlusPreferences.imgTransferFolder() + File.separator; } private static String getPrivateFileDirectoryPath() { return ConversationsPlusApplication.getPrivateFilesDir().getAbsolutePath(); } private static String getPrivateImageDirectoryPath() { return FileBackend.getPrivateFileDirectoryPath() + File.separator + "Images" + File.separator; } public static DownloadableFile copyFileToPrivateStorage(Message message, Uri uri) throws FileCopyException { Logging.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage"); String mime = ConversationsPlusApplication.getInstance().getContentResolver().getType(uri); String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime); message.setRelativeFilePath(FileBackend.getPrivateFileDirectoryPath() + message.getUuid() + "." + extension); DownloadableFile file = getFile(message); file.getParentFile().mkdirs(); OutputStream os = null; InputStream is = null; try { file.createNewFile(); os = new FileOutputStream(file); is = StreamUtil.openInputStreamFromContentResolver(uri); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } os.flush(); } catch(FileNotFoundException e) { throw new FileCopyException(R.string.error_file_not_found); } catch (IOException e) { e.printStackTrace(); throw new FileCopyException(R.string.error_io_exception); } finally { StreamUtil.close(os); StreamUtil.close(is); } Logging.d(Config.LOGTAG, "output file name " + file); return file; } public static DownloadableFile compressImageAndCopyToPrivateStorage(Message message, Bitmap scaledBitmap) throws FileCopyException { message.setRelativeFilePath(FileBackend.getPrivateImageDirectoryPath() + message.getUuid() + ".png"); DownloadableFile file = getFile(message); file.getParentFile().mkdirs(); OutputStream os = null; try { file.createNewFile(); os = new FileOutputStream(file); boolean success = scaledBitmap.compress(Bitmap.CompressFormat.PNG, 75, os); if (!success) { throw new FileCopyException(R.string.error_compressing_image); } os.flush(); } catch (IOException e) { throw new FileCopyException(R.string.error_io_exception, e); } catch (SecurityException e) { throw new FileCopyException(R.string.error_security_exception_during_image_copy); } catch (NullPointerException e) { throw new FileCopyException(R.string.error_io_exception); } finally { StreamUtil.close(os); } return file; } public static Uri getTakePhotoUri() { StringBuilder pathBuilder = new StringBuilder(); pathBuilder.append(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)); pathBuilder.append('/'); pathBuilder.append("Camera"); pathBuilder.append('/'); pathBuilder.append("IMG_" + imageDateFormat.format(new Date()) + ".jpg"); Uri uri = Uri.parse("file://" + pathBuilder.toString()); File file = new File(uri.toString()); file.getParentFile().mkdirs(); return uri; } public static Uri getJingleFileUri(Message message) { File file = getFile(message); return Uri.parse("file://" + file.getAbsolutePath()); } public static boolean isFileAvailable(Message message) { return getFile(message).exists(); } private FileBackend() { // Static helper class } }