use of com.owncloud.android.operations.UploadFileOperation in project android by owncloud.
the class FileUploader method onStartCommand.
/**
* Entry point to add one or several files to the queue of uploads.
* <p>
* New uploads are added calling to startService(), resulting in a call to
* this method. This ensures the service will keep on working although the
* caller activity goes away.
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timber.d("Starting command with id %s", startId);
int createdBy = intent.getIntExtra(KEY_CREATED_BY, UploadFileOperation.CREATED_BY_USER);
boolean isCameraUploadFile = createdBy == CREATED_AS_CAMERA_UPLOAD_PICTURE || createdBy == CREATED_AS_CAMERA_UPLOAD_VIDEO;
boolean isAvailableOfflineFile = intent.getBooleanExtra(KEY_IS_AVAILABLE_OFFLINE_FILE, false);
boolean isRequestedFromWifiBackEvent = intent.getBooleanExtra(KEY_REQUESTED_FROM_WIFI_BACK_EVENT, false);
if ((isCameraUploadFile || isAvailableOfflineFile || isRequestedFromWifiBackEvent) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Timber.d("Starting FileUploader service in foreground");
if (isCameraUploadFile) {
mNotificationBuilder.setContentTitle(getString(R.string.uploader_upload_camera_upload_files));
} else if (isAvailableOfflineFile) {
mNotificationBuilder.setContentTitle(getString(R.string.uploader_upload_available_offline_files));
} else if (isRequestedFromWifiBackEvent) {
mNotificationBuilder.setContentTitle(getString(R.string.uploader_upload_requested_from_wifi_files));
}
/*
* After calling startForegroundService method from {@link TransferRequester} for camera uploads or
* available offline, we have to call this within five seconds after the service is created to avoid
* an error
*/
startForeground(141, mNotificationBuilder.build());
}
boolean retry = intent.getBooleanExtra(KEY_RETRY, false);
AbstractList<String> requestedUploads = new Vector<>();
if (!intent.hasExtra(KEY_ACCOUNT)) {
Timber.e("Not enough information provided in intent");
return Service.START_NOT_STICKY;
}
Account account = intent.getParcelableExtra(KEY_ACCOUNT);
Timber.d("Account to upload the file to: %s", account);
if (account == null || !AccountUtils.exists(account.name, getApplicationContext())) {
return Service.START_NOT_STICKY;
}
if (!retry) {
if (!(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
Timber.e("Not enough information provided in intent");
return Service.START_NOT_STICKY;
}
String[] localPaths = null, remotePaths = null, mimeTypes = null;
OCFile[] files = null;
if (intent.hasExtra(KEY_FILE)) {
Parcelable[] files_temp = intent.getParcelableArrayExtra(KEY_FILE);
files = new OCFile[files_temp.length];
System.arraycopy(files_temp, 0, files, 0, files_temp.length);
} else {
localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
mimeTypes = intent.getStringArrayExtra(KEY_MIME_TYPE);
}
boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_FORGET);
boolean isCreateRemoteFolder = intent.getBooleanExtra(KEY_CREATE_REMOTE_FOLDER, false);
if (intent.hasExtra(KEY_FILE) && files == null) {
Timber.e("Incorrect array for OCFiles provided in upload intent");
return Service.START_NOT_STICKY;
} else if (!intent.hasExtra(KEY_FILE)) {
if (localPaths == null) {
Timber.e("Incorrect array for local paths provided in upload intent");
return Service.START_NOT_STICKY;
}
if (remotePaths == null) {
Timber.e("Incorrect array for remote paths provided in upload intent");
return Service.START_NOT_STICKY;
}
if (localPaths.length != remotePaths.length) {
Timber.e("Different number of remote paths and local paths!");
return Service.START_NOT_STICKY;
}
files = new OCFile[localPaths.length];
for (int i = 0; i < localPaths.length; i++) {
files[i] = UploadFileOperation.obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i] : null), getApplicationContext());
if (files[i] == null) {
Timber.e("obtainNewOCFileToUpload() returned null for remotePaths[i]:" + remotePaths[i] + " and localPaths[i]:" + localPaths[i]);
return Service.START_NOT_STICKY;
}
}
}
// at this point variable "OCFile[] files" is loaded correctly.
String uploadKey;
UploadFileOperation newUploadFileOperation;
try {
FileDataStorageManager storageManager = new FileDataStorageManager(getApplicationContext(), account, getContentResolver());
OCCapability capabilitiesForAccount = storageManager.getCapability(account.name);
boolean isChunkingAllowed = capabilitiesForAccount != null && capabilitiesForAccount.isChunkingAllowed();
Timber.d("Chunking is allowed: %s", isChunkingAllowed);
for (OCFile ocFile : files) {
OCUpload ocUpload = new OCUpload(ocFile, account);
ocUpload.setFileSize(ocFile.getFileLength());
ocUpload.setForceOverwrite(forceOverwrite);
ocUpload.setCreateRemoteFolder(isCreateRemoteFolder);
ocUpload.setCreatedBy(createdBy);
ocUpload.setLocalAction(localAction);
/*ocUpload.setUseWifiOnly(isUseWifiOnly);
ocUpload.setWhileChargingOnly(isWhileChargingOnly);*/
ocUpload.setUploadStatus(UploadStatus.UPLOAD_IN_PROGRESS);
if (new File(ocFile.getStoragePath()).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE && isChunkingAllowed) {
ocUpload.setTransferId(SecurityUtils.stringToMD5Hash(ocFile.getRemotePath()) + System.currentTimeMillis());
newUploadFileOperation = new ChunkedUploadFileOperation(account, ocFile, ocUpload, forceOverwrite, localAction, this);
} else {
newUploadFileOperation = new UploadFileOperation(account, ocFile, ocUpload, forceOverwrite, localAction, this);
}
newUploadFileOperation.setCreatedBy(createdBy);
if (isCreateRemoteFolder) {
newUploadFileOperation.setRemoteFolderToBeCreated();
}
newUploadFileOperation.addDatatransferProgressListener(this);
newUploadFileOperation.addDatatransferProgressListener((FileUploaderBinder) mBinder);
newUploadFileOperation.addRenameUploadListener(this);
Pair<String, String> putResult = mPendingUploads.putIfAbsent(account.name, ocFile.getRemotePath(), newUploadFileOperation);
if (putResult != null) {
uploadKey = putResult.first;
requestedUploads.add(uploadKey);
// Save upload in database
long id = mUploadsStorageManager.storeUpload(ocUpload);
newUploadFileOperation.setOCUploadId(id);
}
}
} catch (IllegalArgumentException e) {
Timber.e(e, "Not enough information provided in intent: %s", e.getMessage());
return START_NOT_STICKY;
} catch (IllegalStateException e) {
Timber.e(e, "Bad information provided in intent: %s", e.getMessage());
return START_NOT_STICKY;
} catch (Exception e) {
Timber.e(e, "Unexpected exception while processing upload intent");
return START_NOT_STICKY;
}
// *** TODO REWRITE: block inserted to request A retry; too many code copied, no control exception ***/
} else {
if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_RETRY_UPLOAD)) {
Timber.e("Not enough information provided in intent: no KEY_RETRY_UPLOAD_KEY");
return START_NOT_STICKY;
}
OCUpload upload = intent.getParcelableExtra(KEY_RETRY_UPLOAD);
UploadFileOperation newUploadFileOperation;
if (upload.getFileSize() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
upload.setTransferId(SecurityUtils.stringToMD5Hash(upload.getRemotePath()) + System.currentTimeMillis());
newUploadFileOperation = new ChunkedUploadFileOperation(account, null, upload, upload.isForceOverwrite(), upload.getLocalAction(), this);
} else {
newUploadFileOperation = new UploadFileOperation(account, null, upload, upload.isForceOverwrite(), upload.getLocalAction(), this);
}
newUploadFileOperation.addDatatransferProgressListener(this);
newUploadFileOperation.addDatatransferProgressListener((FileUploaderBinder) mBinder);
newUploadFileOperation.addRenameUploadListener(this);
Pair<String, String> putResult = mPendingUploads.putIfAbsent(account.name, upload.getRemotePath(), newUploadFileOperation);
if (putResult != null) {
String uploadKey = putResult.first;
requestedUploads.add(uploadKey);
// Update upload in database
upload.setUploadStatus(UploadStatus.UPLOAD_IN_PROGRESS);
mUploadsStorageManager.updateUpload(upload);
}
}
if (requestedUploads.size() > 0) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = requestedUploads;
mServiceHandler.sendMessage(msg);
sendBroadcastUploadsAdded();
}
return Service.START_NOT_STICKY;
}
use of com.owncloud.android.operations.UploadFileOperation in project android by owncloud.
the class FileUploader method uploadFile.
/**
* Core upload method: sends the file(s) to upload
*
* @param uploadKey Key to access the upload to perform, contained in mPendingUploads
*/
public void uploadFile(String uploadKey) {
mCurrentUpload = mPendingUploads.get(uploadKey);
if (mCurrentUpload != null) {
// / Check account existence
if (!AccountUtils.exists(mCurrentUpload.getAccount().name, this)) {
Timber.w("Account " + mCurrentUpload.getAccount().name + " does not exist anymore -> cancelling all " + "its uploads");
cancelUploadsForAccount(mCurrentUpload.getAccount());
return;
}
// / OK, let's upload
mUploadsStorageManager.updateDatabaseUploadStart(mCurrentUpload);
notifyUploadStart(mCurrentUpload);
sendBroadcastUploadStarted(mCurrentUpload);
RemoteOperationResult uploadResult = null;
try {
// / prepare client object to send the request to the ownCloud server
if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentUpload.getAccount())) {
mCurrentAccount = mCurrentUpload.getAccount();
mStorageManager = new FileDataStorageManager(getApplicationContext(), mCurrentAccount, getContentResolver());
}
// else, reuse storage manager from previous operation
// always get client from client manager to get fresh credentials in case of update
OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
mUploadClient = SingleSessionManager.getDefaultSingleton().getClientFor(ocAccount, this);
// / perform the upload
uploadResult = mCurrentUpload.execute(mUploadClient, mStorageManager);
} catch (Exception e) {
Timber.e(e, "Error uploading");
uploadResult = new RemoteOperationResult(e);
} finally {
Pair<UploadFileOperation, String> removeResult;
if (mCurrentUpload.wasRenamed()) {
removeResult = mPendingUploads.removePayload(mCurrentAccount.name, mCurrentUpload.getOldFile().getRemotePath());
/* TODO: grant that name is also updated for mCurrentUpload.getOCUploadId */
} else {
removeResult = mPendingUploads.removePayload(mCurrentAccount.name, mCurrentUpload.getRemotePath());
}
if (uploadResult != null && !uploadResult.isSuccess()) {
TransferRequester requester = new TransferRequester();
int jobId = mPendingUploads.buildKey(mCurrentAccount.name, mCurrentUpload.getRemotePath()).hashCode();
if (uploadResult.getException() != null) {
// if failed due to lack of connectivity, schedule an automatic retry
if (requester.shouldScheduleRetry(this, uploadResult.getException())) {
requester.scheduleUpload(this, jobId, mCurrentAccount.name, mCurrentUpload.getRemotePath());
uploadResult = new RemoteOperationResult(ResultCode.NO_NETWORK_CONNECTION);
} else {
String stringToLog = String.format("Exception in upload, network is OK, no retry scheduled for %1s in %2s", mCurrentUpload.getRemotePath(), mCurrentAccount.name);
Timber.v("%s", stringToLog);
}
} else if (uploadResult.getCode() == ResultCode.DELAYED_FOR_WIFI) {
// if failed due to the upload is delayed for wifi, schedule automatic retry as well
requester.scheduleUpload(this, jobId, mCurrentAccount.name, mCurrentUpload.getRemotePath());
}
} else {
String stringToLog = String.format("Success OR fail without exception for %1s in %2s", mCurrentUpload.getRemotePath(), mCurrentAccount.name);
Timber.v("%s", stringToLog);
}
if (uploadResult != null) {
mUploadsStorageManager.updateDatabaseUploadResult(uploadResult, mCurrentUpload);
// / notify result
notifyUploadResult(mCurrentUpload, uploadResult);
}
sendBroadcastUploadFinished(mCurrentUpload, uploadResult, removeResult.second);
}
}
}
use of com.owncloud.android.operations.UploadFileOperation in project android by nextcloud.
the class AbstractIT method uploadOCUpload.
public void uploadOCUpload(OCUpload ocUpload) {
ConnectivityService connectivityServiceMock = new ConnectivityService() {
@Override
public boolean isInternetWalled() {
return false;
}
@Override
public Connectivity getConnectivity() {
return Connectivity.CONNECTED_WIFI;
}
};
PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@NonNull
@Override
public BatteryStatus getBattery() {
return new BatteryStatus();
}
@Override
public boolean isPowerSavingEnabled() {
return false;
}
@Override
public boolean isPowerSavingExclusionAvailable() {
return false;
}
};
UserAccountManager accountManager = UserAccountManagerImpl.fromContext(targetContext);
UploadsStorageManager uploadsStorageManager = new UploadsStorageManager(accountManager, targetContext.getContentResolver());
UploadFileOperation newUpload = new UploadFileOperation(uploadsStorageManager, connectivityServiceMock, powerManagementServiceMock, user, null, ocUpload, NameCollisionPolicy.DEFAULT, FileUploader.LOCAL_BEHAVIOUR_COPY, targetContext, false, false, getStorageManager());
newUpload.addRenameUploadListener(() -> {
// dummy
});
newUpload.setRemoteFolderToBeCreated();
RemoteOperationResult result = newUpload.execute(client);
assertTrue(result.getLogMessage(), result.isSuccess());
}
use of com.owncloud.android.operations.UploadFileOperation in project android by nextcloud.
the class AbstractOnServerIT method uploadOCUpload.
public void uploadOCUpload(OCUpload ocUpload, int localBehaviour) {
ConnectivityService connectivityServiceMock = new ConnectivityService() {
@Override
public boolean isInternetWalled() {
return false;
}
@Override
public Connectivity getConnectivity() {
return Connectivity.CONNECTED_WIFI;
}
};
PowerManagementService powerManagementServiceMock = new PowerManagementService() {
@NonNull
@Override
public BatteryStatus getBattery() {
return new BatteryStatus();
}
@Override
public boolean isPowerSavingEnabled() {
return false;
}
@Override
public boolean isPowerSavingExclusionAvailable() {
return false;
}
};
UserAccountManager accountManager = UserAccountManagerImpl.fromContext(targetContext);
UploadsStorageManager uploadsStorageManager = new UploadsStorageManager(accountManager, targetContext.getContentResolver());
UploadFileOperation newUpload = new UploadFileOperation(uploadsStorageManager, connectivityServiceMock, powerManagementServiceMock, user, null, ocUpload, NameCollisionPolicy.DEFAULT, localBehaviour, targetContext, false, false, getStorageManager());
newUpload.addRenameUploadListener(() -> {
// dummy
});
newUpload.setRemoteFolderToBeCreated();
RemoteOperationResult result = newUpload.execute(client);
assertTrue(result.getLogMessage(), result.isSuccess());
OCFile parentFolder = getStorageManager().getFileByEncryptedRemotePath(new File(ocUpload.getRemotePath()).getParent() + "/");
String uploadedFileName = new File(ocUpload.getRemotePath()).getName();
OCFile uploadedFile = getStorageManager().getFileByDecryptedRemotePath(parentFolder.getDecryptedRemotePath() + uploadedFileName);
assertNotNull(uploadedFile.getRemoteId());
if (localBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY || localBehaviour == FileUploader.LOCAL_BEHAVIOUR_MOVE) {
assertTrue(new File(uploadedFile.getStoragePath()).exists());
}
}
use of com.owncloud.android.operations.UploadFileOperation in project android by nextcloud.
the class UploadIT method testUploadOnWifiOnlyButNoWifi.
@Test
public void testUploadOnWifiOnlyButNoWifi() {
ConnectivityService connectivityServiceMock = new ConnectivityService() {
@Override
public boolean isInternetWalled() {
return false;
}
@Override
public Connectivity getConnectivity() {
return new Connectivity(true, false, false, true);
}
};
OCUpload ocUpload = new OCUpload(FileStorageUtils.getTemporalPath(account.name) + "/empty.txt", FOLDER + "noWifi.txt", account.name);
ocUpload.setUseWifiOnly(true);
UploadFileOperation newUpload = new UploadFileOperation(uploadsStorageManager, connectivityServiceMock, powerManagementServiceMock, user, null, ocUpload, NameCollisionPolicy.DEFAULT, FileUploader.LOCAL_BEHAVIOUR_COPY, targetContext, true, false, getStorageManager());
newUpload.setRemoteFolderToBeCreated();
newUpload.addRenameUploadListener(() -> {
// dummy
});
RemoteOperationResult result = newUpload.execute(client);
assertFalse(result.toString(), result.isSuccess());
assertEquals(RemoteOperationResult.ResultCode.DELAYED_FOR_WIFI, result.getCode());
}
Aggregations