use of com.owncloud.android.datamodel.ArbitraryDataProvider in project android by nextcloud.
the class FilesSyncHelper method insertAllDBEntriesForSyncedFolder.
public static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) {
final Context context = MainApp.getAppContext();
final ContentResolver contentResolver = context.getContentResolver();
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(contentResolver);
Long currentTime = System.currentTimeMillis();
double currentTimeInSeconds = currentTime / 1000.0;
String currentTimeString = Long.toString((long) currentTimeInSeconds);
String syncedFolderInitiatedKey = SYNCEDFOLDERINITIATED + syncedFolder.getId();
boolean dryRun = TextUtils.isEmpty(arbitraryDataProvider.getValue(GLOBAL, syncedFolderInitiatedKey));
if (MediaFolderType.IMAGE == syncedFolder.getType()) {
if (dryRun) {
arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, currentTimeString);
} else {
FilesSyncHelper.insertContentIntoDB(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, syncedFolder);
FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, syncedFolder);
}
} else if (MediaFolderType.VIDEO == syncedFolder.getType()) {
if (dryRun) {
arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, currentTimeString);
} else {
FilesSyncHelper.insertContentIntoDB(android.provider.MediaStore.Video.Media.INTERNAL_CONTENT_URI, syncedFolder);
FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, syncedFolder);
}
} else {
try {
if (dryRun) {
arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, currentTimeString);
} else {
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
Path path = Paths.get(syncedFolder.getLocalPath());
String dateInitiated = arbitraryDataProvider.getValue(GLOBAL, syncedFolderInitiatedKey);
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
File file = path.toFile();
if (attrs.lastModifiedTime().toMillis() >= Long.parseLong(dateInitiated) * 1000) {
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(), attrs.lastModifiedTime().toMillis(), file.isDirectory(), syncedFolder);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
}
} catch (IOException e) {
Log.e(TAG, "Something went wrong while indexing files for auto upload " + e.getLocalizedMessage());
}
}
}
use of com.owncloud.android.datamodel.ArbitraryDataProvider in project android by nextcloud.
the class PreferenceManager method setFolderPreference.
/**
* Set preference value for a folder.
*
* @param context Context object.
* @param preferenceName Name of the preference to set.
* @param folder Folder.
* @param value Preference value to set.
*/
public static void setFolderPreference(Context context, String preferenceName, OCFile folder, String value) {
Account account = AccountUtils.getCurrentOwnCloudAccount(context);
ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
dataProvider.storeOrUpdateKeyValue(account.name, getKeyFromFolder(preferenceName, folder), value);
}
use of com.owncloud.android.datamodel.ArbitraryDataProvider in project android by nextcloud.
the class ContactsBackupJob method onRunJob.
@NonNull
@Override
protected Result onRunJob(@NonNull Params params) {
final Context context = MainApp.getAppContext();
PersistableBundleCompat bundle = params.getExtras();
boolean force = bundle.getBoolean(FORCE, false);
final Account account = AccountUtils.getOwnCloudAccountByName(context, bundle.getString(ACCOUNT, ""));
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
Long lastExecution = arbitraryDataProvider.getLongValue(account, ContactsPreferenceActivity.PREFERENCE_CONTACTS_LAST_BACKUP);
if (force || (lastExecution + 24 * 60 * 60 * 1000) < Calendar.getInstance().getTimeInMillis()) {
Log_OC.d(TAG, "start contacts backup job");
String backupFolder = getContext().getResources().getString(R.string.contacts_backup_folder) + OCFile.PATH_SEPARATOR;
Integer daysToExpire = getContext().getResources().getInteger(R.integer.contacts_backup_expire);
backupContact(account, backupFolder);
// bind to Operations Service
operationsServiceConnection = new OperationsServiceConnection(daysToExpire, backupFolder, account);
getContext().bindService(new Intent(getContext(), OperationsService.class), operationsServiceConnection, OperationsService.BIND_AUTO_CREATE);
// store execution date
arbitraryDataProvider.storeOrUpdateKeyValue(account.name, ContactsPreferenceActivity.PREFERENCE_CONTACTS_LAST_BACKUP, String.valueOf(Calendar.getInstance().getTimeInMillis()));
} else {
Log_OC.d(TAG, "last execution less than 24h ago");
}
return Result.SUCCESS;
}
use of com.owncloud.android.datamodel.ArbitraryDataProvider in project android by nextcloud.
the class UploadFileOperation method encryptedUpload.
// gson cannot handle sparse arrays easily, therefore use hashmap
@SuppressLint("AndroidLintUseSparseArrays")
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private RemoteOperationResult encryptedUpload(OwnCloudClient client, OCFile parentFile) {
RemoteOperationResult result = null;
File temporalFile = null;
File originalFile = new File(mOriginalStoragePath);
File expectedFile = null;
FileLock fileLock = null;
long size;
boolean metadataExists = false;
String token = null;
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
String privateKey = arbitraryDataProvider.getValue(getAccount().name, EncryptionUtils.PRIVATE_KEY);
String publicKey = arbitraryDataProvider.getValue(getAccount().name, EncryptionUtils.PUBLIC_KEY);
try {
// check conditions
result = checkConditions(originalFile);
if (result != null) {
return result;
}
/**
*** E2E ****
*/
// Lock folder
LockFileOperation lockFileOperation = new LockFileOperation(parentFile.getLocalId());
RemoteOperationResult lockFileOperationResult = lockFileOperation.execute(client, true);
if (lockFileOperationResult.isSuccess()) {
token = (String) lockFileOperationResult.getData().get(0);
// immediately store it
mUpload.setFolderUnlockToken(token);
uploadsStorageManager.updateUpload(mUpload);
} else if (lockFileOperationResult.getHttpCode() == HttpStatus.SC_FORBIDDEN) {
throw new Exception("Forbidden! Please try again later.)");
} else {
throw new Exception("Unknown error!");
}
// Update metadata
GetMetadataOperation getMetadataOperation = new GetMetadataOperation(parentFile.getLocalId());
RemoteOperationResult getMetadataOperationResult = getMetadataOperation.execute(client, true);
DecryptedFolderMetadata metadata;
if (getMetadataOperationResult.isSuccess()) {
metadataExists = true;
// decrypt metadata
String serializedEncryptedMetadata = (String) getMetadataOperationResult.getData().get(0);
EncryptedFolderMetadata encryptedFolderMetadata = EncryptionUtils.deserializeJSON(serializedEncryptedMetadata, new TypeToken<EncryptedFolderMetadata>() {
});
metadata = EncryptionUtils.decryptFolderMetaData(encryptedFolderMetadata, privateKey);
} else if (getMetadataOperationResult.getHttpCode() == HttpStatus.SC_NOT_FOUND) {
// new metadata
metadata = new DecryptedFolderMetadata();
metadata.setMetadata(new DecryptedFolderMetadata.Metadata());
metadata.getMetadata().setMetadataKeys(new HashMap<>());
String metadataKey = EncryptionUtils.encodeBytesToBase64String(EncryptionUtils.generateKey());
String encryptedMetadataKey = EncryptionUtils.encryptStringAsymmetric(metadataKey, publicKey);
metadata.getMetadata().getMetadataKeys().put(0, encryptedMetadataKey);
} else {
// TODO error
throw new Exception("something wrong");
}
/**
*** E2E ****
*/
// check name collision
checkNameCollision(client, metadata, parentFile.isEncrypted());
String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
expectedFile = new File(expectedPath);
result = copyFile(originalFile, expectedPath);
if (result != null) {
return result;
}
// Get the last modification date of the file from the file system
Long timeStampLong = originalFile.lastModified() / 1000;
String timeStamp = timeStampLong.toString();
/**
*** E2E ****
*/
// Key, always generate new one
byte[] key = EncryptionUtils.generateKey();
// IV, always generate new one
byte[] iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength);
EncryptionUtils.EncryptedFile encryptedFile = EncryptionUtils.encryptFile(mFile, key, iv);
// new random file name, check if it exists in metadata
String encryptedFileName = UUID.randomUUID().toString().replaceAll("-", "");
while (metadata.getFiles().get(encryptedFileName) != null) {
encryptedFileName = UUID.randomUUID().toString().replaceAll("-", "");
}
mFile.setEncryptedFileName(encryptedFileName);
File encryptedTempFile = File.createTempFile("encFile", encryptedFileName);
FileOutputStream fileOutputStream = new FileOutputStream(encryptedTempFile);
fileOutputStream.write(encryptedFile.encryptedBytes);
fileOutputStream.close();
/**
*** E2E ****
*/
FileChannel channel = null;
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.getTemporalPath(mAccount.name) + mFile.getRemotePath();
mFile.setStoragePath(temporalPath);
temporalFile = new File(temporalPath);
Files.deleteIfExists(Paths.get(temporalPath));
result = copy(originalFile, temporalFile);
if (result == null) {
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 (IOException e1) {
size = new File(mFile.getStoragePath()).length();
}
for (OCUpload ocUpload : uploadsStorageManager.getAllStoredUploads()) {
if (ocUpload.getUploadId() == getOCUploadId()) {
ocUpload.setFileSize(size);
uploadsStorageManager.updateUpload(ocUpload);
break;
}
}
// / perform the upload
if (mChunked && (size > ChunkedUploadRemoteFileOperation.CHUNK_SIZE)) {
mUploadOperation = new ChunkedUploadRemoteFileOperation(mContext, encryptedTempFile.getAbsolutePath(), mFile.getParentRemotePath() + encryptedFileName, mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
} else {
mUploadOperation = new UploadRemoteFileOperation(encryptedTempFile.getAbsolutePath(), mFile.getParentRemotePath() + encryptedFileName, mFile.getMimetype(), mFile.getEtagInConflict(), timeStamp);
}
Iterator<OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
while (listener.hasNext()) {
mUploadOperation.addDatatransferProgressListener(listener.next());
}
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
result = mUploadOperation.execute(client, true);
// location in the Nextcloud local folder
if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
}
if (result.isSuccess()) {
// upload metadata
DecryptedFolderMetadata.DecryptedFile decryptedFile = new DecryptedFolderMetadata.DecryptedFile();
DecryptedFolderMetadata.Data data = new DecryptedFolderMetadata.Data();
data.setFilename(mFile.getFileName());
data.setMimetype(mFile.getMimetype());
data.setKey(EncryptionUtils.encodeBytesToBase64String(key));
decryptedFile.setEncrypted(data);
decryptedFile.setInitializationVector(EncryptionUtils.encodeBytesToBase64String(iv));
decryptedFile.setAuthenticationTag(encryptedFile.authenticationTag);
metadata.getFiles().put(encryptedFileName, decryptedFile);
EncryptedFolderMetadata encryptedFolderMetadata = EncryptionUtils.encryptFolderMetadata(metadata, privateKey);
String serializedFolderMetadata = EncryptionUtils.serializeJSON(encryptedFolderMetadata);
// upload metadata
RemoteOperationResult uploadMetadataOperationResult;
if (metadataExists) {
// update metadata
UpdateMetadataOperation storeMetadataOperation = new UpdateMetadataOperation(parentFile.getLocalId(), serializedFolderMetadata, token);
uploadMetadataOperationResult = storeMetadataOperation.execute(client, true);
} else {
// store metadata
StoreMetadataOperation storeMetadataOperation = new StoreMetadataOperation(parentFile.getLocalId(), serializedFolderMetadata);
uploadMetadataOperationResult = storeMetadataOperation.execute(client, true);
}
if (!uploadMetadataOperationResult.isSuccess()) {
throw new Exception();
}
}
} catch (FileNotFoundException e) {
Log_OC.d(TAG, mFile.getStoragePath() + " not exists anymore");
result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
} catch (OverlappingFileLockException e) {
Log_OC.d(TAG, "Overlapping file lock exception");
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
} catch (Exception e) {
result = new RemoteOperationResult(e);
} finally {
mUploadStarted.set(false);
if (fileLock != null) {
try {
fileLock.release();
} catch (IOException e) {
Log_OC.e(TAG, "Failed to unlock file with path " + mFile.getStoragePath());
}
}
if (temporalFile != null && !originalFile.equals(temporalFile)) {
temporalFile.delete();
}
if (result == null) {
result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
}
if (result.isSuccess()) {
Log_OC.i(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " + result.getLogMessage());
} else {
if (result.getException() != null) {
if (result.isCancelled()) {
Log_OC.w(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " + result.getLogMessage());
} else {
Log_OC.e(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " + result.getLogMessage(), result.getException());
}
} else {
Log_OC.e(TAG, "Upload of " + mFile.getStoragePath() + " to " + mFile.getRemotePath() + ": " + result.getLogMessage());
}
}
}
if (result.isSuccess()) {
handleSuccessfulUpload(temporalFile, expectedFile, originalFile, client);
RemoteOperationResult unlockFolderResult = unlockFolder(parentFile, client, token);
if (!unlockFolderResult.isSuccess()) {
return unlockFolderResult;
}
} else if (result.getCode() == ResultCode.SYNC_CONFLICT) {
getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
}
return result;
}
use of com.owncloud.android.datamodel.ArbitraryDataProvider in project android by nextcloud.
the class Preferences method setupAutoUploadCategory.
private void setupAutoUploadCategory(int accentColor, PreferenceScreen preferenceScreen) {
PreferenceCategory preferenceCategorySyncedFolders = (PreferenceCategory) findPreference("synced_folders_category");
preferenceCategorySyncedFolders.setTitle(ThemeUtils.getColoredTitle(getString(R.string.drawer_synced_folders), accentColor));
if (!getResources().getBoolean(R.bool.syncedFolder_light)) {
preferenceScreen.removePreference(preferenceCategorySyncedFolders);
} else {
// Upload on WiFi
final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
final Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
final SwitchPreference pUploadOnWifiCheckbox = (SwitchPreference) findPreference("synced_folder_on_wifi");
pUploadOnWifiCheckbox.setChecked(arbitraryDataProvider.getBooleanValue(account, SYNCED_FOLDER_LIGHT_UPLOAD_ON_WIFI));
pUploadOnWifiCheckbox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
arbitraryDataProvider.storeOrUpdateKeyValue(account.name, SYNCED_FOLDER_LIGHT_UPLOAD_ON_WIFI, String.valueOf(pUploadOnWifiCheckbox.isChecked()));
return true;
}
});
Preference pSyncedFolder = findPreference("synced_folders_configure_folders");
if (pSyncedFolder != null) {
if (getResources().getBoolean(R.bool.syncedFolder_light) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
pSyncedFolder.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent syncedFoldersIntent = new Intent(getApplicationContext(), SyncedFoldersActivity.class);
syncedFoldersIntent.putExtra(SyncedFoldersActivity.EXTRA_SHOW_SIDEBAR, false);
startActivity(syncedFoldersIntent);
return true;
}
});
} else {
preferenceCategorySyncedFolders.removePreference(pSyncedFolder);
}
}
}
}
Aggregations