Merge pull request #14583 from nextcloud/tryResources
Use of Try-With-Resources
This commit is contained in:
commit
fa83d67bfa
@ -963,20 +963,12 @@ public final class ThumbnailsCacheManager {
|
||||
thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px, px);
|
||||
}
|
||||
} else if (Type.VIDEO == type) {
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
|
||||
retriever.setDataSource(file.getAbsolutePath());
|
||||
thumbnail = retriever.getFrameAtTime(-1);
|
||||
} catch (Exception ex) {
|
||||
// can't create a bitmap
|
||||
Log_OC.w(TAG, "Failed to create bitmap from video " + file.getAbsolutePath());
|
||||
} finally {
|
||||
try {
|
||||
retriever.release();
|
||||
} catch (RuntimeException | IOException ex) {
|
||||
// Ignore failure at this point.
|
||||
Log_OC.w(TAG, "Failed release MediaMetadataRetriever for " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
if (thumbnail != null) {
|
||||
|
@ -953,15 +953,11 @@ public class UploadFileOperation extends SyncOperation {
|
||||
File temporalFile = null;
|
||||
File originalFile = new File(mOriginalStoragePath);
|
||||
File expectedFile = null;
|
||||
FileLock fileLock = null;
|
||||
FileChannel channel = null;
|
||||
|
||||
long size;
|
||||
|
||||
try {
|
||||
// check conditions
|
||||
result = checkConditions(originalFile);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@ -983,17 +979,16 @@ public class UploadFileOperation extends SyncOperation {
|
||||
|
||||
// Get the last modification date of the file from the file system
|
||||
long lastModifiedTimestamp = originalFile.lastModified() / 1000;
|
||||
|
||||
final Long creationTimestamp = FileUtil.getCreationTimestamp(originalFile);
|
||||
|
||||
try {
|
||||
channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
|
||||
fileLock = channel.tryLock();
|
||||
} catch (FileNotFoundException e) {
|
||||
// this basically means that the file is on SD card
|
||||
// try to copy file to temporary dir if it doesn't exist
|
||||
String temporalPath = FileStorageUtils.getInternalTemporalPath(user.getAccountName(), mContext) +
|
||||
mFile.getRemotePath();
|
||||
// Initialize channel and fileLock in try-with-resources
|
||||
try (
|
||||
FileChannel channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
|
||||
FileLock fileLock = channel.tryLock()
|
||||
) {
|
||||
if (fileLock == null) {
|
||||
// Handle the case when the file lock cannot be acquired
|
||||
String temporalPath = FileStorageUtils.getInternalTemporalPath(user.getAccountName(), mContext) + mFile.getRemotePath();
|
||||
mFile.setStoragePath(temporalPath);
|
||||
temporalFile = new File(temporalPath);
|
||||
|
||||
@ -1002,61 +997,90 @@ public class UploadFileOperation extends SyncOperation {
|
||||
|
||||
if (result.isSuccess()) {
|
||||
if (temporalFile.length() == originalFile.length()) {
|
||||
channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
|
||||
fileLock = channel.tryLock();
|
||||
} else {
|
||||
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
size = channel.size();
|
||||
} catch (Exception e1) {
|
||||
size = new File(mFile.getStoragePath()).length();
|
||||
}
|
||||
|
||||
// Acquire lock on temporary file
|
||||
try (FileChannel tempChannel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
|
||||
FileLock tempFileLock = tempChannel.tryLock()) {
|
||||
if (tempFileLock != null) {
|
||||
// Use the temporary channel for the upload
|
||||
size = tempChannel.size();
|
||||
updateSize(size);
|
||||
|
||||
// perform the upload
|
||||
// Perform the upload operation
|
||||
if (size > ChunkedFileUploadRemoteOperation.CHUNK_SIZE_MOBILE) {
|
||||
boolean onWifiConnection = connectivityService.getConnectivity().isWifi();
|
||||
|
||||
mUploadOperation = new ChunkedFileUploadRemoteOperation(mFile.getStoragePath(),
|
||||
mUploadOperation = new ChunkedFileUploadRemoteOperation(
|
||||
mFile.getStoragePath(),
|
||||
mFile.getRemotePath(),
|
||||
mFile.getMimeType(),
|
||||
mFile.getEtagInConflict(),
|
||||
lastModifiedTimestamp,
|
||||
creationTimestamp,
|
||||
onWifiConnection,
|
||||
mDisableRetries);
|
||||
mDisableRetries
|
||||
);
|
||||
} else {
|
||||
mUploadOperation = new UploadFileRemoteOperation(mFile.getStoragePath(),
|
||||
mUploadOperation = new UploadFileRemoteOperation(
|
||||
mFile.getStoragePath(),
|
||||
mFile.getRemotePath(),
|
||||
mFile.getMimeType(),
|
||||
mFile.getEtagInConflict(),
|
||||
lastModifiedTimestamp,
|
||||
creationTimestamp,
|
||||
mDisableRetries);
|
||||
mDisableRetries
|
||||
);
|
||||
}
|
||||
|
||||
for (OnDatatransferProgressListener mDataTransferListener : mDataTransferListeners) {
|
||||
mUploadOperation.addDataTransferProgressListener(mDataTransferListener);
|
||||
}
|
||||
|
||||
if (mCancellationRequested.get()) {
|
||||
throw new OperationCancelledException();
|
||||
if (result.isSuccess() && mUploadOperation != null) {
|
||||
result = mUploadOperation.execute(client);
|
||||
if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
|
||||
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size = channel.size();
|
||||
updateSize(size);
|
||||
|
||||
// Perform the upload operation
|
||||
if (size > ChunkedFileUploadRemoteOperation.CHUNK_SIZE_MOBILE) {
|
||||
boolean onWifiConnection = connectivityService.getConnectivity().isWifi();
|
||||
mUploadOperation = new ChunkedFileUploadRemoteOperation(
|
||||
mFile.getStoragePath(),
|
||||
mFile.getRemotePath(),
|
||||
mFile.getMimeType(),
|
||||
mFile.getEtagInConflict(),
|
||||
lastModifiedTimestamp,
|
||||
creationTimestamp,
|
||||
onWifiConnection,
|
||||
mDisableRetries
|
||||
);
|
||||
} else {
|
||||
mUploadOperation = new UploadFileRemoteOperation(
|
||||
mFile.getStoragePath(),
|
||||
mFile.getRemotePath(),
|
||||
mFile.getMimeType(),
|
||||
mFile.getEtagInConflict(),
|
||||
lastModifiedTimestamp,
|
||||
creationTimestamp,
|
||||
mDisableRetries
|
||||
);
|
||||
}
|
||||
|
||||
if (result.isSuccess() && mUploadOperation != null) {
|
||||
result = mUploadOperation.execute(client);
|
||||
|
||||
/// move local temporal file or original file to its corresponding
|
||||
// location in the Nextcloud local folder
|
||||
if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
|
||||
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
|
||||
result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
|
||||
@ -1065,25 +1089,11 @@ public class UploadFileOperation extends SyncOperation {
|
||||
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
} finally {
|
||||
}
|
||||
|
||||
// Finalize cleanup
|
||||
mUploadStarted.set(false);
|
||||
|
||||
if (fileLock != null) {
|
||||
try {
|
||||
fileLock.release();
|
||||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "Failed to unlock file with path " + mOriginalStoragePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (channel != null) {
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {
|
||||
Log_OC.w(TAG, "Failed to close file channel");
|
||||
}
|
||||
}
|
||||
|
||||
if (temporalFile != null && !originalFile.equals(temporalFile)) {
|
||||
temporalFile.delete();
|
||||
}
|
||||
@ -1093,6 +1103,8 @@ public class UploadFileOperation extends SyncOperation {
|
||||
}
|
||||
|
||||
logResult(result, mOriginalStoragePath, mRemotePath);
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
}
|
||||
|
||||
if (result.isSuccess()) {
|
||||
@ -1101,7 +1113,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||
getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
|
||||
}
|
||||
|
||||
// delete temporal file
|
||||
// Delete temporal file
|
||||
if (temporalFile != null && temporalFile.exists() && !temporalFile.delete()) {
|
||||
Log_OC.e(TAG, "Could not delete temporal file " + temporalFile.getAbsolutePath());
|
||||
}
|
||||
@ -1109,6 +1121,7 @@ public class UploadFileOperation extends SyncOperation {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void updateSize(long size) {
|
||||
OCUpload ocUpload = uploadsStorageManager.getUploadById(getOCUploadId());
|
||||
if (ocUpload != null) {
|
||||
@ -1532,22 +1545,16 @@ public class UploadFileOperation extends SyncOperation {
|
||||
if (!sourceFile.renameTo(targetFile)) {
|
||||
// try to copy and then delete
|
||||
targetFile.createNewFile();
|
||||
try (
|
||||
FileChannel inChannel = new FileInputStream(sourceFile).getChannel();
|
||||
FileChannel outChannel = new FileOutputStream(targetFile).getChannel();
|
||||
try {
|
||||
FileChannel outChannel = new FileOutputStream(targetFile).getChannel()
|
||||
) {
|
||||
inChannel.transferTo(0, inChannel.size(), outChannel);
|
||||
sourceFile.delete();
|
||||
} catch (Exception e) {
|
||||
mFile.setStoragePath(""); // forget the local file
|
||||
// by now, treat this as a success; the file was uploaded
|
||||
// the best option could be show a warning message
|
||||
} finally {
|
||||
if (inChannel != null) {
|
||||
inChannel.close();
|
||||
}
|
||||
if (outChannel != null) {
|
||||
outChannel.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,6 @@ public class CopyAndUploadContentUrisTask extends AsyncTask<Object, Void, Result
|
||||
protected ResultCode doInBackground(Object[] params) {
|
||||
|
||||
ResultCode result = ResultCode.UNKNOWN_ERROR;
|
||||
|
||||
InputStream inputStream = null;
|
||||
FileOutputStream outputStream = null;
|
||||
String fullTempPath = null;
|
||||
Uri currentUri = null;
|
||||
|
||||
@ -137,11 +134,7 @@ public class CopyAndUploadContentUrisTask extends AsyncTask<Object, Void, Result
|
||||
currentRemotePath = remotePaths[i];
|
||||
|
||||
long lastModified = 0;
|
||||
try (Cursor cursor = leakedContentResolver.query(currentUri,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
try (Cursor cursor = leakedContentResolver.query(currentUri, null, null, null, null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
// this check prevents a crash when last modification time is not available on certain phones
|
||||
int columnIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED);
|
||||
@ -152,16 +145,15 @@ public class CopyAndUploadContentUrisTask extends AsyncTask<Object, Void, Result
|
||||
}
|
||||
|
||||
fullTempPath = FileStorageUtils.getTemporalPath(user.getAccountName()) + currentRemotePath;
|
||||
inputStream = leakedContentResolver.openInputStream(currentUri);
|
||||
File cacheFile = new File(fullTempPath);
|
||||
File tempDir = cacheFile.getParentFile();
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
}
|
||||
cacheFile.createNewFile();
|
||||
outputStream = new FileOutputStream(fullTempPath);
|
||||
try (InputStream inputStream = leakedContentResolver.openInputStream(currentUri);
|
||||
FileOutputStream outputStream = new FileOutputStream(fullTempPath)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
|
||||
int count;
|
||||
while ((count = inputStream.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, count);
|
||||
@ -179,15 +171,11 @@ public class CopyAndUploadContentUrisTask extends AsyncTask<Object, Void, Result
|
||||
}
|
||||
}
|
||||
|
||||
requestUpload(
|
||||
user,
|
||||
fullTempPath,
|
||||
currentRemotePath,
|
||||
behaviour
|
||||
);
|
||||
requestUpload(user, fullTempPath, currentRemotePath, behaviour);
|
||||
fullTempPath = null;
|
||||
}
|
||||
|
||||
}
|
||||
result = ResultCode.OK;
|
||||
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
@ -216,22 +204,6 @@ public class CopyAndUploadContentUrisTask extends AsyncTask<Object, Void, Result
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
Log_OC.w(TAG, "Ignoring exception of inputStream closure");
|
||||
}
|
||||
}
|
||||
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
Log_OC.w(TAG, "Ignoring exception of outStream closure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2018 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
*/
|
||||
package com.owncloud.android.ui.decoration;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* DividerItemDecoration based on {@link DividerItemDecoration} adding a 72dp left padding.
|
||||
*/
|
||||
public class SimpleListItemDividerDecoration extends DividerItemDecoration {
|
||||
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
|
||||
|
||||
private final Rect bounds = new Rect();
|
||||
private Drawable divider;
|
||||
private int leftPadding;
|
||||
|
||||
/**
|
||||
* Default divider will be used
|
||||
*/
|
||||
public SimpleListItemDividerDecoration(Context context) {
|
||||
super(context, DividerItemDecoration.VERTICAL);
|
||||
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
|
||||
divider = styledAttributes.getDrawable(0);
|
||||
leftPadding = Math.round(72 * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
|
||||
styledAttributes.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
|
||||
canvas.save();
|
||||
final int right;
|
||||
//noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
|
||||
if (parent.getClipToPadding()) {
|
||||
right = parent.getWidth() - parent.getPaddingRight();
|
||||
canvas.clipRect(leftPadding, parent.getPaddingTop(), right,
|
||||
parent.getHeight() - parent.getPaddingBottom());
|
||||
} else {
|
||||
right = parent.getWidth();
|
||||
}
|
||||
|
||||
final int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
parent.getDecoratedBoundsWithMargins(child, bounds);
|
||||
final int bottom = bounds.bottom + Math.round(child.getTranslationY());
|
||||
final int top = bottom - 1;
|
||||
|
||||
if (divider != null) {
|
||||
divider.setBounds(leftPadding, top, right, bottom);
|
||||
divider.draw(canvas);
|
||||
}
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
@ -113,12 +113,10 @@ public class AndroidCalendar {
|
||||
|
||||
private static boolean missing(ContentResolver resolver, Uri uri) {
|
||||
// Determine if a provider is missing
|
||||
ContentProviderClient provider = resolver.acquireContentProviderClient(uri);
|
||||
if (provider != null) {
|
||||
provider.release();
|
||||
}
|
||||
try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
|
||||
return provider == null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user