@@ -77,35 +77,12 @@ public class FileBackend {
this.mXmppConnectionService = service;
}
- private void createNoMedia(File diretory) {
- final File noMedia = new File(diretory,".nomedia");
- if (!noMedia.exists()) {
- try {
- if (!noMedia.createNewFile()) {
- Log.d(Config.LOGTAG,"created nomedia file "+noMedia.getAbsolutePath());
- }
- } catch (Exception e) {
- Log.d(Config.LOGTAG, "could not create nomedia file");
- }
- }
- }
-
- public void updateMediaScanner(File file) {
- if (!isInDirectoryThatShouldNotBeScanned(mXmppConnectionService, file)) {
- 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))) {
- createNoMedia(file.getParentFile());
- }
- }
-
private static boolean isInDirectoryThatShouldNotBeScanned(Context context, File file) {
return isInDirectoryThatShouldNotBeScanned(context, file.getAbsolutePath());
}
public static boolean isInDirectoryThatShouldNotBeScanned(Context context, String path) {
- for(String type : new String[]{RecordingActivity.STORAGE_DIRECTORY_TYPE_NAME, "Files"}) {
+ for (String type : new String[]{RecordingActivity.STORAGE_DIRECTORY_TYPE_NAME, "Files"}) {
if (path.startsWith(getConversationsDirectory(context, type))) {
return true;
}
@@ -113,52 +90,6 @@ public class FileBackend {
return false;
}
- public boolean deleteFile(Message message) {
- File file = getFile(message);
- if (file.delete()) {
- updateMediaScanner(file);
- return true;
- } else {
- return false;
- }
- }
-
- public DownloadableFile getFile(Message message) {
- return getFile(message, true);
- }
-
- public DownloadableFile getFileForPath(String path, String mime) {
- final DownloadableFile file;
- if (path.startsWith("/")) {
- file = 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 file;
- }
-
- public DownloadableFile getFile(Message message, boolean 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");
- } else {
- return file;
- }
- }
-
public static long getFileSize(Context context, Uri uri) {
try {
final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
@@ -200,41 +131,329 @@ public class FileBackend {
return true;
}
- public String getConversationsDirectory(final String type) {
- return getConversationsDirectory(mXmppConnectionService, type);
- }
-
public static String getConversationsDirectory(Context context, final String type) {
if (Config.ONLY_INTERNAL_STORAGE) {
return context.getFilesDir().getAbsolutePath() + "/" + type + "/";
} else {
- return getAppMediaDirectory(context)+context.getString(R.string.app_name)+" " + type + "/";
+ return getAppMediaDirectory(context) + context.getString(R.string.app_name) + " " + type + "/";
+ }
+ }
+
+ public static String getAppMediaDirectory(Context context) {
+ return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getString(R.string.app_name) + "/Media/";
+ }
+
+ public static String getConversationsLogsDirectory() {
+ return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Conversations/";
+ }
+
+ private static Bitmap rotate(Bitmap bitmap, int degree) {
+ if (degree == 0) {
+ return bitmap;
+ }
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+ Matrix mtx = new Matrix();
+ mtx.postRotate(degree);
+ Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
+ if (bitmap != null && !bitmap.isRecycled()) {
+ bitmap.recycle();
+ }
+ return result;
+ }
+
+ public static boolean isPathBlacklisted(String path) {
+ final String androidDataPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/";
+ return path.startsWith(androidDataPath);
+ }
+
+ private static Paint createAntiAliasingPaint() {
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setFilterBitmap(true);
+ paint.setDither(true);
+ return paint;
+ }
+
+ private static String getTakePhotoPath() {
+ return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";
+ }
+
+ public static Uri getUriForFile(Context context, File file) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N || Config.ONLY_INTERNAL_STORAGE) {
+ try {
+ return FileProvider.getUriForFile(context, getAuthority(context), file);
+ } catch (IllegalArgumentException e) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ throw new SecurityException(e);
+ } else {
+ return Uri.fromFile(file);
+ }
+ }
+ } else {
+ return Uri.fromFile(file);
+ }
+ }
+
+ public static String getAuthority(Context context) {
+ return context.getPackageName() + FILE_PROVIDER;
+ }
+
+ public static Uri getIndexableTakePhotoUri(Uri original) {
+ if (Config.ONLY_INTERNAL_STORAGE || "file".equals(original.getScheme())) {
+ return original;
+ } else {
+ List<String> segments = original.getPathSegments();
+ return Uri.parse("file://" + getTakePhotoPath() + segments.get(segments.size() - 1));
+ }
+ }
+
+ private static boolean hasAlpha(final Bitmap bitmap) {
+ for (int x = 0; x < bitmap.getWidth(); ++x) {
+ for (int y = 0; y < bitmap.getWidth(); ++y) {
+ if (Color.alpha(bitmap.getPixel(x, y)) < 255) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static int calcSampleSize(File image, int size) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(image.getAbsolutePath(), options);
+ return calcSampleSize(options, size);
+ }
+
+ public static int calcSampleSize(BitmapFactory.Options options, int size) {
+ int height = options.outHeight;
+ int width = options.outWidth;
+ int inSampleSize = 1;
+
+ if (height > size || width > size) {
+ int halfHeight = height / 2;
+ int halfWidth = width / 2;
+
+ while ((halfHeight / inSampleSize) > size
+ && (halfWidth / inSampleSize) > size) {
+ inSampleSize *= 2;
+ }
+ }
+ return inSampleSize;
+ }
+
+ private static Dimensions getVideoDimensions(Context context, Uri uri) throws NotAVideoFile {
+ MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
+ try {
+ mediaMetadataRetriever.setDataSource(context, uri);
+ } catch (RuntimeException e) {
+ throw new NotAVideoFile(e);
+ }
+ return getVideoDimensions(mediaMetadataRetriever);
+ }
+
+ private static Dimensions getVideoDimensionsOfFrame(MediaMetadataRetriever mediaMetadataRetriever) {
+ Bitmap bitmap = null;
+ try {
+ bitmap = mediaMetadataRetriever.getFrameAtTime();
+ return new Dimensions(bitmap.getHeight(), bitmap.getWidth());
+ } catch (Exception e) {
+ return null;
+ } finally {
+ if (bitmap != null) {
+ bitmap.recycle();
+ ;
+ }
+ }
+ }
+
+ private static Dimensions getVideoDimensions(MediaMetadataRetriever metadataRetriever) throws NotAVideoFile {
+ String hasVideo = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
+ if (hasVideo == null) {
+ throw new NotAVideoFile();
+ }
+ Dimensions dimensions = getVideoDimensionsOfFrame(metadataRetriever);
+ if (dimensions != null) {
+ return dimensions;
+ }
+ int rotation = extractRotationFromMediaRetriever(metadataRetriever);
+ boolean rotated = rotation == 90 || rotation == 270;
+ int height;
+ try {
+ 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);
+ width = Integer.parseInt(w);
+ } catch (Exception e) {
+ width = -1;
+ }
+ metadataRetriever.release();
+ Log.d(Config.LOGTAG, "extracted video dims " + width + "x" + height);
+ return rotated ? new Dimensions(width, height) : new Dimensions(height, width);
+ }
+
+ private static int extractRotationFromMediaRetriever(MediaMetadataRetriever metadataRetriever) {
+ String r = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+ try {
+ return Integer.parseInt(r);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ public static void close(Closeable stream) {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ public static void close(Socket socket) {
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ public static boolean weOwnFile(Context context, Uri uri) {
+ if (uri == null || !ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
+ return false;
+ } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ return fileIsInFilesDir(context, uri);
+ } else {
+ return weOwnFileLollipop(uri);
+ }
+ }
+
+ /**
+ * 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 {
+ final String haystack = context.getFilesDir().getParentFile().getCanonicalPath();
+ final String needle = new File(uri.getPath()).getCanonicalPath();
+ return needle.startsWith(haystack);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private static boolean weOwnFileLollipop(Uri uri) {
+ try {
+ File file = new File(uri.getPath());
+ 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) {
+ return false;
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+ private void createNoMedia(File diretory) {
+ final File noMedia = new File(diretory, ".nomedia");
+ if (!noMedia.exists()) {
+ try {
+ if (!noMedia.createNewFile()) {
+ Log.d(Config.LOGTAG, "created nomedia file " + noMedia.getAbsolutePath());
+ }
+ } catch (Exception e) {
+ Log.d(Config.LOGTAG, "could not create nomedia file");
+ }
+ }
+ }
+
+ public void updateMediaScanner(File file) {
+ if (!isInDirectoryThatShouldNotBeScanned(mXmppConnectionService, file)) {
+ 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))) {
+ createNoMedia(file.getParentFile());
+ }
+ }
+
+ public boolean deleteFile(Message message) {
+ File file = getFile(message);
+ if (file.delete()) {
+ updateMediaScanner(file);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public DownloadableFile getFile(Message message) {
+ return getFile(message, true);
+ }
+
+ public DownloadableFile getFileForPath(String path, String mime) {
+ final DownloadableFile file;
+ if (path.startsWith("/")) {
+ file = 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 file;
}
- public static String getAppMediaDirectory(Context context) {
- return Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+context.getString(R.string.app_name)+"/Media/";
+ public DownloadableFile getFile(Message message, boolean 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");
+ } else {
+ return file;
+ }
}
- public static String getConversationsLogsDirectory() {
- return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Conversations/";
+ public String getConversationsDirectory(final String type) {
+ return getConversationsDirectory(mXmppConnectionService, type);
}
- public Bitmap resize(Bitmap originalBitmap, int size) {
+ private Bitmap resize(final Bitmap originalBitmap, int size) throws IOException {
int w = originalBitmap.getWidth();
int h = originalBitmap.getHeight();
- if (Math.max(w, h) > size) {
+ if (w <= 0 || h <= 0) {
+ throw new IOException("Decoded bitmap reported bounds smaller 0");
+ } else if (Math.max(w, h) > size) {
int scalledW;
int scalledH;
if (w <= h) {
- scalledW = (int) (w / ((double) h / size));
+ scalledW = Math.max((int) (w / ((double) h / size)), 1);
scalledH = size;
} else {
scalledW = size;
- scalledH = (int) (h / ((double) w / size));
+ scalledH = Math.max((int) (h / ((double) w / size)), 1);
}
- Bitmap result = Bitmap.createScaledBitmap(originalBitmap, scalledW, scalledH, true);
- if (originalBitmap != null && !originalBitmap.isRecycled()) {
+ final Bitmap result = Bitmap.createScaledBitmap(originalBitmap, scalledW, scalledH, true);
+ if (!originalBitmap.isRecycled()) {
originalBitmap.recycle();
}
return result;
@@ -243,22 +462,6 @@ public class FileBackend {
}
}
- private static Bitmap rotate(Bitmap bitmap, int degree) {
- if (degree == 0) {
- return bitmap;
- }
- int w = bitmap.getWidth();
- int h = bitmap.getHeight();
- Matrix mtx = new Matrix();
- mtx.postRotate(degree);
- Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
- if (bitmap != null && !bitmap.isRecycled()) {
- bitmap.recycle();
- }
- return result;
- }
-
-
public boolean useImageAsIs(Uri uri) {
String path = getOriginalPath(uri);
if (path == null || isPathBlacklisted(path)) {
@@ -282,11 +485,6 @@ public class FileBackend {
}
}
- public static boolean isPathBlacklisted(String path) {
- final String androidDataPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/";
- return path.startsWith(androidDataPath);
- }
-
public String getOriginalPath(Uri uri) {
return FileUtils.getPath(mXmppConnectionService, uri);
}
@@ -332,7 +530,7 @@ public class FileBackend {
Log.d(Config.LOGTAG, "copy " + uri.toString() + " to private storage (mime=" + mime + ")");
String extension = MimeUtils.guessExtensionFromMimeType(mime);
if (extension == null) {
- Log.d(Config.LOGTAG,"extension from mime type was null");
+ Log.d(Config.LOGTAG, "extension from mime type was null");
extension = getExtensionFromUri(uri);
}
if ("ogg".equals(extension) && type != null && type.startsWith("audio/")) {
@@ -360,7 +558,7 @@ public class FileBackend {
if (filename == null) {
final List<String> segments = uri.getPathSegments();
if (segments.size() > 0) {
- filename = segments.get(segments.size() -1);
+ filename = segments.get(segments.size() - 1);
}
}
int pos = filename == null ? -1 : filename.lastIndexOf('.');
@@ -463,7 +661,7 @@ public class FileBackend {
}
}
- public Bitmap getThumbnail(Message message, int size, boolean cacheOnly) throws FileNotFoundException {
+ public Bitmap getThumbnail(Message message, int size, boolean cacheOnly) throws IOException {
final String uuid = message.getUuid();
final LruCache<String, Bitmap> cache = mXmppConnectionService.getBitmapCache();
Bitmap thumbnail = cache.get(uuid);
@@ -519,14 +717,6 @@ public class FileBackend {
canvas.drawBitmap(overlay, null, dst, createAntiAliasingPaint());
}
- private static Paint createAntiAliasingPaint() {
- Paint paint = new Paint();
- paint.setAntiAlias(true);
- paint.setFilterBitmap(true);
- paint.setDither(true);
- return paint;
- }
-
private Bitmap getVideoPreview(File file, int size) {
MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
Bitmap frame;
@@ -535,7 +725,7 @@ public class FileBackend {
frame = metadataRetriever.getFrameAtTime(0);
metadataRetriever.release();
frame = resize(frame, size);
- } catch (RuntimeException e) {
+ } catch (IOException | RuntimeException e) {
frame = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
frame.eraseColor(0xff000000);
}
@@ -543,10 +733,6 @@ public class FileBackend {
return frame;
}
- private static String getTakePhotoPath() {
- return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";
- }
-
public Uri getTakePhotoUri() {
File file;
if (Config.ONLY_INTERNAL_STORAGE) {
@@ -558,35 +744,6 @@ public class FileBackend {
return getUriForFile(mXmppConnectionService, file);
}
- public static Uri getUriForFile(Context context, File file) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N || Config.ONLY_INTERNAL_STORAGE) {
- try {
- return FileProvider.getUriForFile(context, getAuthority(context), file);
- } catch (IllegalArgumentException e) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- throw new SecurityException(e);
- } else {
- return Uri.fromFile(file);
- }
- }
- } else {
- return Uri.fromFile(file);
- }
- }
-
- public static String getAuthority(Context context) {
- return context.getPackageName() + FILE_PROVIDER;
- }
-
- public static Uri getIndexableTakePhotoUri(Uri original) {
- if (Config.ONLY_INTERNAL_STORAGE || "file".equals(original.getScheme())) {
- return original;
- } else {
- List<String> segments = original.getPathSegments();
- return Uri.parse("file://" + getTakePhotoPath() + segments.get(segments.size() - 1));
- }
- }
-
public Avatar getPepAvatar(Uri image, int size, Bitmap.CompressFormat format) {
Bitmap bm = cropCenterSquare(image, size);
if (bm == null) {
@@ -601,17 +758,6 @@ public class FileBackend {
return getPepAvatar(bm, format, 100);
}
- private static boolean hasAlpha(final Bitmap bitmap) {
- for (int x = 0; x < bitmap.getWidth(); ++x) {
- for (int y = 0; y < bitmap.getWidth(); ++y) {
- if (Color.alpha(bitmap.getPixel(x, y)) < 255) {
- return true;
- }
- }
- }
- return false;
- }
-
private Avatar getPepAvatar(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
try {
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
@@ -698,12 +844,12 @@ public class FileBackend {
} else {
file = new File(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + UUID.randomUUID().toString());
if (file.getParentFile().mkdirs()) {
- Log.d(Config.LOGTAG,"created cache directory");
+ 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");
@@ -717,17 +863,17 @@ public class FileBackend {
if (sha1sum.equals(avatar.sha1sum)) {
File outputFile = new File(getAvatarPath(avatar.getFilename()));
if (outputFile.getParentFile().mkdirs()) {
- Log.d(Config.LOGTAG,"created avatar directory");
+ Log.d(Config.LOGTAG, "created avatar directory");
}
String filename = getAvatarPath(avatar.getFilename());
if (!file.renameTo(new File(filename))) {
- 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 {
Log.d(Config.LOGTAG, "sha1sum mismatch for " + avatar.owner);
if (!file.delete()) {
- Log.d(Config.LOGTAG,"unable to delete temporary file");
+ Log.d(Config.LOGTAG, "unable to delete temporary file");
}
return false;
}
@@ -846,30 +992,6 @@ public class FileBackend {
return calcSampleSize(options, size);
}
- private static int calcSampleSize(File image, int size) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(image.getAbsolutePath(), options);
- return calcSampleSize(options, size);
- }
-
- public static int calcSampleSize(BitmapFactory.Options options, int size) {
- int height = options.outHeight;
- int width = options.outWidth;
- int inSampleSize = 1;
-
- if (height > size || width > size) {
- int halfHeight = height / 2;
- int halfWidth = width / 2;
-
- while ((halfHeight / inSampleSize) > size
- && (halfWidth / inSampleSize) > size) {
- inSampleSize *= 2;
- }
- }
- return inSampleSize;
- }
-
public void updateFileParams(Message message) {
updateFileParams(message, null);
}
@@ -942,67 +1064,19 @@ public class FileBackend {
return getVideoDimensions(metadataRetriever);
}
- private static Dimensions getVideoDimensions(Context context, Uri uri) throws NotAVideoFile {
- MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
- try {
- mediaMetadataRetriever.setDataSource(context, uri);
- } catch (RuntimeException e) {
- throw new NotAVideoFile(e);
- }
- return getVideoDimensions(mediaMetadataRetriever);
- }
-
- private static Dimensions getVideoDimensionsOfFrame(MediaMetadataRetriever mediaMetadataRetriever) {
- Bitmap bitmap = null;
- try {
- bitmap = mediaMetadataRetriever.getFrameAtTime();
- return new Dimensions(bitmap.getHeight(), bitmap.getWidth());
- } catch (Exception e) {
+ public Bitmap getAvatar(String avatar, int size) {
+ if (avatar == null) {
return null;
- } finally {
- if (bitmap != null) {
- bitmap.recycle();;
- }
- }
- }
-
- private static Dimensions getVideoDimensions(MediaMetadataRetriever metadataRetriever) throws NotAVideoFile {
- String hasVideo = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
- if (hasVideo == null) {
- throw new NotAVideoFile();
- }
- Dimensions dimensions = getVideoDimensionsOfFrame(metadataRetriever);
- if (dimensions != null) {
- return dimensions;
- }
- int rotation = extractRotationFromMediaRetriever(metadataRetriever);
- boolean rotated = rotation == 90 || rotation == 270;
- int height;
- try {
- 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);
- width = Integer.parseInt(w);
- } catch (Exception e) {
- width = -1;
+ Bitmap bm = cropCenter(getAvatarUri(avatar), size, size);
+ if (bm == null) {
+ return null;
}
- metadataRetriever.release();
- Log.d(Config.LOGTAG, "extracted video dims " + width + "x" + height);
- return rotated ? new Dimensions(width, height) : new Dimensions(height, width);
+ return bm;
}
- private static int extractRotationFromMediaRetriever(MediaMetadataRetriever metadataRetriever) {
- String r = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
- try {
- return Integer.parseInt(r);
- } catch (Exception e) {
- return 0;
- }
+ public boolean isFileAvailable(Message message) {
+ return getFile(message).exists();
}
private static class Dimensions {
@@ -1045,78 +1119,4 @@ public class FileBackend {
return resId;
}
}
-
- public Bitmap getAvatar(String avatar, int size) {
- if (avatar == null) {
- return null;
- }
- Bitmap bm = cropCenter(getAvatarUri(avatar), size, size);
- if (bm == null) {
- return null;
- }
- return bm;
- }
-
- public boolean isFileAvailable(Message message) {
- return getFile(message).exists();
- }
-
- public static void close(Closeable stream) {
- if (stream != null) {
- try {
- stream.close();
- } catch (IOException e) {
- }
- }
- }
-
- public static void close(Socket socket) {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- }
-
-
- public static boolean weOwnFile(Context context, Uri uri) {
- if (uri == null || !ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
- return false;
- } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- return fileIsInFilesDir(context, uri);
- } else {
- return weOwnFileLollipop(uri);
- }
- }
-
-
- /**
- * 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 {
- final String haystack = context.getFilesDir().getParentFile().getCanonicalPath();
- final String needle = new File(uri.getPath()).getCanonicalPath();
- return needle.startsWith(haystack);
- } catch (IOException e) {
- return false;
- }
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private static boolean weOwnFileLollipop(Uri uri) {
- try {
- File file = new File(uri.getPath());
- 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) {
- return false;
- } catch (Exception e) {
- return true;
- }
- }
}