@@ 33,6 33,7 @@ import androidx.annotation.StringRes;
import androidx.core.content.FileProvider;
import androidx.exifinterface.media.ExifInterface;
+import com.google.common.base.Strings;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayOutputStream;
@@ 76,7 77,8 @@ public class FileBackend {
private static final Object THUMBNAIL_LOCK = new Object();
- private static final SimpleDateFormat IMAGE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
+ private static final SimpleDateFormat IMAGE_DATE_FORMAT =
+ new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
private static final String FILE_PROVIDER = ".files";
private static final float IGNORE_PADDING = 0.15f;
@@ 91,8 93,8 @@ public class FileBackend {
}
public static boolean isInDirectoryThatShouldNotBeScanned(Context context, String path) {
- for (String type : new String[]{RecordingActivity.STORAGE_DIRECTORY_TYPE_NAME, "Files"}) {
- if (path.startsWith(getConversationsDirectory(context, type))) {
+ for (String type : new String[] {RecordingActivity.STORAGE_DIRECTORY_TYPE_NAME, "Files"}) {
+ if (path.startsWith(getLegacyStorageLocation(context, type).getAbsolutePath())) {
return true;
}
}
@@ 114,11 116,14 @@ public class FileBackend {
}
}
- public static boolean allFilesUnderSize(Context context, List<Attachment> attachments, long max) {
- final boolean compressVideo = !AttachFileToConversationRunnable.getVideoCompression(context).equals("uncompressed");
+ public static boolean allFilesUnderSize(
+ Context context, List<Attachment> attachments, long max) {
+ final boolean compressVideo =
+ !AttachFileToConversationRunnable.getVideoCompression(context)
+ .equals("uncompressed");
if (max <= 0) {
Log.d(Config.LOGTAG, "server did not report max file size for http upload");
- return true; //exception to be compatible with HTTP Upload < v0.2
+ return true; // exception to be compatible with HTTP Upload < v0.2
}
for (Attachment attachment : attachments) {
if (attachment.getType() != Attachment.Type.FILE) {
@@ 127,33 132,50 @@ public class FileBackend {
String mime = attachment.getMime();
if (mime != null && mime.startsWith("video/") && compressVideo) {
try {
- Dimensions dimensions = FileBackend.getVideoDimensions(context, attachment.getUri());
+ Dimensions dimensions =
+ FileBackend.getVideoDimensions(context, attachment.getUri());
if (dimensions.getMin() > 720) {
- Log.d(Config.LOGTAG, "do not consider video file with min width larger than 720 for size check");
+ Log.d(
+ Config.LOGTAG,
+ "do not consider video file with min width larger than 720 for size check");
continue;
}
} catch (NotAVideoFile notAVideoFile) {
- //ignore and fall through
+ // ignore and fall through
}
}
if (FileBackend.getFileSize(context, attachment.getUri()) > max) {
- Log.d(Config.LOGTAG, "not all files are under " + max + " bytes. suggesting falling back to jingle");
+ Log.d(
+ Config.LOGTAG,
+ "not all files are under "
+ + max
+ + " bytes. suggesting falling back to jingle");
return false;
}
}
return true;
}
- public static String getConversationsDirectory(Context context, final String type) {
+ public static File getLegacyStorageLocation(Context context, final String type) {
if (Config.ONLY_INTERNAL_STORAGE) {
- return context.getFilesDir().getAbsolutePath() + "/" + type + "/";
+ return new File(context.getFilesDir(), type);
} else {
- return getAppMediaDirectory(context) + context.getString(R.string.app_name) + " " + type + "/";
+ final File appDirectory =
+ new File(
+ Environment.getExternalStorageDirectory(),
+ context.getString(R.string.app_name));
+ final File appMediaDirectory = new File(appDirectory, "Media");
+ final String locationName =
+ String.format("%s %s", context.getString(R.string.app_name), type);
+ return new File(appMediaDirectory, locationName);
}
}
- public static String getAppMediaDirectory(Context context) {
- return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getString(R.string.app_name) + "/Media/";
+ private static String getAppMediaDirectory(Context context) {
+ return Environment.getExternalStorageDirectory().getAbsolutePath()
+ + "/"
+ + context.getString(R.string.app_name)
+ + "/Media/";
}
public static String getBackupDirectory(Context context) {
@@ 180,7 202,8 @@ public class FileBackend {
}
public static boolean isPathBlacklisted(String path) {
- final String androidDataPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/";
+ final String androidDataPath =
+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/";
return path.startsWith(androidDataPath);
}
@@ 193,7 216,8 @@ public class FileBackend {
}
private static String getTakePhotoPath() {
- return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";
+ return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
+ + "/Camera/";
}
public static Uri getUriForUri(Context context, Uri uri) {
@@ 246,7 270,6 @@ public class FileBackend {
return calcSampleSize(options, size);
}
-
private static int calcSampleSize(BitmapFactory.Options options, int size) {
int height = options.outHeight;
int width = options.outWidth;
@@ 256,8 279,7 @@ public class FileBackend {
int halfHeight = height / 2;
int halfWidth = width / 2;
- while ((halfHeight / inSampleSize) > size
- && (halfWidth / inSampleSize) > size) {
+ while ((halfHeight / inSampleSize) > size && (halfWidth / inSampleSize) > size) {
inSampleSize *= 2;
}
}
@@ 274,7 296,8 @@ public class FileBackend {
return getVideoDimensions(mediaMetadataRetriever);
}
- private static Dimensions getVideoDimensionsOfFrame(MediaMetadataRetriever mediaMetadataRetriever) {
+ private static Dimensions getVideoDimensionsOfFrame(
+ MediaMetadataRetriever mediaMetadataRetriever) {
Bitmap bitmap = null;
try {
bitmap = mediaMetadataRetriever.getFrameAtTime();
@@ 288,8 311,10 @@ public class FileBackend {
}
}
- private static Dimensions getVideoDimensions(MediaMetadataRetriever metadataRetriever) throws NotAVideoFile {
- String hasVideo = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
+ private static Dimensions getVideoDimensions(MediaMetadataRetriever metadataRetriever)
+ throws NotAVideoFile {
+ String hasVideo =
+ metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
if (hasVideo == null) {
throw new NotAVideoFile();
}
@@ 301,14 326,18 @@ public class FileBackend {
boolean rotated = rotation == 90 || rotation == 270;
int height;
try {
- String h = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
+ String h =
+ metadataRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
height = Integer.parseInt(h);
} catch (Exception e) {
height = -1;
}
int width;
try {
- String w = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
+ String w =
+ metadataRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
width = Integer.parseInt(w);
} catch (Exception e) {
width = -1;
@@ 319,7 348,9 @@ public class FileBackend {
}
private static int extractRotationFromMediaRetriever(MediaMetadataRetriever metadataRetriever) {
- String r = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+ String r =
+ metadataRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
try {
return Integer.parseInt(r);
} catch (Exception e) {
@@ 368,9 399,8 @@ public class FileBackend {
}
/**
- * This is more than hacky but probably way better than doing nothing
- * Further 'optimizations' might contain to get the parents of CacheDir and NoBackupDir
- * and check against those as well
+ * This is more than hacky but probably way better than doing nothing Further 'optimizations'
+ * might contain to get the parents of CacheDir and NoBackupDir and check against those as well
*/
private static boolean fileIsInFilesDir(Context context, Uri uri) {
try {
@@ 386,7 416,9 @@ public class FileBackend {
private static boolean weOwnFileLollipop(Uri uri) {
try {
File file = new File(uri.getPath());
- FileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor();
+ FileDescriptor fd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
+ .getFileDescriptor();
StructStat st = Os.fstat(fd);
return st.st_uid == android.os.Process.myUid();
} catch (FileNotFoundException e) {
@@ 400,18 432,22 @@ public class FileBackend {
final String filePath = file.getAbsolutePath();
final Cursor cursor;
try {
- cursor = context.getContentResolver().query(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- new String[]{MediaStore.Images.Media._ID},
- MediaStore.Images.Media.DATA + "=? ",
- new String[]{filePath}, null);
+ cursor =
+ context.getContentResolver()
+ .query(
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ new String[] {MediaStore.Images.Media._ID},
+ MediaStore.Images.Media.DATA + "=? ",
+ new String[] {filePath},
+ null);
} catch (SecurityException e) {
return null;
}
if (cursor != null && cursor.moveToFirst()) {
final int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
cursor.close();
- return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));
+ return Uri.withAppendedPath(
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));
} else {
return null;
}
@@ 433,15 469,30 @@ public class FileBackend {
final String mime = attachment.getMime();
if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) {
bitmap = cropCenterSquarePdf(attachment.getUri(), size);
- drawOverlay(bitmap, paintOverlayBlackPdf(bitmap) ? R.drawable.open_pdf_black : R.drawable.open_pdf_white, 0.75f);
+ drawOverlay(
+ bitmap,
+ paintOverlayBlackPdf(bitmap)
+ ? R.drawable.open_pdf_black
+ : R.drawable.open_pdf_white,
+ 0.75f);
} else if (mime != null && mime.startsWith("video/")) {
bitmap = cropCenterSquareVideo(attachment.getUri(), size);
- drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f);
+ drawOverlay(
+ bitmap,
+ paintOverlayBlack(bitmap)
+ ? R.drawable.play_video_black
+ : R.drawable.play_video_white,
+ 0.75f);
} else {
bitmap = cropCenterSquare(attachment.getUri(), size);
if (bitmap != null && "image/gif".equals(mime)) {
Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true);
- drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f);
+ drawOverlay(
+ withGifOverlay,
+ paintOverlayBlack(withGifOverlay)
+ ? R.drawable.play_gif_black
+ : R.drawable.play_gif_white,
+ 1.0f);
bitmap.recycle();
bitmap = withGifOverlay;
}
@@ 471,29 522,32 @@ public class FileBackend {
public void updateMediaScanner(File file, final Runnable callback) {
if (!isInDirectoryThatShouldNotBeScanned(mXmppConnectionService, file)) {
- MediaScannerConnection.scanFile(mXmppConnectionService, new String[]{file.getAbsolutePath()}, null, new MediaScannerConnection.MediaScannerConnectionClient() {
- @Override
- public void onMediaScannerConnected() {
-
- }
-
- @Override
- public void onScanCompleted(String path, Uri uri) {
- if (callback != null && file.getAbsolutePath().equals(path)) {
- callback.run();
- } else {
- Log.d(Config.LOGTAG, "media scanner scanned wrong file");
- if (callback != null) {
- callback.run();
+ MediaScannerConnection.scanFile(
+ mXmppConnectionService,
+ new String[] {file.getAbsolutePath()},
+ null,
+ new MediaScannerConnection.MediaScannerConnectionClient() {
+ @Override
+ public void onMediaScannerConnected() {}
+
+ @Override
+ public void onScanCompleted(String path, Uri uri) {
+ if (callback != null && file.getAbsolutePath().equals(path)) {
+ callback.run();
+ } else {
+ Log.d(Config.LOGTAG, "media scanner scanned wrong file");
+ if (callback != null) {
+ callback.run();
+ }
+ }
}
- }
- }
- });
+ });
return;
/*Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
mXmppConnectionService.sendBroadcast(intent);*/
- } else if (file.getAbsolutePath().startsWith(getAppMediaDirectory(mXmppConnectionService))) {
+ } else if (file.getAbsolutePath()
+ .startsWith(getAppMediaDirectory(mXmppConnectionService))) {
createNoMedia(file.getParentFile());
}
if (callback != null) {
@@ 515,25 569,30 @@ public class FileBackend {
return getFile(message, true);
}
-
public DownloadableFile getFileForPath(String path) {
- return getFileForPath(path, MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path)));
+ return getFileForPath(
+ path,
+ MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path)));
}
- public DownloadableFile getFileForPath(String path, String mime) {
- final DownloadableFile file;
+ public DownloadableFile getFileForPath(final String path, final String mime) {
if (path.startsWith("/")) {
- file = new DownloadableFile(path);
+ return new DownloadableFile(path);
} else {
- if (mime != null && mime.startsWith("image/")) {
- file = new DownloadableFile(getConversationsDirectory("Images") + path);
- } else if (mime != null && mime.startsWith("video/")) {
- file = new DownloadableFile(getConversationsDirectory("Videos") + path);
- } else {
- file = new DownloadableFile(getConversationsDirectory("Files") + path);
- }
+ return getLegacyFileForFilename(path, mime);
+ }
+ }
+
+ public DownloadableFile getLegacyFileForFilename(final String filename, final String mime) {
+ if (Strings.isNullOrEmpty(mime)) {
+ return new DownloadableFile(getLegacyStorageLocation("Files"), filename);
+ } else if (mime.startsWith("image/")) {
+ return new DownloadableFile(getLegacyStorageLocation("Images"), filename);
+ } else if (mime.startsWith("video/")) {
+ return new DownloadableFile(getLegacyStorageLocation("Videos"), filename);
+ } else {
+ return new DownloadableFile(getLegacyStorageLocation("Files"), filename);
}
- return file;
}
public boolean isInternalFile(final File file) {
@@ 542,33 601,37 @@ public class FileBackend {
}
public DownloadableFile getFile(Message message, boolean decrypted) {
- final boolean encrypted = !decrypted
- && (message.getEncryption() == Message.ENCRYPTION_PGP
- || message.getEncryption() == Message.ENCRYPTION_DECRYPTED);
+ final boolean encrypted =
+ !decrypted
+ && (message.getEncryption() == Message.ENCRYPTION_PGP
+ || message.getEncryption() == Message.ENCRYPTION_DECRYPTED);
String path = message.getRelativeFilePath();
if (path == null) {
path = message.getUuid();
}
final DownloadableFile file = getFileForPath(path, message.getMimeType());
if (encrypted) {
- return new DownloadableFile(getConversationsDirectory("Files") + file.getName() + ".pgp");
+ return new DownloadableFile(getLegacyStorageLocation("Files"), file.getName() + ".pgp");
} else {
return file;
}
}
public List<Attachment> convertToAttachments(List<DatabaseBackend.FilePath> relativeFilePaths) {
- List<Attachment> attachments = new ArrayList<>();
- for (DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) {
- final String mime = MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(relativeFilePath.path));
+ final List<Attachment> attachments = new ArrayList<>();
+ for (final DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) {
+ final String mime =
+ MimeUtils.guessMimeTypeFromExtension(
+ MimeUtils.extractRelevantExtension(relativeFilePath.path));
final File file = getFileForPath(relativeFilePath.path, mime);
attachments.add(Attachment.of(relativeFilePath.uuid, file, mime));
}
return attachments;
}
- private String getConversationsDirectory(final String type) {
- return getConversationsDirectory(mXmppConnectionService, type);
+ // TODO remove static method. use direct instance access
+ private File getLegacyStorageLocation(final String type) {
+ return getLegacyStorageLocation(mXmppConnectionService, type);
}
private Bitmap resize(final Bitmap originalBitmap, int size) throws IOException {
@@ 586,7 649,8 @@ public class FileBackend {
scalledW = size;
scalledH = Math.max((int) (h / ((double) w / size)), 1);
}
- final Bitmap result = Bitmap.createScaledBitmap(originalBitmap, scalledW, scalledH, true);
+ final Bitmap result =
+ Bitmap.createScaledBitmap(originalBitmap, scalledW, scalledH, true);
if (!originalBitmap.isRecycled()) {
originalBitmap.recycle();
}
@@ 603,19 667,26 @@ public class FileBackend {
}
final File file = new File(path);
long size = file.length();
- if (size == 0 || size >= mXmppConnectionService.getResources().getInteger(R.integer.auto_accept_filesize)) {
+ if (size == 0
+ || size
+ >= mXmppConnectionService
+ .getResources()
+ .getInteger(R.integer.auto_accept_filesize)) {
return false;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
- final InputStream inputStream = mXmppConnectionService.getContentResolver().openInputStream(uri);
+ final InputStream inputStream =
+ mXmppConnectionService.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(inputStream, null, options);
close(inputStream);
if (options.outMimeType == null || options.outHeight <= 0 || options.outWidth <= 0) {
return false;
}
- return (options.outWidth <= Config.IMAGE_SIZE && options.outHeight <= Config.IMAGE_SIZE && options.outMimeType.contains(Config.IMAGE_FORMAT.name().toLowerCase()));
+ return (options.outWidth <= Config.IMAGE_SIZE
+ && options.outHeight <= Config.IMAGE_SIZE
+ && options.outMimeType.contains(Config.IMAGE_FORMAT.name().toLowerCase()));
} catch (FileNotFoundException e) {
Log.d(Config.LOGTAG, "unable to get image dimensions", e);
return false;
@@ 627,7 698,9 @@ public class FileBackend {
}
private void copyFileToPrivateStorage(File file, Uri uri) throws FileCopyException {
- Log.d(Config.LOGTAG, "copy file (" + uri.toString() + ") to private storage " + file.getAbsolutePath());
+ Log.d(
+ Config.LOGTAG,
+ "copy file (" + uri.toString() + ") to private storage " + file.getAbsolutePath());
file.getParentFile().mkdirs();
try {
file.createNewFile();
@@ 635,7 708,8 @@ public class FileBackend {
throw new FileCopyException(R.string.error_unable_to_create_temporary_file);
}
try (final OutputStream os = new FileOutputStream(file);
- final InputStream is = mXmppConnectionService.getContentResolver().openInputStream(uri)) {
+ final InputStream is =
+ mXmppConnectionService.getContentResolver().openInputStream(uri)) {
if (is == null) {
throw new FileCopyException(R.string.error_file_not_found);
}
@@ 664,7 738,8 @@ public class FileBackend {
}
}
- public void copyFileToPrivateStorage(Message message, Uri uri, String type) throws FileCopyException {
+ public void copyFileToPrivateStorage(Message message, Uri uri, String type)
+ throws FileCopyException {
String mime = MimeUtils.guessMimeTypeFromUriAndMime(mXmppConnectionService, uri, type);
Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage (mime=" + mime + ")");
String extension = MimeUtils.guessExtensionFromMimeType(mime);
@@ 684,7 759,10 @@ public class FileBackend {
String filename = null;
Cursor cursor;
try {
- cursor = mXmppConnectionService.getContentResolver().query(uri, projection, null, null, null);
+ cursor =
+ mXmppConnectionService
+ .getContentResolver()
+ .query(uri, projection, null, null, null);
} catch (IllegalArgumentException e) {
cursor = null;
}
@@ 709,7 787,8 @@ public class FileBackend {
return pos > 0 ? filename.substring(pos + 1) : null;
}
- private void copyImageToPrivateStorage(File file, Uri image, int sampleSize) throws FileCopyException, ImageCompressionException {
+ private void copyImageToPrivateStorage(File file, Uri image, int sampleSize)
+ throws FileCopyException, ImageCompressionException {
final File parent = file.getParentFile();
if (parent != null && parent.mkdirs()) {
Log.d(Config.LOGTAG, "created parent directory");
@@ 743,7 822,10 @@ public class FileBackend {
scaledBitmap = rotate(scaledBitmap, rotation);
boolean targetSizeReached = false;
int quality = Config.IMAGE_QUALITY;
- final int imageMaxSize = mXmppConnectionService.getResources().getInteger(R.integer.auto_accept_filesize);
+ final int imageMaxSize =
+ mXmppConnectionService
+ .getResources()
+ .getInteger(R.integer.auto_accept_filesize);
while (!targetSizeReached) {
os = new FileOutputStream(file);
Log.d(Config.LOGTAG, "compressing image with quality " + quality);
@@ 788,12 870,19 @@ public class FileBackend {
}
}
- public void copyImageToPrivateStorage(File file, Uri image) throws FileCopyException, ImageCompressionException {
- Log.d(Config.LOGTAG, "copy image (" + image.toString() + ") to private storage " + file.getAbsolutePath());
+ public void copyImageToPrivateStorage(File file, Uri image)
+ throws FileCopyException, ImageCompressionException {
+ Log.d(
+ Config.LOGTAG,
+ "copy image ("
+ + image.toString()
+ + ") to private storage "
+ + file.getAbsolutePath());
copyImageToPrivateStorage(file, image, 0);
}
- public void copyImageToPrivateStorage(Message message, Uri image) throws FileCopyException, ImageCompressionException {
+ public void copyImageToPrivateStorage(Message message, Uri image)
+ throws FileCopyException, ImageCompressionException {
switch (Config.IMAGE_FORMAT) {
case JPEG:
message.setRelativeFilePath(message.getUuid() + ".jpg");
@@ 813,7 902,8 @@ public class FileBackend {
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- final InputStream inputStream = mXmppConnectionService.getContentResolver().openInputStream(image);
+ final InputStream inputStream =
+ mXmppConnectionService.getContentResolver().openInputStream(image);
BitmapFactory.decodeStream(inputStream, null, options);
close(inputStream);
float ratio = (float) options.outHeight / options.outWidth;
@@ 833,7 923,8 @@ public class FileBackend {
}
private int getRotation(final Uri image) {
- try (final InputStream is = mXmppConnectionService.getContentResolver().openInputStream(image)) {
+ try (final InputStream is =
+ mXmppConnectionService.getContentResolver().openInputStream(image)) {
return is == null ? 0 : getRotation(is);
} catch (final Exception e) {
return 0;
@@ 842,7 933,9 @@ public class FileBackend {
private static int getRotation(final InputStream inputStream) throws IOException {
final ExifInterface exif = new ExifInterface(inputStream);
- final int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
+ final int orientation =
+ exif.getAttributeInt(
+ ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
@@ 880,7 973,12 @@ public class FileBackend {
thumbnail = rotate(thumbnail, getRotation(file));
if (mime.equals("image/gif")) {
Bitmap withGifOverlay = thumbnail.copy(Bitmap.Config.ARGB_8888, true);
- drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f);
+ drawOverlay(
+ withGifOverlay,
+ paintOverlayBlack(withGifOverlay)
+ ? R.drawable.play_gif_black
+ : R.drawable.play_gif_white,
+ 1.0f);
thumbnail.recycle();
thumbnail = withGifOverlay;
}
@@ 903,27 1001,36 @@ public class FileBackend {
}
private void drawOverlay(Bitmap bitmap, int resource, float factor) {
- Bitmap overlay = BitmapFactory.decodeResource(mXmppConnectionService.getResources(), resource);
+ Bitmap overlay =
+ BitmapFactory.decodeResource(mXmppConnectionService.getResources(), resource);
Canvas canvas = new Canvas(bitmap);
float targetSize = Math.min(canvas.getWidth(), canvas.getHeight()) * factor;
- Log.d(Config.LOGTAG, "target size overlay: " + targetSize + " overlay bitmap size was " + overlay.getHeight());
+ Log.d(
+ Config.LOGTAG,
+ "target size overlay: "
+ + targetSize
+ + " overlay bitmap size was "
+ + overlay.getHeight());
float left = (canvas.getWidth() - targetSize) / 2.0f;
float top = (canvas.getHeight() - targetSize) / 2.0f;
RectF dst = new RectF(left, top, left + targetSize - 1, top + targetSize - 1);
canvas.drawBitmap(overlay, null, dst, createAntiAliasingPaint());
}
- /**
- * https://stackoverflow.com/a/3943023/210897
- */
+ /** https://stackoverflow.com/a/3943023/210897 */
private boolean paintOverlayBlack(final Bitmap bitmap) {
final int h = bitmap.getHeight();
final int w = bitmap.getWidth();
int record = 0;
for (int y = Math.round(h * IGNORE_PADDING); y < h - Math.round(h * IGNORE_PADDING); ++y) {
- for (int x = Math.round(w * IGNORE_PADDING); x < w - Math.round(w * IGNORE_PADDING); ++x) {
+ for (int x = Math.round(w * IGNORE_PADDING);
+ x < w - Math.round(w * IGNORE_PADDING);
+ ++x) {
int pixel = bitmap.getPixel(x, y);
- if ((Color.red(pixel) * 0.299 + Color.green(pixel) * 0.587 + Color.blue(pixel) * 0.114) > 186) {
+ if ((Color.red(pixel) * 0.299
+ + Color.green(pixel) * 0.587
+ + Color.blue(pixel) * 0.114)
+ > 186) {
--record;
} else {
++record;
@@ 940,7 1047,10 @@ public class FileBackend {
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
int pixel = bitmap.getPixel(x, y);
- if ((Color.red(pixel) * 0.299 + Color.green(pixel) * 0.587 + Color.blue(pixel) * 0.114) > 186) {
+ if ((Color.red(pixel) * 0.299
+ + Color.green(pixel) * 0.587
+ + Color.blue(pixel) * 0.114)
+ > 186) {
white++;
}
}
@@ 975,16 1085,27 @@ public class FileBackend {
frame = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
frame.eraseColor(0xff000000);
}
- drawOverlay(frame, paintOverlayBlack(frame) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f);
+ drawOverlay(
+ frame,
+ paintOverlayBlack(frame)
+ ? R.drawable.play_video_black
+ : R.drawable.play_video_white,
+ 0.75f);
return frame;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private Bitmap getPdfDocumentPreview(final File file, final int size) {
try {
- final ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+ final ParcelFileDescriptor fileDescriptor =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
final Bitmap rendered = renderPdfDocument(fileDescriptor, size, true);
- drawOverlay(rendered, paintOverlayBlackPdf(rendered) ? R.drawable.open_pdf_black : R.drawable.open_pdf_white, 0.75f);
+ drawOverlay(
+ rendered,
+ paintOverlayBlackPdf(rendered)
+ ? R.drawable.open_pdf_black
+ : R.drawable.open_pdf_white,
+ 0.75f);
return rendered;
} catch (final IOException | SecurityException e) {
Log.d(Config.LOGTAG, "unable to render PDF document preview", e);
@@ 994,11 1115,11 @@ public class FileBackend {
}
}
-
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private Bitmap cropCenterSquarePdf(final Uri uri, final int size) {
try {
- ParcelFileDescriptor fileDescriptor = mXmppConnectionService.getContentResolver().openFileDescriptor(uri, "r");
+ ParcelFileDescriptor fileDescriptor =
+ mXmppConnectionService.getContentResolver().openFileDescriptor(uri, "r");
final Bitmap bitmap = renderPdfDocument(fileDescriptor, size, false);
return cropCenterSquare(bitmap, size);
} catch (Exception e) {
@@ 1009,11 1130,15 @@ public class FileBackend {
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
- private Bitmap renderPdfDocument(ParcelFileDescriptor fileDescriptor, int targetSize, boolean fit) throws IOException {
+ private Bitmap renderPdfDocument(
+ ParcelFileDescriptor fileDescriptor, int targetSize, boolean fit) throws IOException {
final PdfRenderer pdfRenderer = new PdfRenderer(fileDescriptor);
final PdfRenderer.Page page = pdfRenderer.openPage(0);
- final Dimensions dimensions = scalePdfDimensions(new Dimensions(page.getHeight(), page.getWidth()), targetSize, fit);
- final Bitmap rendered = Bitmap.createBitmap(dimensions.width, dimensions.height, Bitmap.Config.ARGB_8888);
+ final Dimensions dimensions =
+ scalePdfDimensions(
+ new Dimensions(page.getHeight(), page.getWidth()), targetSize, fit);
+ final Bitmap rendered =
+ Bitmap.createBitmap(dimensions.width, dimensions.height, Bitmap.Config.ARGB_8888);
rendered.eraseColor(0xffffffff);
page.render(rendered, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
page.close();
@@ 1025,9 1150,17 @@ public class FileBackend {
public Uri getTakePhotoUri() {
File file;
if (Config.ONLY_INTERNAL_STORAGE) {
- file = new File(mXmppConnectionService.getCacheDir().getAbsolutePath(), "Camera/IMG_" + IMAGE_DATE_FORMAT.format(new Date()) + ".jpg");
+ file =
+ new File(
+ mXmppConnectionService.getCacheDir().getAbsolutePath(),
+ "Camera/IMG_" + IMAGE_DATE_FORMAT.format(new Date()) + ".jpg");
} else {
- file = new File(getTakePhotoPath() + "IMG_" + IMAGE_DATE_FORMAT.format(new Date()) + ".jpg");
+ file =
+ new File(
+ getTakePhotoPath()
+ + "IMG_"
+ + IMAGE_DATE_FORMAT.format(new Date())
+ + ".jpg");
}
file.getParentFile().mkdirs();
return getUriForFile(mXmppConnectionService, file);
@@ 1036,11 1169,15 @@ public class FileBackend {
public Avatar getPepAvatar(Uri image, int size, Bitmap.CompressFormat format) {
final Avatar uncompressAvatar = getUncompressedAvatar(image);
- if (uncompressAvatar != null && uncompressAvatar.image.length() <= Config.AVATAR_CHAR_LIMIT) {
+ if (uncompressAvatar != null
+ && uncompressAvatar.image.length() <= Config.AVATAR_CHAR_LIMIT) {
return uncompressAvatar;
}
if (uncompressAvatar != null) {
- Log.d(Config.LOGTAG, "uncompressed avatar exceeded char limit by " + (uncompressAvatar.image.length() - Config.AVATAR_CHAR_LIMIT));
+ Log.d(
+ Config.LOGTAG,
+ "uncompressed avatar exceeded char limit by "
+ + (uncompressAvatar.image.length() - Config.AVATAR_CHAR_LIMIT));
}
Bitmap bm = cropCenterSquare(image, size);
@@ 1059,7 1196,9 @@ public class FileBackend {
private Avatar getUncompressedAvatar(Uri uri) {
Bitmap bitmap = null;
try {
- bitmap = BitmapFactory.decodeStream(mXmppConnectionService.getContentResolver().openInputStream(uri));
+ bitmap =
+ BitmapFactory.decodeStream(
+ mXmppConnectionService.getContentResolver().openInputStream(uri));
return getPepAvatar(bitmap, Bitmap.CompressFormat.PNG, 100);
} catch (Exception e) {
return null;
@@ 1073,18 1212,24 @@ public class FileBackend {
private Avatar getPepAvatar(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
try {
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
- Base64OutputStream mBase64OutputStream = new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT);
+ Base64OutputStream mBase64OutputStream =
+ new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT);
MessageDigest digest = MessageDigest.getInstance("SHA-1");
- DigestOutputStream mDigestOutputStream = new DigestOutputStream(mBase64OutputStream, digest);
+ DigestOutputStream mDigestOutputStream =
+ new DigestOutputStream(mBase64OutputStream, digest);
if (!bitmap.compress(format, quality, mDigestOutputStream)) {
return null;
}
mDigestOutputStream.flush();
mDigestOutputStream.close();
long chars = mByteArrayOutputStream.size();
- if (format != Bitmap.CompressFormat.PNG && quality >= 50 && chars >= Config.AVATAR_CHAR_LIMIT) {
+ if (format != Bitmap.CompressFormat.PNG
+ && quality >= 50
+ && chars >= Config.AVATAR_CHAR_LIMIT) {
int q = quality - 2;
- Log.d(Config.LOGTAG, "avatar char length was " + chars + " reducing quality to " + q);
+ Log.d(
+ Config.LOGTAG,
+ "avatar char length was " + chars + " reducing quality to " + q);
return getPepAvatar(bitmap, format, q);
}
Log.d(Config.LOGTAG, "settled on char length " + chars + " with quality=" + quality);
@@ 1123,7 1268,8 @@ public class FileBackend {
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
is = new FileInputStream(file);
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
- Base64OutputStream mBase64OutputStream = new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT);
+ Base64OutputStream mBase64OutputStream =
+ new Base64OutputStream(mByteArrayOutputStream, Base64.DEFAULT);
MessageDigest digest = MessageDigest.getInstance("SHA-1");
DigestOutputStream os = new DigestOutputStream(mBase64OutputStream, digest);
byte[] buffer = new byte[4096];
@@ 1157,14 1303,20 @@ public class FileBackend {
file = getAvatarFile(avatar.getFilename());
avatar.size = file.length();
} else {
- file = new File(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + UUID.randomUUID().toString());
+ file =
+ new File(
+ mXmppConnectionService.getCacheDir().getAbsolutePath()
+ + "/"
+ + UUID.randomUUID().toString());
if (file.getParentFile().mkdirs()) {
Log.d(Config.LOGTAG, "created cache directory");
}
OutputStream os = null;
try {
if (!file.createNewFile()) {
- Log.d(Config.LOGTAG, "unable to create temporary file " + file.getAbsolutePath());
+ Log.d(
+ Config.LOGTAG,
+ "unable to create temporary file " + file.getAbsolutePath());
}
os = new FileOutputStream(file);
MessageDigest digest = MessageDigest.getInstance("SHA-1");
@@ 1182,7 1334,9 @@ public class FileBackend {
}
final File avatarFile = getAvatarFile(avatar.getFilename());
if (!file.renameTo(avatarFile)) {
- Log.d(Config.LOGTAG, "unable to rename " + file.getAbsolutePath() + " to " + outputFile);
+ Log.d(
+ Config.LOGTAG,
+ "unable to rename " + file.getAbsolutePath() + " to " + outputFile);
return false;
}
} else {
@@ 1294,7 1448,7 @@ public class FileBackend {
}
return dest;
} catch (SecurityException e) {
- return null; //android 6.0 with revoked permissions for example
+ return null; // android 6.0 with revoked permissions for example
} catch (FileNotFoundException e) {
return null;
} finally {
@@ 1323,10 1477,12 @@ public class FileBackend {
return output;
}
- private int calcSampleSize(Uri image, int size) throws FileNotFoundException, SecurityException {
+ private int calcSampleSize(Uri image, int size)
+ throws FileNotFoundException, SecurityException {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- final InputStream inputStream = mXmppConnectionService.getContentResolver().openInputStream(image);
+ final InputStream inputStream =
+ mXmppConnectionService.getContentResolver().openInputStream(image);
BitmapFactory.decodeStream(inputStream, null, options);
close(inputStream);
return calcSampleSize(options, size);
@@ 1340,7 1496,9 @@ public class FileBackend {
DownloadableFile file = getFile(message);
final String mime = file.getMimeType();
final boolean privateMessage = message.isPrivateMessage();
- final boolean image = message.getType() == Message.TYPE_IMAGE || (mime != null && mime.startsWith("image/"));
+ final boolean image =
+ message.getType() == Message.TYPE_IMAGE
+ || (mime != null && mime.startsWith("image/"));
final boolean video = mime != null && mime.startsWith("video/");
final boolean audio = mime != null && mime.startsWith("audio/");
final boolean pdf = "application/pdf".equals(mime);
@@ 1363,22 1521,29 @@ public class FileBackend {
body.append('|').append(dimensions.width).append('|').append(dimensions.height);
}
} catch (NotAVideoFile notAVideoFile) {
- Log.d(Config.LOGTAG, "file with mime type " + file.getMimeType() + " was not a video file");
- //fall threw
+ Log.d(
+ Config.LOGTAG,
+ "file with mime type " + file.getMimeType() + " was not a video file");
+ // fall threw
}
} else if (audio) {
body.append("|0|0|").append(getMediaRuntime(file));
}
message.setBody(body.toString());
message.setDeleted(false);
- message.setType(privateMessage ? Message.TYPE_PRIVATE_FILE : (image ? Message.TYPE_IMAGE : Message.TYPE_FILE));
+ message.setType(
+ privateMessage
+ ? Message.TYPE_PRIVATE_FILE
+ : (image ? Message.TYPE_IMAGE : Message.TYPE_FILE));
}
private int getMediaRuntime(File file) {
try {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(file.toString());
- return Integer.parseInt(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
+ return Integer.parseInt(
+ mediaMetadataRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_DURATION));
} catch (RuntimeException e) {
return 0;
}
@@ 1431,12 1596,14 @@ public class FileBackend {
}
private Dimensions scalePdfDimensions(Dimensions in) {
- final DisplayMetrics displayMetrics = mXmppConnectionService.getResources().getDisplayMetrics();
+ final DisplayMetrics displayMetrics =
+ mXmppConnectionService.getResources().getDisplayMetrics();
final int target = (int) (displayMetrics.density * 288);
return scalePdfDimensions(in, target, true);
}
- private static Dimensions scalePdfDimensions(final Dimensions in, final int target, final boolean fit) {
+ private static Dimensions scalePdfDimensions(
+ final Dimensions in, final int target, final boolean fit) {
final int w, h;
if (fit == (in.width <= in.height)) {
w = Math.max((int) (in.width / ((double) in.height / target)), 1);
@@ 1491,7 1658,6 @@ public class FileBackend {
}
}
-
public static class FileCopyException extends Exception {
private final int resId;
@@ 1499,8 1665,7 @@ public class FileBackend {
this.resId = resId;
}
- public @StringRes
- int getResId() {
+ public @StringRes int getResId() {
return resId;
}
}