diff --git a/.gitignore b/.gitignore index c4f61d1c..30e3fc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,18 @@ *.iml *.ipr *.iws -.idea/ +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/**/libraries/ +.idea/caches +.idea/modules.xml +.idea/navEditor.xml +.idea/encodings.xml +.idea/compiler.xml +.idea/jarRepositories.xml ###Android### diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..ad42ec10 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,187 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100755 index 00000000..82c2e2f0 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..77121615 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100755 index 00000000..085a74d0 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100755 index 00000000..50124b03 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100755 index 00000000..7f68460d --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100755 index 00000000..286a07d2 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/data/src/main/java/org/cryptomator/data/cloud/InterceptingCloudContentRepository.java b/data/src/main/java/org/cryptomator/data/cloud/InterceptingCloudContentRepository.java index 6fc502d7..b5a03ded 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/InterceptingCloudContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/cloud/InterceptingCloudContentRepository.java @@ -16,8 +16,7 @@ import java.io.File; import java.io.OutputStream; import java.util.List; -public abstract class InterceptingCloudContentRepository - implements CloudContentRepository { +public abstract class InterceptingCloudContentRepository implements CloudContentRepository { private final CloudContentRepository delegate; diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloud.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloud.java index 102b6265..ca6dd52e 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloud.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloud.java @@ -52,10 +52,12 @@ public class CryptoCloud implements Cloud { @Override public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) + if (obj == null || getClass() != obj.getClass()) { return false; - if (obj == this) + } + if (obj == this) { return true; + } return internalEquals((CryptoCloud) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepository.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepository.java index 597a80b8..5719ca71 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepository.java @@ -1,10 +1,6 @@ package org.cryptomator.data.cloud.crypto; -import static java.lang.String.format; - -import java.io.File; -import java.io.OutputStream; -import java.util.List; +import android.content.Context; import org.cryptomator.cryptolib.api.Cryptor; import org.cryptomator.domain.CloudFolder; @@ -19,7 +15,11 @@ import org.cryptomator.domain.usecases.cloud.UploadState; import org.cryptomator.util.Optional; import org.cryptomator.util.Supplier; -import android.content.Context; +import java.io.File; +import java.io.OutputStream; +import java.util.List; + +import static java.lang.String.format; class CryptoCloudContentRepository implements CloudContentRepository { @@ -34,15 +34,15 @@ class CryptoCloudContentRepository implements CloudContentRepository progressAware, boolean replace) - throws BackendException, IOException { + private CryptoFile writeFromTmpFile(DataSource originalDataSource, final CryptoFile cryptoFile, File encryptedFile, final ProgressAware progressAware, boolean replace) throws BackendException, IOException { CryptoFile targetFile = targetFile(cryptoFile, replace); return file(targetFile, // cloudContentRepository.write( // @@ -298,8 +297,8 @@ abstract class CryptoImplDecorator { try { File encryptedTmpFile = readToTmpFile(cryptoFile, ciphertextFile, progressAware); progressAware.onProgress(Progress.started(DownloadState.decryption(cryptoFile))); - try (ReadableByteChannel readableByteChannel = Channels.newChannel(new FileInputStream(encryptedTmpFile)); - ReadableByteChannel decryptingReadableByteChannel = new DecryptingReadableByteChannel(readableByteChannel, cryptor(), true)) { + try (ReadableByteChannel readableByteChannel = Channels.newChannel(new FileInputStream(encryptedTmpFile)); // + ReadableByteChannel decryptingReadableByteChannel = new DecryptingReadableByteChannel(readableByteChannel, cryptor(), true)) { ByteBuffer buff = ByteBuffer.allocate(cryptor().fileContentCryptor().ciphertextChunkSize()); long cleartextSize = cryptoFile.getSize().orElse(Long.MAX_VALUE); long decrypted = 0; @@ -395,8 +394,8 @@ abstract class CryptoImplDecorator { } try (InputStream stream = data.open(context)) { File encryptedTmpFile = File.createTempFile(UUID.randomUUID().toString(), ".crypto", getInternalCache()); - try (WritableByteChannel writableByteChannel = Channels.newChannel(new FileOutputStream(encryptedTmpFile)); - WritableByteChannel encryptingWritableByteChannel = new EncryptingWritableByteChannel(writableByteChannel, cryptor())) { + try (WritableByteChannel writableByteChannel = Channels.newChannel(new FileOutputStream(encryptedTmpFile)); // + WritableByteChannel encryptingWritableByteChannel = new EncryptingWritableByteChannel(writableByteChannel, cryptor())) { progressAware.onProgress(Progress.started(UploadState.encryption(cryptoFile))); ByteBuffer buff = ByteBuffer.allocate(cryptor().fileContentCryptor().cleartextChunkSize()); long ciphertextSize = Cryptors.ciphertextSize(cryptoFile.getSize().get(), cryptor()) + cryptor().fileHeaderCryptor().headerSize(); diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.java index 7bd37584..2cdc7467 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7.java @@ -189,14 +189,14 @@ final class CryptoImplVaultFormat7 extends CryptoImplDecorator { for (CloudNode cloudNode1 : subfiles) { switch (cloudNode1.getName()) { - case LONG_NODE_FILE_CONTENT_CONTENTS + CLOUD_NODE_EXT: - longNameFile = Optional.of((CloudFile) cloudNode1); - break; - case CLOUD_FOLDER_DIR_FILE_PRE + CLOUD_NODE_EXT: - longNameFolderDirFile = Optional.of((CloudFile) cloudNode1); - break; - case CLOUD_NODE_SYMLINK_PRE + CLOUD_NODE_EXT: - return Optional.empty(); + case LONG_NODE_FILE_CONTENT_CONTENTS + CLOUD_NODE_EXT: + longNameFile = Optional.of((CloudFile) cloudNode1); + break; + case CLOUD_FOLDER_DIR_FILE_PRE + CLOUD_NODE_EXT: + longNameFolderDirFile = Optional.of((CloudFile) cloudNode1); + break; + case CLOUD_NODE_SYMLINK_PRE + CLOUD_NODE_EXT: + return Optional.empty(); } } } @@ -472,7 +472,7 @@ final class CryptoImplVaultFormat7 extends CryptoImplDecorator { try (InputStream stream = data.open(context)) { File encryptedTmpFile = File.createTempFile(UUID.randomUUID().toString(), ".crypto", getInternalCache()); try (WritableByteChannel writableByteChannel = Channels.newChannel(new FileOutputStream(encryptedTmpFile)); // - WritableByteChannel encryptingWritableByteChannel = new EncryptingWritableByteChannel(writableByteChannel, cryptor())) { + WritableByteChannel encryptingWritableByteChannel = new EncryptingWritableByteChannel(writableByteChannel, cryptor())) { progressAware.onProgress(Progress.started(UploadState.encryption(cloudFile))); ByteBuffer buff = ByteBuffer.allocate(cryptor().fileContentCryptor().cleartextChunkSize()); long ciphertextSize = Cryptors.ciphertextSize(cloudFile.getSize().get(), cryptor()) + cryptor().fileHeaderCryptor().headerSize(); diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoNode.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoNode.java index bd22fca3..fc4fd2ff 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoNode.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoNode.java @@ -3,4 +3,5 @@ package org.cryptomator.data.cloud.crypto; import org.cryptomator.domain.CloudNode; interface CryptoNode extends CloudNode { + } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoSymlink.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoSymlink.java index 4c9d6e77..8960aea2 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoSymlink.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoSymlink.java @@ -61,10 +61,12 @@ class CryptoSymlink implements CloudFile, CryptoNode { @Override public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) + if (obj == null || getClass() != obj.getClass()) { return false; - if (obj == this) + } + if (obj == this) { return true; + } return internalEquals((CryptoSymlink) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.java index 6ac46823..73f079bd 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.java @@ -1,16 +1,16 @@ package org.cryptomator.data.cloud.crypto; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.cryptomator.cryptolib.api.Cryptor; import org.cryptomator.domain.Vault; import org.cryptomator.domain.exception.MissingCryptorException; import org.cryptomator.util.Optional; import org.cryptomator.util.Supplier; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + public abstract class Cryptors { Cryptors() { diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormat7.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormat7.java index 853366aa..e42ae764 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormat7.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormat7.java @@ -1,9 +1,9 @@ package org.cryptomator.data.cloud.crypto; -import java.util.Map; - import android.util.LruCache; +import java.util.Map; + class DirIdCacheFormat7 implements DirIdCache { private static final int MAX_SIZE = 1024; @@ -43,22 +43,24 @@ class DirIdCacheFormat7 implements DirIdCache { private static class DirIdCacheKey { - static DirIdCacheKey toKey(CryptoFolder folder) { - return new DirIdCacheKey(folder.getPath()); - } - private final String path; private DirIdCacheKey(String path) { this.path = path; } + static DirIdCacheKey toKey(CryptoFolder folder) { + return new DirIdCacheKey(folder.getPath()); + } + @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((DirIdCacheKey) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormatPre7.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormatPre7.java index 2235420e..62337ba6 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormatPre7.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/DirIdCacheFormatPre7.java @@ -39,10 +39,6 @@ class DirIdCacheFormatPre7 implements DirIdCache { private static class DirIdCacheKey { - static DirIdCacheKey toKey(CryptoFolder folder) { - return new DirIdCacheKey(folder.getDirFile()); - } - private final String path; private final Date modified; @@ -56,16 +52,22 @@ class DirIdCacheFormatPre7 implements DirIdCache { this.modified = null; } + static DirIdCacheKey toKey(CryptoFolder folder) { + return new DirIdCacheKey(folder.getDirFile()); + } + DirIdCacheKey withoutModified() { return new DirIdCacheKey(path); } @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((DirIdCacheKey) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/RootCryptoFolder.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/RootCryptoFolder.java index 80594edc..f1fee965 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/RootCryptoFolder.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/RootCryptoFolder.java @@ -4,10 +4,6 @@ import org.cryptomator.domain.Cloud; class RootCryptoFolder extends CryptoFolder { - public static boolean isRoot(CryptoFolder folder) { - return folder instanceof RootCryptoFolder; - } - private final CryptoCloud cloud; public RootCryptoFolder(CryptoCloud cloud) { @@ -15,6 +11,10 @@ class RootCryptoFolder extends CryptoFolder { this.cloud = cloud; } + public static boolean isRoot(CryptoFolder folder) { + return folder instanceof RootCryptoFolder; + } + @Override public Cloud getCloud() { return cloud; diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.java b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.java index efddfdf0..78e403b6 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxClientFactory.java @@ -23,6 +23,10 @@ class DropboxClientFactory { private DbxClientV2 sDbxClient; + private static Interceptor httpLoggingInterceptor(Context context) { + return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context); + } + public DbxClientV2 getClient(String accessToken, Context context) { if (sDbxClient == null) { sDbxClient = createDropboxClient(accessToken, context); @@ -49,8 +53,4 @@ class DropboxClientFactory { return new DbxClientV2(requestConfig, accessToken); } - - private static Interceptor httpLoggingInterceptor(Context context) { - return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context); - } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudNodeFactory.java b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudNodeFactory.java index d5f5439e..6c931587 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudNodeFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxCloudNodeFactory.java @@ -1,11 +1,11 @@ package org.cryptomator.data.cloud.dropbox; -import org.cryptomator.util.Optional; - import com.dropbox.core.v2.files.FileMetadata; import com.dropbox.core.v2.files.FolderMetadata; import com.dropbox.core.v2.files.Metadata; +import org.cryptomator.util.Optional; + class DropboxCloudNodeFactory { public static DropboxFile from(DropboxFolder parent, FileMetadata metadata) { diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.java b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.java index 19fa607b..f886857f 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.java +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxImpl.java @@ -79,6 +79,14 @@ class DropboxImpl { sharedPreferencesHandler = new SharedPreferencesHandler(context); } + private static void sleepQuietly(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException ex) { + throw new FatalBackendException("Error uploading to Dropbox: interrupted during backoff."); + } + } + private DbxClientV2 client() throws AuthenticationException { return clientFactory.getClient(decrypt(cloud.accessToken()), context); } @@ -186,8 +194,7 @@ class DropboxImpl { relocationResult.getMetadata()); } - public DropboxFile write(DropboxFile file, DataSource data, final ProgressAware progressAware, boolean replace, long size) - throws AuthenticationException, DbxException, IOException, CloudNodeAlreadyExistsException { + public DropboxFile write(DropboxFile file, DataSource data, final ProgressAware progressAware, boolean replace, long size) throws AuthenticationException, DbxException, IOException, CloudNodeAlreadyExistsException { if (exists(file) && !replace) { throw new CloudNodeAlreadyExistsException("CloudNode already exists and replace is false"); } @@ -237,8 +244,7 @@ class DropboxImpl { } } - private void chunkedUploadFile(final DropboxFile file, DataSource data, final ProgressAware progressAware, WriteMode writeMode, final long size) - throws AuthenticationException, DbxException, IOException { + private void chunkedUploadFile(final DropboxFile file, DataSource data, final ProgressAware progressAware, WriteMode writeMode, final long size) throws AuthenticationException, DbxException, IOException { // Assert our file is at least the chunk upload size. We make this assumption in the code // below to simplify the logic. if (size < CHUNKED_UPLOAD_CHUNK_SIZE) { @@ -348,8 +354,8 @@ class DropboxImpl { // the expected offset according to the server and try again. uploaded = ex. // errorValue. // - getIncorrectOffsetValue(). // - getCorrectOffset(); + getIncorrectOffsetValue(). // + getCorrectOffset(); } else { throw new FatalBackendException(ex); } @@ -360,9 +366,9 @@ class DropboxImpl { // the expected offset according to the server and try again. uploaded = ex. // errorValue. // - getLookupFailedValue(). // - getIncorrectOffsetValue(). // - getCorrectOffset(); + getLookupFailedValue(). // + getIncorrectOffsetValue(). // + getCorrectOffset(); } else { throw new FatalBackendException(ex); } @@ -457,12 +463,4 @@ class DropboxImpl { .getCurrentAccount(); return currentAccount.getName().getDisplayName(); } - - private static void sleepQuietly(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException ex) { - throw new FatalBackendException("Error uploading to Dropbox: interrupted during backoff."); - } - } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxNode.java b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxNode.java index 665e7d0a..9d6a6aa2 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxNode.java +++ b/data/src/main/java/org/cryptomator/data/cloud/dropbox/DropboxNode.java @@ -3,4 +3,5 @@ package org.cryptomator.data.cloud.dropbox; import org.cryptomator.domain.CloudNode; interface DropboxNode extends CloudNode { + } diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/file/LocalNode.java b/data/src/main/java/org/cryptomator/data/cloud/local/file/LocalNode.java index aa3ee16e..dc9e9d02 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/file/LocalNode.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/file/LocalNode.java @@ -3,4 +3,5 @@ package org.cryptomator.data.cloud.local.file; import org.cryptomator.domain.CloudNode; interface LocalNode extends CloudNode { + } diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFile.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFile.java index 33a73aa6..a65a5de8 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFile.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFile.java @@ -72,10 +72,12 @@ class LocalStorageAccessFile implements CloudFile, LocalStorageAccessNode { @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((LocalStorageAccessFile) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFolder.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFolder.java index cf6e9071..a392f618 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFolder.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFolder.java @@ -59,10 +59,12 @@ class LocalStorageAccessFolder implements CloudFolder, LocalStorageAccessNode { @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((LocalStorageAccessFolder) obj); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkContentRepository.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkContentRepository.java index 809ea2cc..a880b696 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkContentRepository.java @@ -3,6 +3,8 @@ package org.cryptomator.data.cloud.local.storageaccessframework; import android.content.Context; import android.os.Build; +import androidx.annotation.RequiresApi; + import org.cryptomator.domain.CloudNode; import org.cryptomator.domain.LocalStorageCloud; import org.cryptomator.domain.exception.BackendException; @@ -21,8 +23,6 @@ import java.io.IOException; import java.io.OutputStream; import java.util.List; -import androidx.annotation.RequiresApi; - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) public class LocalStorageAccessFrameworkContentRepository implements CloudContentRepository { diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkImpl.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkImpl.java index 9e58eefa..44f7cde6 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkImpl.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkImpl.java @@ -1,18 +1,16 @@ package org.cryptomator.data.cloud.local.storageaccessframework; -import static org.cryptomator.data.cloud.local.storageaccessframework.LocalStorageAccessFrameworkNodeFactory.from; -import static org.cryptomator.data.util.CopyStream.closeQuietly; -import static org.cryptomator.data.util.CopyStream.copyStreamToStream; -import static org.cryptomator.domain.usecases.ProgressAware.NO_OP_PROGRESS_AWARE; -import static org.cryptomator.domain.usecases.cloud.Progress.progress; +import android.content.ContentResolver; +import android.content.Context; +import android.content.UriPermission; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.provider.DocumentsContract; +import android.provider.DocumentsContract.Document; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; +import androidx.annotation.RequiresApi; +import androidx.documentfile.provider.DocumentFile; import org.cryptomator.data.util.TransferredBytesAwareInputStream; import org.cryptomator.data.util.TransferredBytesAwareOutputStream; @@ -35,20 +33,22 @@ import org.cryptomator.util.Supplier; import org.cryptomator.util.file.MimeType; import org.cryptomator.util.file.MimeTypes; -import android.content.ContentResolver; -import android.content.Context; -import android.content.UriPermission; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.provider.DocumentsContract; -import android.provider.DocumentsContract.Document; - -import androidx.annotation.RequiresApi; -import androidx.documentfile.provider.DocumentFile; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; import timber.log.Timber; +import static org.cryptomator.data.cloud.local.storageaccessframework.LocalStorageAccessFrameworkNodeFactory.from; +import static org.cryptomator.data.util.CopyStream.closeQuietly; +import static org.cryptomator.data.util.CopyStream.copyStreamToStream; +import static org.cryptomator.domain.usecases.ProgressAware.NO_OP_PROGRESS_AWARE; +import static org.cryptomator.domain.usecases.cloud.Progress.progress; + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) class LocalStorageAccessFrameworkImpl { @@ -178,7 +178,7 @@ class LocalStorageAccessFrameworkImpl { .query( // DocumentsContract.buildChildDocumentsUriUsingTree( // parent.getUri(), // - parent.getDocumentId()), + parent.getDocumentId()), // new String[] {Document.COLUMN_DISPLAY_NAME, // cursor position 0 Document.COLUMN_MIME_TYPE, // cursor position 1 Document.COLUMN_SIZE, // cursor position 2 @@ -230,7 +230,7 @@ class LocalStorageAccessFrameworkImpl { .query( // DocumentsContract.buildChildDocumentsUriUsingTree( // folder.getUri(), // - folder.getDocumentId()), + folder.getDocumentId()), // new String[] { // Document.COLUMN_DISPLAY_NAME, // cursor position 0 Document.COLUMN_MIME_TYPE, // cursor position 1 @@ -445,16 +445,16 @@ class LocalStorageAccessFrameworkImpl { } try (OutputStream out = contentResolver().openOutputStream(uploadUri); // - TransferredBytesAwareInputStream in = new TransferredBytesAwareInputStream(data.open(context)) { - @Override - public void bytesTransferred(long transferred) { - progressAware // - .onProgress(progress(UploadState.upload(tmpFile)) // - .between(0) // - .and(size) // - .withValue(transferred)); - } - }) { + TransferredBytesAwareInputStream in = new TransferredBytesAwareInputStream(data.open(context)) { + @Override + public void bytesTransferred(long transferred) { + progressAware // + .onProgress(progress(UploadState.upload(tmpFile)) // + .between(0) // + .and(size) // + .withValue(transferred)); + } + }) { if (out instanceof FileOutputStream) { ((FileOutputStream) out).getChannel().truncate(0); } @@ -500,15 +500,15 @@ class LocalStorageAccessFrameworkImpl { progressAware.onProgress(Progress.started(DownloadState.download(file))); try (InputStream in = contentResolver().openInputStream(file.getUri()); // - TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { - @Override - public void bytesTransferred(long transferred) { - progressAware.onProgress(progress(DownloadState.download(file)) // - .between(0) // - .and(file.getSize().orElse(Long.MAX_VALUE)) // - .withValue(transferred)); - } - }) { + TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { + @Override + public void bytesTransferred(long transferred) { + progressAware.onProgress(progress(DownloadState.download(file)) // + .between(0) // + .and(file.getSize().orElse(Long.MAX_VALUE)) // + .withValue(transferred)); + } + }) { copyStreamToStream(in, out); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkNodeFactory.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkNodeFactory.java index f2cf4df7..6964e315 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkNodeFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/LocalStorageAccessFrameworkNodeFactory.java @@ -4,13 +4,13 @@ import android.database.Cursor; import android.os.Build; import android.provider.DocumentsContract; +import androidx.annotation.RequiresApi; +import androidx.documentfile.provider.DocumentFile; + import org.cryptomator.util.Optional; import java.util.Date; -import androidx.annotation.RequiresApi; -import androidx.documentfile.provider.DocumentFile; - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) class LocalStorageAccessFrameworkNodeFactory { diff --git a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/RootLocalStorageAccessFolder.java b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/RootLocalStorageAccessFolder.java index a5736c89..ccc021a7 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/RootLocalStorageAccessFolder.java +++ b/data/src/main/java/org/cryptomator/data/cloud/local/storageaccessframework/RootLocalStorageAccessFolder.java @@ -3,11 +3,11 @@ package org.cryptomator.data.cloud.local.storageaccessframework; import android.os.Build; import android.provider.DocumentsContract; +import androidx.annotation.RequiresApi; + import org.cryptomator.domain.Cloud; import org.cryptomator.domain.LocalStorageCloud; -import androidx.annotation.RequiresApi; - import static android.net.Uri.parse; @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @@ -23,9 +23,7 @@ public class RootLocalStorageAccessFolder extends LocalStorageAccessFolder { parse(localStorageCloud.rootUri())), // DocumentsContract.buildChildDocumentsUriUsingTree( // parse(localStorageCloud.rootUri()), // - DocumentsContract.getTreeDocumentId( // - parse(localStorageCloud.rootUri()))) - .toString()); + DocumentsContract.getTreeDocumentId(parse(localStorageCloud.rootUri()))).toString()); this.localStorageCloud = localStorageCloud; } diff --git a/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.java b/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.java index a905d434..0e1b71f9 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.java +++ b/data/src/main/java/org/cryptomator/data/cloud/okhttplogging/HttpLoggingInterceptor.java @@ -29,18 +29,17 @@ public final class HttpLoggingInterceptor implements Interceptor { "Cookie", // "Set-Cookie" // ); - - public interface Logger { - void log(String message); - } + private final Logger logger; + private final Context context; public HttpLoggingInterceptor(Logger logger, Context context) { this.logger = logger; this.context = context; } - private final Logger logger; - private final Context context; + private static boolean debugModeEnabled(Context context) { + return getDefaultSharedPreferences(context).getBoolean("debugMode", false); + } @NotNull @Override @@ -137,11 +136,12 @@ public final class HttpLoggingInterceptor implements Interceptor { } } - private static boolean debugModeEnabled(Context context) { - return getDefaultSharedPreferences(context).getBoolean("debugMode", false); - } - private boolean isExcludedHeader(String name) { return EXCLUDED_HEADERS.contains(name); } + + public interface Logger { + + void log(String message); + } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.java index 6130c9ac..01956cc9 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveClientFactory.java @@ -22,11 +22,9 @@ import static org.cryptomator.data.util.NetworkTimeout.WRITE; public class OnedriveClientFactory { + private static OnedriveClientFactory instance; private final AtomicReference graphServiceClient = new AtomicReference<>(); private final IAuthenticationAdapter authenticationAdapter; - - private static OnedriveClientFactory instance; - private final Context context; private OnedriveClientFactory(Context context, String refreshToken) { @@ -41,6 +39,10 @@ public class OnedriveClientFactory { return instance; } + private static Interceptor httpLoggingInterceptor(Context context) { + return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context); + } + public IGraphServiceClient client() { if (graphServiceClient.get() == null) { @@ -67,10 +69,6 @@ public class OnedriveClientFactory { return graphServiceClient.get(); } - private static Interceptor httpLoggingInterceptor(Context context) { - return new HttpLoggingInterceptor(message -> Timber.tag("OkHttp").d(message), context); - } - public synchronized IAuthenticationAdapter getAuthenticationAdapter() { return authenticationAdapter; } diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudContentRepository.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudContentRepository.java index 56b46baf..4da67edc 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudContentRepository.java @@ -58,7 +58,7 @@ class OnedriveCloudContentRepository extends InterceptingCloudContentRepository< private boolean isAuthenticationError(Throwable e) { return e != null // && ((e instanceof ClientException && ((ClientException) e).errorCode().equals(GraphErrorCodes.AUTHENTICATION_FAILURE)) // - || isAuthenticationError(e.getCause())); + || isAuthenticationError(e.getCause())); } private static class Intercepted implements CloudContentRepository { diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudNodeFactory.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudNodeFactory.java index b8ed36f4..d9968b65 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudNodeFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveCloudNodeFactory.java @@ -58,8 +58,8 @@ class OnedriveCloudNodeFactory { return item.remoteItem != null // ? item.remoteItem.parentReference.driveId // : item.parentReference != null // - ? item.parentReference.driveId // - : null; + ? item.parentReference.driveId // + : null; } public static boolean isFolder(DriveItem item) { diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveHttpProvider.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveHttpProvider.java index 392e817f..f3910ac0 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveHttpProvider.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveHttpProvider.java @@ -21,20 +21,6 @@ // ------------------------------------------------------------------------------ package org.cryptomator.data.cloud.onedrive; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.concurrent.TimeUnit; - import com.google.common.annotations.VisibleForTesting; import com.microsoft.graph.authentication.IAuthenticationProvider; import com.microsoft.graph.concurrency.ICallback; @@ -63,6 +49,20 @@ import com.microsoft.graph.serializer.ISerializer; import org.jetbrains.annotations.NotNull; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.concurrent.TimeUnit; + import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Protocol; @@ -111,10 +111,10 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Creates the DefaultHttpProvider * - * @param serializer the serializer + * @param serializer the serializer * @param authenticationProvider the authentication provider - * @param executors the executors - * @param logger the logger for diagnostic information + * @param executors the executors + * @param logger the logger for diagnostic information */ public OnedriveHttpProvider(final ISerializer serializer, final IAuthenticationProvider authenticationProvider, final IExecutors executors, final ILogger logger) { this.serializer = serializer; @@ -127,13 +127,50 @@ public class OnedriveHttpProvider implements IHttpProvider { * Creates the DefaultHttpProvider * * @param clientConfig the client configuration to use for the provider - * @param httpClient the http client to execute the requests with + * @param httpClient the http client to execute the requests with */ public OnedriveHttpProvider(final IClientConfig clientConfig, final OkHttpClient httpClient) { this(clientConfig.getSerializer(), clientConfig.getAuthenticationProvider(), clientConfig.getExecutors(), clientConfig.getLogger()); this.corehttpClient = httpClient; } + /** + * Reads in a stream and converts it into a string + * + * @param input the response body stream + * @return the string result + */ + public static String streamToString(final InputStream input) { + final String httpStreamEncoding = "UTF-8"; + final String endOfFile = "\\A"; + final Scanner scanner = new Scanner(input, httpStreamEncoding); + String scannerString = ""; + try { + scanner.useDelimiter(endOfFile); + scannerString = scanner.next(); + } finally { + scanner.close(); + } + return scannerString; + } + + /** + * Searches for the given header in a list of HeaderOptions + * + * @param headers the list of headers to search through + * @param header the header name to search for (case insensitive) + * @return true if the header has already been set + */ + @VisibleForTesting + static boolean hasHeader(List headers, String header) { + for (HeaderOption option : headers) { + if (option.getName().equalsIgnoreCase(header)) { + return true; + } + } + return false; + } + /** * Gets the serializer for this HTTP provider * @@ -147,12 +184,12 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Sends the HTTP request asynchronously * - * @param request the request description - * @param callback the callback to be called after success or failure - * @param resultClass the class of the response from the service + * @param request the request description + * @param callback the callback to be called after success or failure + * @param resultClass the class of the response from the service * @param serializable the object to send to the service in the body of the request - * @param the type of the response object - * @param the type of the object to send to the service in the body of the request + * @param the type of the response object + * @param the type of the object to send to the service in the body of the request */ @Override public void send(final IHttpRequest request, final ICallback callback, final Class resultClass, final Body serializable) { @@ -175,11 +212,11 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Sends the HTTP request * - * @param request the request description - * @param resultClass the class of the response from the service + * @param request the request description + * @param resultClass the class of the response from the service * @param serializable the object to send to the service in the body of the request - * @param the type of the response object - * @param the type of the object to send to the service in the body of the request + * @param the type of the response object + * @param the type of the object to send to the service in the body of the request * @return the result from the request * @throws ClientException an exception occurs if the request was unable to complete for any reason */ @@ -191,30 +228,29 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Sends the HTTP request * - * @param request the request description - * @param resultClass the class of the response from the service - * @param serializable the object to send to the service in the body of the request - * @param handler the handler for stateful response - * @param the type of the response object - * @param the type of the object to send to the service in the body of the request + * @param request the request description + * @param resultClass the class of the response from the service + * @param serializable the object to send to the service in the body of the request + * @param handler the handler for stateful response + * @param the type of the response object + * @param the type of the object to send to the service in the body of the request * @param the response handler for stateful response * @return the result from the request * @throws ClientException this exception occurs if the request was unable to complete for any reason */ - public Result send(final IHttpRequest request, final Class resultClass, final Body serializable, final IStatefulResponseHandler handler) - throws ClientException { + public Result send(final IHttpRequest request, final Class resultClass, final Body serializable, final IStatefulResponseHandler handler) throws ClientException { return sendRequestInternal(request, resultClass, serializable, null, handler); } /** * Sends the HTTP request * - * @param request the request description - * @param resultClass the class of the response from the service + * @param request the request description + * @param resultClass the class of the response from the service * @param serializable the object to send to the service in the body of the request - * @param progress the progress callback for the request - * @param the type of the response object - * @param the type of the object to send to the service in the body of the request + * @param progress the progress callback for the request + * @param the type of the response object + * @param the type of the object to send to the service in the body of the request * @return the result from the request * @throws ClientException an exception occurs if the request was unable to complete for any reason */ @@ -229,10 +265,8 @@ public class OnedriveHttpProvider implements IHttpProvider { } // Request level middleware options - RedirectOptions redirectOptions = new RedirectOptions(request.getMaxRedirects() > 0 ? request.getMaxRedirects() : this.connectionConfig.getMaxRedirects(), - request.getShouldRedirect() != null ? request.getShouldRedirect() : this.connectionConfig.getShouldRedirect()); - RetryOptions retryOptions = new RetryOptions(request.getShouldRetry() != null ? request.getShouldRetry() : this.connectionConfig.getShouldRetry(), - request.getMaxRetries() > 0 ? request.getMaxRetries() : this.connectionConfig.getMaxRetries(), request.getDelay() > 0 ? request.getDelay() : this.connectionConfig.getDelay()); + RedirectOptions redirectOptions = new RedirectOptions(request.getMaxRedirects() > 0 ? request.getMaxRedirects() : this.connectionConfig.getMaxRedirects(), request.getShouldRedirect() != null ? request.getShouldRedirect() : this.connectionConfig.getShouldRedirect()); + RetryOptions retryOptions = new RetryOptions(request.getShouldRetry() != null ? request.getShouldRetry() : this.connectionConfig.getShouldRetry(), request.getMaxRetries() > 0 ? request.getMaxRetries() : this.connectionConfig.getMaxRetries(), request.getDelay() > 0 ? request.getDelay() : this.connectionConfig.getDelay()); Request coreHttpRequest = convertIHttpRequestToOkHttpRequest(request); Request.Builder corehttpRequestBuilder = coreHttpRequest.newBuilder().tag(RedirectOptions.class, redirectOptions).tag(RetryOptions.class, retryOptions); @@ -331,20 +365,19 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Sends the HTTP request * - * @param request the request description - * @param resultClass the class of the response from the service - * @param serializable the object to send to the service in the body of the request - * @param progress the progress callback for the request - * @param handler the handler for stateful response - * @param the type of the response object - * @param the type of the object to send to the service in the body of the request + * @param request the request description + * @param resultClass the class of the response from the service + * @param serializable the object to send to the service in the body of the request + * @param progress the progress callback for the request + * @param handler the handler for stateful response + * @param the type of the response object + * @param the type of the object to send to the service in the body of the request * @param the response handler for stateful response * @return the result from the request * @throws ClientException an exception occurs if the request was unable to complete for any reason */ @SuppressWarnings("unchecked") - private Result sendRequestInternal(final IHttpRequest request, final Class resultClass, final Body serializable, final IProgressCallback progress, - final IStatefulResponseHandler handler) throws ClientException { + private Result sendRequestInternal(final IHttpRequest request, final Class resultClass, final Body serializable, final IProgressCallback progress, final IStatefulResponseHandler handler) throws ClientException { try { if (this.connectionConfig == null) { @@ -352,8 +385,7 @@ public class OnedriveHttpProvider implements IHttpProvider { } if (this.corehttpClient == null) { final ICoreAuthenticationProvider authProvider = request1 -> request1; - this.corehttpClient = HttpClients.createDefault(authProvider).newBuilder().connectTimeout(connectionConfig.getConnectTimeout(), TimeUnit.MILLISECONDS) - .readTimeout(connectionConfig.getReadTimeout(), TimeUnit.MILLISECONDS).followRedirects(false) // TODO https://github.com/microsoftgraph/msgraph-sdk-java/issues/516 + this.corehttpClient = HttpClients.createDefault(authProvider).newBuilder().connectTimeout(connectionConfig.getConnectTimeout(), TimeUnit.MILLISECONDS).readTimeout(connectionConfig.getReadTimeout(), TimeUnit.MILLISECONDS).followRedirects(false) // TODO https://github.com/microsoftgraph/msgraph-sdk-java/issues/516 .protocols(Collections.singletonList(Protocol.HTTP_1_1)) // https://stackoverflow.com/questions/62031298/sockettimeout-on-java-11-but-not-on-java-8 .build(); } @@ -399,8 +431,9 @@ public class OnedriveHttpProvider implements IHttpProvider { final Map headers = responseHeadersHelper.getResponseHeadersAsMapStringString(response); - if (response.body() == null || response.body().contentLength() == 0) + if (response.body() == null || response.body().contentLength() == 0) { return (Result) null; + } final String contentType = headers.get(Constants.CONTENT_TYPE_HEADER_NAME); if (contentType != null && resultClass != InputStream.class && contentType.contains(Constants.JSON_CONTENT_TYPE)) { @@ -416,13 +449,15 @@ public class OnedriveHttpProvider implements IHttpProvider { } finally { if (!isBinaryStreamInput) { try { - if (in != null) + if (in != null) { in.close(); + } } catch (IOException e) { logger.logError(e.getMessage(), e); } - if (response != null) + if (response != null) { response.close(); + } } } } catch (final GraphServiceException ex) { @@ -451,10 +486,10 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Handles the event of an error response * - * @param request the request that caused the failed response + * @param request the request that caused the failed response * @param serializable the body of the request - * @param connection the URL connection - * @param the type of the request body + * @param connection the URL connection + * @param the type of the request body * @throws IOException an exception occurs if there were any problems interacting with the connection object */ private void handleErrorResponse(final IHttpRequest request, final Body serializable, final Response response) throws IOException { @@ -474,10 +509,10 @@ public class OnedriveHttpProvider implements IHttpProvider { /** * Handles the cause where the response is a JSON object * - * @param in the input stream from the response + * @param in the input stream from the response * @param responseHeaders the response header - * @param clazz the class of the response object - * @param the type of the response object + * @param clazz the class of the response object + * @param the type of the response object * @return the JSON object */ private Result handleJsonResponse(final InputStream in, Map> responseHeaders, final Class clazz) { @@ -493,7 +528,7 @@ public class OnedriveHttpProvider implements IHttpProvider { * Handles the case where the response body is empty * * @param responseHeaders the response headers - * @param clazz the type of the response object + * @param clazz the type of the response object * @return the JSON object */ private Result handleEmptyResponse(Map> responseHeaders, final Class clazz) throws UnsupportedEncodingException { @@ -502,43 +537,6 @@ public class OnedriveHttpProvider implements IHttpProvider { return handleJsonResponse(in, responseHeaders, clazz); } - /** - * Reads in a stream and converts it into a string - * - * @param input the response body stream - * @return the string result - */ - public static String streamToString(final InputStream input) { - final String httpStreamEncoding = "UTF-8"; - final String endOfFile = "\\A"; - final Scanner scanner = new Scanner(input, httpStreamEncoding); - String scannerString = ""; - try { - scanner.useDelimiter(endOfFile); - scannerString = scanner.next(); - } finally { - scanner.close(); - } - return scannerString; - } - - /** - * Searches for the given header in a list of HeaderOptions - * - * @param headers the list of headers to search through - * @param header the header name to search for (case insensitive) - * @return true if the header has already been set - */ - @VisibleForTesting - static boolean hasHeader(List headers, String header) { - for (HeaderOption option : headers) { - if (option.getName().equalsIgnoreCase(header)) { - return true; - } - } - return false; - } - @VisibleForTesting public ILogger getLogger() { return logger; diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.java index 8173004e..c104da55 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/OnedriveImpl.java @@ -68,11 +68,10 @@ class OnedriveImpl { private static final long CHUNKED_UPLOAD_MAX_SIZE = 4L << 20; private static final int CHUNKED_UPLOAD_CHUNK_SIZE = 327680 * 32; private static final int CHUNKED_UPLOAD_MAX_ATTEMPTS = 5; - - private final OnedriveCloud cloud; - private final Context context; private static final String REPLACE_MODE = "replace"; private static final String NON_REPLACING_MODE = "rename"; + private final OnedriveCloud cloud; + private final Context context; private final OnedriveIdCache nodeInfoCache; private final OnedriveClientFactory clientFactory; private final SharedPreferencesHandler sharedPreferencesHandler; @@ -393,16 +392,16 @@ class OnedriveImpl { .buildRequest(); try (InputStream in = request.get(); // - TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { - @Override - public void bytesTransferred(long transferred) { - progressAware.onProgress( // - progress(DownloadState.download(file)) // - .between(0) // - .and(file.getSize().orElse(Long.MAX_VALUE)) // - .withValue(transferred)); - } - }) { + TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { + @Override + public void bytesTransferred(long transferred) { + progressAware.onProgress( // + progress(DownloadState.download(file)) // + .between(0) // + .and(file.getSize().orElse(Long.MAX_VALUE)) // + .withValue(transferred)); + } + }) { copyStreamToStream(in, out); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ClientException.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ClientException.java index ec4b8b67..4c3641cc 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ClientException.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ClientException.java @@ -15,7 +15,7 @@ public class ClientException extends com.microsoft.graph.core.ClientException { * Creates the client exception * * @param message the message to display - * @param ex the exception from + * @param ex the exception from */ public ClientException(final String message, final Throwable ex, Enum errorCode) { super(message, ex); diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ICallback.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ICallback.java index 1fe7783a..e02bada9 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ICallback.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/ICallback.java @@ -28,6 +28,7 @@ package org.cryptomator.data.cloud.onedrive.graph; * @param the result type of the successful action */ public interface ICallback { + /** * How successful results are handled * diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/IProgressCallback.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/IProgressCallback.java index 37d2a97d..98012d50 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/IProgressCallback.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/IProgressCallback.java @@ -33,7 +33,7 @@ public interface IProgressCallback extends com.microsoft.graph.concurren * How progress updates are handled for this callback * * @param current the current amount of progress - * @param max the max amount of progress + * @param max the max amount of progress */ void progress(final long current, final long max); } diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MSAAuthAndroidAdapter.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MSAAuthAndroidAdapter.java index a9b1a723..4fdb3224 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MSAAuthAndroidAdapter.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MSAAuthAndroidAdapter.java @@ -39,6 +39,18 @@ public abstract class MSAAuthAndroidAdapter implements IAuthenticationAdapter { * The live auth client. */ private final LiveAuthClient mLiveAuthClient; + private Context context; + + /** + * Create a new instance of the provider + * + * @param context the application context instance + * @param refreshToken + */ + protected MSAAuthAndroidAdapter(final Context context, String refreshToken) { + this.context = context; + mLiveAuthClient = new LiveAuthClient(context, getClientId(), Arrays.asList(getScopes()), MicrosoftOAuth2Endpoint.getInstance(), refreshToken); + } /** * The client id for this authenticator. @@ -56,19 +68,6 @@ public abstract class MSAAuthAndroidAdapter implements IAuthenticationAdapter { */ protected abstract String[] getScopes(); - private Context context; - - /** - * Create a new instance of the provider - * - * @param context the application context instance - * @param refreshToken - */ - protected MSAAuthAndroidAdapter(final Context context, String refreshToken) { - this.context = context; - mLiveAuthClient = new LiveAuthClient(context, getClientId(), Arrays.asList(getScopes()), MicrosoftOAuth2Endpoint.getInstance(), refreshToken); - } - @Override public void authenticateRequest(final IHttpRequest request) { Timber.tag("MSAAuthAndroidAdapter").d("Authenticating request, %s", request.getRequestUrl()); @@ -181,8 +180,9 @@ public abstract class MSAAuthAndroidAdapter implements IAuthenticationAdapter { } private String encrypt(String refreshToken) { - if (refreshToken == null) + if (refreshToken == null) { return null; + } return CredentialCryptor // .getInstance(context) // .encrypt(refreshToken); diff --git a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MicrosoftOAuth2Endpoint.java b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MicrosoftOAuth2Endpoint.java index 5adb24a9..5d964fdb 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MicrosoftOAuth2Endpoint.java +++ b/data/src/main/java/org/cryptomator/data/cloud/onedrive/graph/MicrosoftOAuth2Endpoint.java @@ -7,6 +7,7 @@ import com.microsoft.services.msa.OAuthConfig; import org.cryptomator.data.BuildConfig; class MicrosoftOAuth2Endpoint implements OAuthConfig { + /** * The current instance of this class */ diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavCloudContentRepository.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavCloudContentRepository.java index 7b68d330..43c645f2 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavCloudContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavCloudContentRepository.java @@ -41,9 +41,8 @@ import static org.cryptomator.util.ExceptionUtil.extract; @Singleton class WebDavCloudContentRepository extends InterceptingCloudContentRepository { - private final WebDavCloud cloud; - private static final CharSequence START_OF_CERTIFICATE = "-----BEGIN CERTIFICATE-----"; + private final WebDavCloud cloud; WebDavCloudContentRepository(WebDavCloud cloud, ConnectionHandlerHandlerImpl connectionHandlerHandler) { super(new Intercepted(cloud, connectionHandlerHandler)); diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavImpl.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavImpl.java index d1f1bbdf..4d4a3dcc 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavImpl.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/WebDavImpl.java @@ -174,6 +174,48 @@ class WebDavImpl { connectionHandler.checkAuthenticationAndServerCompatibility(url); } + public void read(final CloudFile file, OutputStream data, final ProgressAware progressAware) throws BackendException, IOException { + progressAware.onProgress(Progress.started(DownloadState.download(file))); + + try (InputStream in = connectionHandler.readFile(absoluteUriFrom(file.getPath())); // + TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { + @Override + public void bytesTransferred(long transferred) { + progressAware.onProgress( // + progress(DownloadState.download(file)) // + .between(0) // + .and(file.getSize().orElse(Long.MAX_VALUE)) // + .withValue(transferred)); + } + }) { + CopyStream.copyStreamToStream(in, out); + } + + progressAware.onProgress(Progress.completed(DownloadState.download(file))); + } + + public void delete(CloudNode node) throws BackendException { + connectionHandler.delete(absoluteUriFrom(node.getPath())); + } + + private String absoluteUriFrom(String path) { + path = removeLeadingSlash(path); + + return baseUrl.newBuilder() // + .addPathSegments(path) // + .build() // + .toString(); + } + + private String removeLeadingSlash(String path) { + return path.length() > 0 && path.charAt(0) == '/' ? path.substring(1) : path; + } + + public String currentAccount() throws BackendException { + checkAuthenticationAndServerCompatibility(cloud.url()); + return cloud.url(); + } + private static abstract class TransferredBytesAwareDataSource implements DataSource { private final DataSource data; @@ -209,46 +251,4 @@ class WebDavImpl { return delegate; } } - - public void read(final CloudFile file, OutputStream data, final ProgressAware progressAware) throws BackendException, IOException { - progressAware.onProgress(Progress.started(DownloadState.download(file))); - - try (InputStream in = connectionHandler.readFile(absoluteUriFrom(file.getPath())); // - TransferredBytesAwareOutputStream out = new TransferredBytesAwareOutputStream(data) { - @Override - public void bytesTransferred(long transferred) { - progressAware.onProgress( // - progress(DownloadState.download(file)) // - .between(0) // - .and(file.getSize().orElse(Long.MAX_VALUE)) // - .withValue(transferred)); - } - }) { - CopyStream.copyStreamToStream(in, out); - } - - progressAware.onProgress(Progress.completed(DownloadState.download(file))); - } - - public void delete(CloudNode node) throws BackendException { - connectionHandler.delete(absoluteUriFrom(node.getPath())); - } - - private String absoluteUriFrom(String path) { - path = removeLeadingSlash(path); - - return baseUrl.newBuilder() // - .addPathSegments(path) // - .build() // - .toString(); - } - - private String removeLeadingSlash(String path) { - return path.length() > 0 && path.charAt(0) == '/' ? path.substring(1) : path; - } - - public String currentAccount() throws BackendException { - checkAuthenticationAndServerCompatibility(cloud.url()); - return cloud.url(); - } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/ConnectionHandlerFactory.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/ConnectionHandlerFactory.java index 0c620b7a..a4ed60c2 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/ConnectionHandlerFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/ConnectionHandlerFactory.java @@ -9,6 +9,7 @@ import javax.inject.Singleton; @Singleton public class ConnectionHandlerFactory { + private final Context context; @Inject diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/DataSourceBasedRequestBody.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/DataSourceBasedRequestBody.java index bcf850f4..0b7040d9 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/DataSourceBasedRequestBody.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/DataSourceBasedRequestBody.java @@ -2,10 +2,10 @@ package org.cryptomator.data.cloud.webdav.network; import android.content.Context; -import java.io.IOException; - import org.cryptomator.domain.usecases.cloud.DataSource; +import java.io.IOException; + import okhttp3.MediaType; import okhttp3.RequestBody; import okio.BufferedSink; @@ -13,10 +13,6 @@ import okio.Okio; class DataSourceBasedRequestBody extends RequestBody { - public static RequestBody from(Context context, DataSource data) { - return new DataSourceBasedRequestBody(context, data); - } - private final Context context; private final DataSource data; @@ -25,6 +21,10 @@ class DataSourceBasedRequestBody extends RequestBody { this.data = data; } + public static RequestBody from(Context context, DataSource data) { + return new DataSourceBasedRequestBody(context, data); + } + @Override public long contentLength() { return data.size(context).get(); diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindEntryData.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindEntryData.java index 30858810..5c5335af 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindEntryData.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindEntryData.java @@ -12,6 +12,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; class PropfindEntryData { + private static final Pattern URI_PATTERN = Pattern.compile("^[a-z]+://[^/]+/(.*)$"); private String path; @@ -21,11 +22,6 @@ class PropfindEntryData { private Optional lastModified = Optional.empty(); private Optional size = Optional.empty(); - public void setPath(String pathOrUri) { - this.path = extractPath(pathOrUri); - this.pathSegments = path.split("/"); - } - private String extractPath(String pathOrUri) { Matcher matcher = URI_PATTERN.matcher(pathOrUri); if (matcher.matches()) { @@ -41,26 +37,31 @@ class PropfindEntryData { this.lastModified = lastModified; } - public void setSize(Optional size) { - this.size = size; - } - - public void setFile(boolean file) { - this.file = file; - } - public String getPath() { return path; } + public void setPath(String pathOrUri) { + this.path = extractPath(pathOrUri); + this.pathSegments = path.split("/"); + } + public Optional getSize() { return size; } + public void setSize(Optional size) { + this.size = size; + } + private boolean isFile() { return file; } + public void setFile(boolean file) { + this.file = file; + } + public WebDavNode toCloudNode(WebDavFolder parent) { if (isFile()) { return new WebDavFile(parent, getName(), size, lastModified); diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParser.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParser.java index 2c7f5b99..55d2de3f 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParser.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParser.java @@ -151,15 +151,15 @@ class PropfindResponseParser { int ident = 0; do { switch (xmlPullParser.next()) { - case XmlPullParser.TEXT: - result.append(xmlPullParser.getText()); - break; - case XmlPullParser.START_TAG: - ident++; - break; - case XmlPullParser.END_TAG: - ident--; - break; + case XmlPullParser.TEXT: + result.append(xmlPullParser.getText()); + break; + case XmlPullParser.START_TAG: + ident++; + break; + case XmlPullParser.END_TAG: + ident--; + break; } } while (!endOfDocument() && ident >= 0); return result.toString(); diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavClient.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavClient.java index 90c0d750..f913e13e 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavClient.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavClient.java @@ -1,14 +1,6 @@ package org.cryptomator.data.cloud.webdav.network; -import static java.util.Collections.sort; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; +import android.content.Context; import org.cryptomator.data.cloud.webdav.WebDavFolder; import org.cryptomator.data.cloud.webdav.WebDavNode; @@ -27,7 +19,13 @@ import org.cryptomator.domain.exception.UnauthorizedException; import org.cryptomator.domain.usecases.cloud.DataSource; import org.xmlpull.v1.XmlPullParserException; -import android.content.Context; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import okhttp3.MediaType; import okhttp3.Request; @@ -35,10 +33,13 @@ import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; +import static java.util.Collections.sort; + class WebDavClient { private final Context context; private final WebDavCompatibleHttpClient httpClient; + private final Comparator ASCENDING_BY_DEPTH = (o1, o2) -> o1.getDepth() - o2.getDepth(); WebDavClient(Context context, WebDavCompatibleHttpClient httpClient) { this.context = context; @@ -90,12 +91,12 @@ class WebDavClient { private void checkPropfindExecutionSucceeded(int responseCode) throws BackendException { switch (responseCode) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_NOT_FOUND: - throw new NotFoundException(); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_NOT_FOUND: + throw new NotFoundException(); } if (responseCode < 199 || responseCode > 300) { @@ -121,18 +122,18 @@ class WebDavClient { try (Response response = httpClient.execute(builder)) { if (!response.isSuccessful()) { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_NOT_FOUND: - throw new NotFoundException(); - case HttpURLConnection.HTTP_CONFLICT: - throw new ParentFolderDoesNotExistException(); - case HttpURLConnection.HTTP_PRECON_FAILED: - throw new CloudNodeAlreadyExistsException(to); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_NOT_FOUND: + throw new NotFoundException(); + case HttpURLConnection.HTTP_CONFLICT: + throw new ParentFolderDoesNotExistException(); + case HttpURLConnection.HTTP_PRECON_FAILED: + throw new CloudNodeAlreadyExistsException(to); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -156,16 +157,16 @@ class WebDavClient { return response.body().byteStream(); } else { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_NOT_FOUND: - throw new NotFoundException(); - case 416: // UNSATISFIABLE_RANGE - return new ByteArrayInputStream(new byte[0]); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_NOT_FOUND: + throw new NotFoundException(); + case 416: // UNSATISFIABLE_RANGE + return new ByteArrayInputStream(new byte[0]); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -185,17 +186,17 @@ class WebDavClient { try (Response response = httpClient.execute(builder)) { if (!response.isSuccessful()) { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_BAD_METHOD: - throw new TypeMismatchException(); - case HttpURLConnection.HTTP_CONFLICT: // fall through - case HttpURLConnection.HTTP_NOT_FOUND: // necessary due to a bug in Nextcloud, see https://github.com/nextcloud/server/issues/23519 - throw new ParentFolderDoesNotExistException(); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_BAD_METHOD: + throw new TypeMismatchException(); + case HttpURLConnection.HTTP_CONFLICT: // fall through + case HttpURLConnection.HTTP_NOT_FOUND: // necessary due to a bug in Nextcloud, see https://github.com/nextcloud/server/issues/23519 + throw new ParentFolderDoesNotExistException(); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -213,16 +214,16 @@ class WebDavClient { return folder; } else { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_BAD_METHOD: - throw new AlreadyExistException(); - case HttpURLConnection.HTTP_CONFLICT: - throw new ParentFolderDoesNotExistException(); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_BAD_METHOD: + throw new AlreadyExistException(); + case HttpURLConnection.HTTP_CONFLICT: + throw new ParentFolderDoesNotExistException(); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -238,14 +239,14 @@ class WebDavClient { try (Response response = httpClient.execute(builder)) { if (!response.isSuccessful()) { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - case HttpURLConnection.HTTP_NOT_FOUND: - throw new NotFoundException(String.format("Node %s doesn't exists", url)); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + case HttpURLConnection.HTTP_NOT_FOUND: + throw new NotFoundException(String.format("Node %s doesn't exists", url)); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -266,12 +267,12 @@ class WebDavClient { } } else { switch (response.code()) { - case HttpURLConnection.HTTP_UNAUTHORIZED: - throw new UnauthorizedException(); - case HttpURLConnection.HTTP_FORBIDDEN: - throw new ForbiddenException(); - default: - throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); + case HttpURLConnection.HTTP_UNAUTHORIZED: + throw new UnauthorizedException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new ForbiddenException(); + default: + throw new FatalBackendException("Response code isn't between 200 and 300: " + response.code()); } } } catch (IOException e) { @@ -302,8 +303,6 @@ class WebDavClient { return entryData.size() >= 1 ? entryData.get(0).toCloudNode(requestedFolder) : null; } - private final Comparator ASCENDING_BY_DEPTH = (o1, o2) -> o1.getDepth() - o2.getDepth(); - private enum PropfindDepth { ZERO("0"), // ONE("1"), // diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.java index 888cdd04..8ec386fb 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavCompatibleHttpClient.java @@ -1,24 +1,8 @@ package org.cryptomator.data.cloud.webdav.network; -import static com.google.common.net.HttpHeaders.CACHE_CONTROL; -import static org.cryptomator.data.util.NetworkTimeout.CONNECTION; -import static org.cryptomator.data.util.NetworkTimeout.READ; -import static org.cryptomator.data.util.NetworkTimeout.WRITE; -import static org.cryptomator.util.file.LruFileCacheUtil.Cache.WEBDAV; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.X509TrustManager; - -import org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor; -import org.cryptomator.domain.WebDavCloud; -import org.cryptomator.domain.exception.UnableToDecryptWebdavPasswordException; -import org.cryptomator.util.SharedPreferencesHandler; -import org.cryptomator.util.crypto.CredentialCryptor; -import org.cryptomator.util.file.LruFileCacheUtil; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import com.burgstaller.okhttp.AuthenticationCacheInterceptor; import com.burgstaller.okhttp.CachingAuthenticatorDecorator; @@ -28,9 +12,19 @@ import com.burgstaller.okhttp.digest.CachingAuthenticator; import com.burgstaller.okhttp.digest.Credentials; import com.burgstaller.okhttp.digest.DigestAuthenticator; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; +import org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor; +import org.cryptomator.domain.WebDavCloud; +import org.cryptomator.domain.exception.UnableToDecryptWebdavPasswordException; +import org.cryptomator.util.SharedPreferencesHandler; +import org.cryptomator.util.crypto.CredentialCryptor; +import org.cryptomator.util.file.LruFileCacheUtil; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.X509TrustManager; import okhttp3.Authenticator; import okhttp3.Cache; @@ -41,6 +35,12 @@ import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; +import static com.google.common.net.HttpHeaders.CACHE_CONTROL; +import static org.cryptomator.data.util.NetworkTimeout.CONNECTION; +import static org.cryptomator.data.util.NetworkTimeout.READ; +import static org.cryptomator.data.util.NetworkTimeout.WRITE; +import static org.cryptomator.util.file.LruFileCacheUtil.Cache.WEBDAV; + class WebDavCompatibleHttpClient { private final WebDavRedirectHandler webDavRedirectHandler; @@ -50,14 +50,6 @@ class WebDavCompatibleHttpClient { this.webDavRedirectHandler = new WebDavRedirectHandler(httpClientFor(cloud, context, sharedPreferencesHandler.useLruCache(), sharedPreferencesHandler.lruCacheSize())); } - Response execute(Request.Builder requestBuilder) throws IOException { - return execute(requestBuilder.build()); - } - - private Response execute(Request request) throws IOException { - return webDavRedirectHandler.executeFollowingRedirects(request); - } - private static OkHttpClient httpClientFor(WebDavCloud webDavCloud, Context context, boolean useLruCache, int lruCacheSize) { final Map authCache = new ConcurrentHashMap<>(); @@ -131,9 +123,9 @@ class WebDavCompatibleHttpClient { Authenticator result = new DispatchingAuthenticator // .Builder() // - .with("digest", digestAuthenticator) // - .with("basic", basicAuthenticator) // - .build(); + .with("digest", digestAuthenticator) // + .with("basic", basicAuthenticator) // + .build(); result = new CachingAuthenticatorDecorator(result, authCache); return result; @@ -162,4 +154,12 @@ class WebDavCompatibleHttpClient { NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } + + Response execute(Request.Builder requestBuilder) throws IOException { + return execute(requestBuilder.build()); + } + + private Response execute(Request request) throws IOException { + return webDavRedirectHandler.executeFollowingRedirects(request); + } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavRedirectHandler.java b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavRedirectHandler.java index 7c1219a7..2c895ff8 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavRedirectHandler.java +++ b/data/src/main/java/org/cryptomator/data/cloud/webdav/network/WebDavRedirectHandler.java @@ -36,15 +36,15 @@ class WebDavRedirectHandler { private Request redirectedRequestFor(Response response) { switch (response.code()) { - case 300: // fall through - case 301: // fall through - case 302: // fall through - case 303: // fall through - case 307: // fall through - case 308: - return createRedirectedRequest(response); - default: - return NO_REDIRECTED_REQUEST; + case 300: // fall through + case 301: // fall through + case 302: // fall through + case 303: // fall through + case 307: // fall through + case 308: + return createRedirectedRequest(response); + default: + return NO_REDIRECTED_REQUEST; } } diff --git a/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java b/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java index 60458e36..1b3725ee 100644 --- a/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java +++ b/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java @@ -31,6 +31,10 @@ class DatabaseUpgrades { upgrade3To4); } + private static Comparator reverseOrder() { + return (a, b) -> b.compareTo(a); + } + private Map> defineUpgrades(DatabaseUpgrade... upgrades) { Map> result = new HashMap<>(); for (DatabaseUpgrade upgrade : upgrades) { @@ -74,8 +78,4 @@ class DatabaseUpgrades { } return false; } - - private static Comparator reverseOrder() { - return (a, b) -> b.compareTo(a); - } } diff --git a/data/src/main/java/org/cryptomator/data/db/Sql.java b/data/src/main/java/org/cryptomator/data/db/Sql.java index 3125db5e..5f703a0a 100644 --- a/data/src/main/java/org/cryptomator/data/db/Sql.java +++ b/data/src/main/java/org/cryptomator/data/db/Sql.java @@ -76,6 +76,21 @@ class Sql { return (column, contentValues) -> contentValues.putNull(column); } + private static SQLiteDatabase unwrap(Database wrapped) { + return (SQLiteDatabase) wrapped.getRawDatabase(); + } + + public interface ValueHolder { + + void put(String column, ContentValues contentValues); + + } + + public interface Criterion { + + void appendTo(String column, StringBuilder whereClause, List whereArgs); + } + public static class SqlUpdateBuilder { private final String tableName; @@ -129,8 +144,8 @@ class Sql { public static class SqlUniqueIndexBuilder { private final String indexName; - private String table; private final StringBuilder columns = new StringBuilder(); + private String table; private SqlUniqueIndexBuilder(String indexName) { this.indexName = indexName; @@ -173,8 +188,8 @@ class Sql { public static class SqlAlterTableBuilder { private final String table; - private String newName; private final StringBuilder columns = new StringBuilder(); + private String newName; private SqlAlterTableBuilder(String table) { this.table = table; @@ -195,12 +210,10 @@ class Sql { private static final int NOT_FOUND = -1; private final String table; - private String[] columns; private final String[] selectedColumns; - - private String sourceTableName; - private final StringBuilder joinClauses = new StringBuilder(); + private String[] columns; + private String sourceTableName; private SqlInsertSelectBuilder(String table, String[] columns) { this.table = table; @@ -454,19 +467,4 @@ class Sql { } } - private static SQLiteDatabase unwrap(Database wrapped) { - return (SQLiteDatabase) wrapped.getRawDatabase(); - } - - public interface ValueHolder { - - void put(String column, ContentValues contentValues); - - } - - public interface Criterion { - - void appendTo(String column, StringBuilder whereClause, List whereArgs); - } - } diff --git a/data/src/main/java/org/cryptomator/data/db/Upgrade1To2.java b/data/src/main/java/org/cryptomator/data/db/Upgrade1To2.java index 0c62f2e4..61ae9979 100644 --- a/data/src/main/java/org/cryptomator/data/db/Upgrade1To2.java +++ b/data/src/main/java/org/cryptomator/data/db/Upgrade1To2.java @@ -1,12 +1,12 @@ package org.cryptomator.data.db; -import static org.cryptomator.data.db.Sql.createTable; -import static org.cryptomator.data.db.Sql.insertInto; +import org.greenrobot.greendao.database.Database; import javax.inject.Inject; import javax.inject.Singleton; -import org.greenrobot.greendao.database.Database; +import static org.cryptomator.data.db.Sql.createTable; +import static org.cryptomator.data.db.Sql.insertInto; @Singleton class Upgrade1To2 extends DatabaseUpgrade { diff --git a/data/src/main/java/org/cryptomator/data/db/entities/CloudEntity.java b/data/src/main/java/org/cryptomator/data/db/entities/CloudEntity.java index cbc9ab55..21551729 100644 --- a/data/src/main/java/org/cryptomator/data/db/entities/CloudEntity.java +++ b/data/src/main/java/org/cryptomator/data/db/entities/CloudEntity.java @@ -22,10 +22,28 @@ public class CloudEntity extends DatabaseEntity { private String webdavCertificate; + @Generated(hash = 2078985174) + public CloudEntity(Long id, @NotNull String type, String accessToken, String webdavUrl, String username, String webdavCertificate) { + this.id = id; + this.type = type; + this.accessToken = accessToken; + this.webdavUrl = webdavUrl; + this.username = username; + this.webdavCertificate = webdavCertificate; + } + + @Generated(hash = 1354152224) + public CloudEntity() { + } + public String getAccessToken() { return this.accessToken; } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + public String getType() { return this.type; } @@ -42,10 +60,6 @@ public class CloudEntity extends DatabaseEntity { this.id = id; } - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - public String getWebdavUrl() { return webdavUrl; } @@ -69,18 +83,4 @@ public class CloudEntity extends DatabaseEntity { public void setWebdavCertificate(String webdavCertificate) { this.webdavCertificate = webdavCertificate; } - - @Generated(hash = 2078985174) - public CloudEntity(Long id, @NotNull String type, String accessToken, String webdavUrl, String username, String webdavCertificate) { - this.id = id; - this.type = type; - this.accessToken = accessToken; - this.webdavUrl = webdavUrl; - this.username = username; - this.webdavCertificate = webdavCertificate; - } - - @Generated(hash = 1354152224) - public CloudEntity() { - } } diff --git a/data/src/main/java/org/cryptomator/data/db/entities/UpdateCheckEntity.java b/data/src/main/java/org/cryptomator/data/db/entities/UpdateCheckEntity.java index 911ec82e..10323409 100644 --- a/data/src/main/java/org/cryptomator/data/db/entities/UpdateCheckEntity.java +++ b/data/src/main/java/org/cryptomator/data/db/entities/UpdateCheckEntity.java @@ -38,6 +38,10 @@ public class UpdateCheckEntity extends DatabaseEntity { return id; } + public void setId(Long id) { + this.id = id; + } + public String getLicenseToken() { return this.licenseToken; } @@ -46,10 +50,6 @@ public class UpdateCheckEntity extends DatabaseEntity { this.licenseToken = licenseToken; } - public void setId(Long id) { - this.id = id; - } - public String getVersion() { return this.version; } diff --git a/data/src/main/java/org/cryptomator/data/db/entities/VaultEntity.java b/data/src/main/java/org/cryptomator/data/db/entities/VaultEntity.java index 9201131d..b8d683fc 100644 --- a/data/src/main/java/org/cryptomator/data/db/entities/VaultEntity.java +++ b/data/src/main/java/org/cryptomator/data/db/entities/VaultEntity.java @@ -29,6 +29,33 @@ public class VaultEntity extends DatabaseEntity { private String password; private Integer position; + /** + * Used for active entity operations. + */ + @Generated(hash = 941685503) + private transient VaultEntityDao myDao; + /** + * Used to resolve relations + */ + @Generated(hash = 2040040024) + private transient DaoSession daoSession; + @Generated(hash = 229273163) + private transient Long folderCloud__resolvedKey; + + @Generated(hash = 825602374) + public VaultEntity(Long id, Long folderCloudId, String folderPath, String folderName, @NotNull String cloudType, String password, Integer position) { + this.id = id; + this.folderCloudId = folderCloudId; + this.folderPath = folderPath; + this.folderName = folderName; + this.cloudType = cloudType; + this.password = password; + this.position = position; + } + + @Generated(hash = 691253864) + public VaultEntity() { + } /** * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}. @@ -66,17 +93,9 @@ public class VaultEntity extends DatabaseEntity { myDao.delete(this); } - /** called by internal mechanisms, do not call yourself. */ - @Generated(hash = 1482096330) - public void setFolderCloud(CloudEntity folderCloud) { - synchronized (this) { - this.folderCloud = folderCloud; - folderCloudId = folderCloud == null ? null : folderCloud.getId(); - folderCloud__resolvedKey = folderCloudId; - } - } - - /** To-one relationship, resolved on first access. */ + /** + * To-one relationship, resolved on first access. + */ @Generated(hash = 1508817413) public CloudEntity getFolderCloud() { Long __key = this.folderCloudId; @@ -95,16 +114,17 @@ public class VaultEntity extends DatabaseEntity { return folderCloud; } - /** Used for active entity operations. */ - @Generated(hash = 941685503) - private transient VaultEntityDao myDao; - - /** Used to resolve relations */ - @Generated(hash = 2040040024) - private transient DaoSession daoSession; - - @Generated(hash = 229273163) - private transient Long folderCloud__resolvedKey; + /** + * called by internal mechanisms, do not call yourself. + */ + @Generated(hash = 1482096330) + public void setFolderCloud(CloudEntity folderCloud) { + synchronized (this) { + this.folderCloud = folderCloud; + folderCloudId = folderCloud == null ? null : folderCloud.getId(); + folderCloud__resolvedKey = folderCloudId; + } + } public String getFolderPath() { return this.folderPath; @@ -169,20 +189,4 @@ public class VaultEntity extends DatabaseEntity { myDao = daoSession != null ? daoSession.getVaultEntityDao() : null; } - @Generated(hash = 825602374) - public VaultEntity(Long id, Long folderCloudId, String folderPath, String folderName, @NotNull String cloudType, String password, - Integer position) { - this.id = id; - this.folderCloudId = folderCloudId; - this.folderPath = folderPath; - this.folderName = folderName; - this.cloudType = cloudType; - this.password = password; - this.position = position; - } - - @Generated(hash = 691253864) - public VaultEntity() { - } - } diff --git a/data/src/main/java/org/cryptomator/data/db/mappers/CloudEntityMapper.java b/data/src/main/java/org/cryptomator/data/db/mappers/CloudEntityMapper.java index d0017352..39118d2b 100644 --- a/data/src/main/java/org/cryptomator/data/db/mappers/CloudEntityMapper.java +++ b/data/src/main/java/org/cryptomator/data/db/mappers/CloudEntityMapper.java @@ -29,38 +29,38 @@ public class CloudEntityMapper extends EntityMapper { public Cloud fromEntity(CloudEntity entity) { CloudType type = CloudType.valueOf(entity.getType()); switch (type) { - case DROPBOX: - return aDropboxCloud() // - .withId(entity.getId()) // - .withAccessToken(entity.getAccessToken()) // - .withUsername(entity.getUsername()) // - .build(); - case GOOGLE_DRIVE: - return aGoogleDriveCloud() // - .withId(entity.getId()) // - .withAccessToken(entity.getAccessToken()) // - .withUsername(entity.getUsername()) // - .build(); - case ONEDRIVE: - return aOnedriveCloud() // - .withId(entity.getId()) // - .withAccessToken(entity.getAccessToken()) // - .withUsername(entity.getUsername()) // - .build(); - case LOCAL: - return aLocalStorage() // - .withId(entity.getId()) // - .withRootUri(entity.getAccessToken()).build(); - case WEBDAV: - return aWebDavCloudCloud() // - .withId(entity.getId()) // - .withUrl(entity.getWebdavUrl()) // - .withUsername(entity.getUsername()) // - .withPassword(entity.getAccessToken()) // - .withCertificate(entity.getWebdavCertificate()) // - .build(); - default: - throw new IllegalStateException("Unhandled enum constant " + type); + case DROPBOX: + return aDropboxCloud() // + .withId(entity.getId()) // + .withAccessToken(entity.getAccessToken()) // + .withUsername(entity.getUsername()) // + .build(); + case GOOGLE_DRIVE: + return aGoogleDriveCloud() // + .withId(entity.getId()) // + .withAccessToken(entity.getAccessToken()) // + .withUsername(entity.getUsername()) // + .build(); + case ONEDRIVE: + return aOnedriveCloud() // + .withId(entity.getId()) // + .withAccessToken(entity.getAccessToken()) // + .withUsername(entity.getUsername()) // + .build(); + case LOCAL: + return aLocalStorage() // + .withId(entity.getId()) // + .withRootUri(entity.getAccessToken()).build(); + case WEBDAV: + return aWebDavCloudCloud() // + .withId(entity.getId()) // + .withUrl(entity.getWebdavUrl()) // + .withUsername(entity.getUsername()) // + .withPassword(entity.getAccessToken()) // + .withCertificate(entity.getWebdavCertificate()) // + .build(); + default: + throw new IllegalStateException("Unhandled enum constant " + type); } } @@ -70,29 +70,29 @@ public class CloudEntityMapper extends EntityMapper { result.setId(domainObject.id()); result.setType(domainObject.type().name()); switch (domainObject.type()) { - case DROPBOX: - result.setAccessToken(((DropboxCloud) domainObject).accessToken()); - result.setUsername(((DropboxCloud) domainObject).username()); - break; - case GOOGLE_DRIVE: - result.setAccessToken(((GoogleDriveCloud) domainObject).accessToken()); - result.setUsername(((GoogleDriveCloud) domainObject).username()); - break; - case ONEDRIVE: - result.setAccessToken(((OnedriveCloud) domainObject).accessToken()); - result.setUsername(((OnedriveCloud) domainObject).username()); - break; - case LOCAL: - result.setAccessToken(((LocalStorageCloud) domainObject).rootUri()); - break; - case WEBDAV: - result.setAccessToken(((WebDavCloud) domainObject).password()); - result.setWebdavUrl(((WebDavCloud) domainObject).url()); - result.setUsername(((WebDavCloud) domainObject).username()); - result.setWebdavCertificate(((WebDavCloud) domainObject).certificate()); - break; - default: - throw new IllegalStateException("Unhandled enum constant " + domainObject.type()); + case DROPBOX: + result.setAccessToken(((DropboxCloud) domainObject).accessToken()); + result.setUsername(((DropboxCloud) domainObject).username()); + break; + case GOOGLE_DRIVE: + result.setAccessToken(((GoogleDriveCloud) domainObject).accessToken()); + result.setUsername(((GoogleDriveCloud) domainObject).username()); + break; + case ONEDRIVE: + result.setAccessToken(((OnedriveCloud) domainObject).accessToken()); + result.setUsername(((OnedriveCloud) domainObject).username()); + break; + case LOCAL: + result.setAccessToken(((LocalStorageCloud) domainObject).rootUri()); + break; + case WEBDAV: + result.setAccessToken(((WebDavCloud) domainObject).password()); + result.setWebdavUrl(((WebDavCloud) domainObject).url()); + result.setUsername(((WebDavCloud) domainObject).username()); + result.setWebdavCertificate(((WebDavCloud) domainObject).certificate()); + break; + default: + throw new IllegalStateException("Unhandled enum constant " + domainObject.type()); } return result; } diff --git a/data/src/main/java/org/cryptomator/data/executor/JobExecutor.java b/data/src/main/java/org/cryptomator/data/executor/JobExecutor.java index 52b40690..608a8a9e 100644 --- a/data/src/main/java/org/cryptomator/data/executor/JobExecutor.java +++ b/data/src/main/java/org/cryptomator/data/executor/JobExecutor.java @@ -17,6 +17,7 @@ import javax.inject.Singleton; */ @Singleton public class JobExecutor implements ThreadExecutor { + private static final int INITIAL_POOL_SIZE = 3; private static final int MAX_POOL_SIZE = 5; @@ -44,6 +45,7 @@ public class JobExecutor implements ThreadExecutor { } private static class JobThreadFactory implements ThreadFactory { + private static final String THREAD_NAME = "android_"; private int counter = 0; diff --git a/data/src/main/java/org/cryptomator/data/repository/CloudContentRepositoryFactory.java b/data/src/main/java/org/cryptomator/data/repository/CloudContentRepositoryFactory.java index 6d6d2b7c..91d3a09a 100644 --- a/data/src/main/java/org/cryptomator/data/repository/CloudContentRepositoryFactory.java +++ b/data/src/main/java/org/cryptomator/data/repository/CloudContentRepositoryFactory.java @@ -11,12 +11,11 @@ public interface CloudContentRepositoryFactory { /** * Creates a new {@link CloudContentRepository}. - * + * * @param cloud the {@link Cloud} to access through the {@code CloudContentRepository} * @return the created {@code CloudContentRepository} - * * @throws NoAuthenticationProvidedException if the cloud has not been authenticated - * @throws AuthenticationException if an authentication error occurs while accessing the cloud + * @throws AuthenticationException if an authentication error occurs while accessing the cloud */ CloudContentRepository cloudContentRepositoryFor(Cloud cloud); diff --git a/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.java b/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.java index 0577c47e..8d679703 100644 --- a/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.java +++ b/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.java @@ -36,8 +36,7 @@ public class DispatchingCloudContentRepository implements CloudContentRepository private final CryptoCloudContentRepositoryFactory cryptoCloudContentRepositoryFactory; @Inject - public DispatchingCloudContentRepository(CloudContentRepositoryFactories cloudContentRepositoryFactories, NetworkConnectionCheck networkConnectionCheck, - CryptoCloudContentRepositoryFactory cryptoCloudContentRepositoryFactory) { + public DispatchingCloudContentRepository(CloudContentRepositoryFactories cloudContentRepositoryFactories, NetworkConnectionCheck networkConnectionCheck, CryptoCloudContentRepositoryFactory cryptoCloudContentRepositoryFactory) { this.cloudContentRepositoryFactories = cloudContentRepositoryFactories; this.networkConnectionCheck = networkConnectionCheck; this.cryptoCloudContentRepositoryFactory = cryptoCloudContentRepositoryFactory; diff --git a/data/src/main/java/org/cryptomator/data/repository/UpdateCheckRepositoryImpl.java b/data/src/main/java/org/cryptomator/data/repository/UpdateCheckRepositoryImpl.java index ebcecbc2..2c053cfb 100644 --- a/data/src/main/java/org/cryptomator/data/repository/UpdateCheckRepositoryImpl.java +++ b/data/src/main/java/org/cryptomator/data/repository/UpdateCheckRepositoryImpl.java @@ -2,6 +2,17 @@ package org.cryptomator.data.repository; import com.google.common.io.BaseEncoding; +import org.cryptomator.data.db.Database; +import org.cryptomator.data.db.entities.UpdateCheckEntity; +import org.cryptomator.data.util.UserAgentInterceptor; +import org.cryptomator.domain.exception.BackendException; +import org.cryptomator.domain.exception.FatalBackendException; +import org.cryptomator.domain.exception.update.GeneralUpdateErrorException; +import org.cryptomator.domain.exception.update.SSLHandshakePreAndroid5UpdateCheckException; +import org.cryptomator.domain.repository.UpdateCheckRepository; +import org.cryptomator.domain.usecases.UpdateCheck; +import org.cryptomator.util.Optional; + import java.io.File; import java.io.IOException; import java.security.Key; @@ -16,17 +27,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.net.ssl.SSLHandshakeException; -import org.cryptomator.data.db.Database; -import org.cryptomator.data.db.entities.UpdateCheckEntity; -import org.cryptomator.data.util.UserAgentInterceptor; -import org.cryptomator.domain.exception.BackendException; -import org.cryptomator.domain.exception.FatalBackendException; -import org.cryptomator.domain.exception.update.GeneralUpdateErrorException; -import org.cryptomator.domain.exception.update.SSLHandshakePreAndroid5UpdateCheckException; -import org.cryptomator.domain.repository.UpdateCheckRepository; -import org.cryptomator.domain.usecases.UpdateCheck; -import org.cryptomator.util.Optional; - import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import okhttp3.OkHttpClient; @@ -52,7 +52,7 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { private OkHttpClient httpClient() { return new OkHttpClient // .Builder().addInterceptor(new UserAgentInterceptor()) // - .build(); + .build(); } @Override @@ -100,7 +100,7 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { final Request request = new Request // .Builder() // - .url(entity.getUrlToApk()).build(); + .url(entity.getUrlToApk()).build(); final Response response = httpClient.newCall(request).execute(); @@ -120,8 +120,8 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { try { final Request request = new Request // .Builder() // - .url(HOSTNAME_LATEST_VERSION) // - .build(); + .url(HOSTNAME_LATEST_VERSION) // + .build(); return toLatestVersion(httpClient.newCall(request).execute()); } catch (SSLHandshakeException e) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { @@ -138,8 +138,8 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { try { final Request request = new Request // .Builder() // - .url(latestVersion.urlReleaseNote) // - .build(); + .url(latestVersion.urlReleaseNote) // + .build(); return toUpdateCheck(httpClient.newCall(request).execute(), latestVersion); } catch (IOException e) { throw new GeneralUpdateErrorException("Failed to update. General error occurred.", e); @@ -163,30 +163,21 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { } } - private class LatestVersion { + private ECPublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException { + final byte[] publicKey = BaseEncoding // + .base64() // + .decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELOYa5ax7QZvS92HJYCBPBiR2wWfX" + "P9/Oq/yl2J1yg0Vovetp8i1A3yCtoqdHVdVytM1wNV0JXgRbWuNTAr9nlQ=="); - private final String version; - private final String urlApk; - private final String urlReleaseNote; - - LatestVersion(String json) throws GeneralUpdateErrorException { - try { - Claims jws = Jwts // - .parserBuilder().setSigningKey(getPublicKey()) // - .build() // - .parseClaimsJws(json) // - .getBody(); - - version = jws.get("version", String.class); - urlApk = jws.get("url", String.class); - urlReleaseNote = jws.get("release_notes", String.class); - } catch (Exception e) { - throw new GeneralUpdateErrorException("Failed to parse latest version", e); - } + Key key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(publicKey)); + if (key instanceof ECPublicKey) { + return (ECPublicKey) key; + } else { + throw new FatalBackendException("Key not an EC public key."); } } private static class UpdateCheckImpl implements UpdateCheck { + private final String releaseNote; private final String version; private final String urlApk; @@ -227,16 +218,26 @@ public class UpdateCheckRepositoryImpl implements UpdateCheckRepository { } } - private ECPublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException { - final byte[] publicKey = BaseEncoding // - .base64() // - .decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELOYa5ax7QZvS92HJYCBPBiR2wWfX" + "P9/Oq/yl2J1yg0Vovetp8i1A3yCtoqdHVdVytM1wNV0JXgRbWuNTAr9nlQ=="); + private class LatestVersion { - Key key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(publicKey)); - if (key instanceof ECPublicKey) { - return (ECPublicKey) key; - } else { - throw new FatalBackendException("Key not an EC public key."); + private final String version; + private final String urlApk; + private final String urlReleaseNote; + + LatestVersion(String json) throws GeneralUpdateErrorException { + try { + Claims jws = Jwts // + .parserBuilder().setSigningKey(getPublicKey()) // + .build() // + .parseClaimsJws(json) // + .getBody(); + + version = jws.get("version", String.class); + urlApk = jws.get("url", String.class); + urlReleaseNote = jws.get("release_notes", String.class); + } catch (Exception e) { + throw new GeneralUpdateErrorException("Failed to parse latest version", e); + } } } } diff --git a/data/src/main/java/org/cryptomator/data/util/CopyStream.java b/data/src/main/java/org/cryptomator/data/util/CopyStream.java index 4e753757..b645d665 100644 --- a/data/src/main/java/org/cryptomator/data/util/CopyStream.java +++ b/data/src/main/java/org/cryptomator/data/util/CopyStream.java @@ -25,8 +25,9 @@ public class CopyStream { throw new FatalBackendException(ex); } - if (count == -1) + if (count == -1) { break; + } try { out.write(copyBuffer, 0, count); diff --git a/data/src/main/java/org/cryptomator/data/util/X509CertificateHelper.java b/data/src/main/java/org/cryptomator/data/util/X509CertificateHelper.java index 933936c1..d0293972 100644 --- a/data/src/main/java/org/cryptomator/data/util/X509CertificateHelper.java +++ b/data/src/main/java/org/cryptomator/data/util/X509CertificateHelper.java @@ -2,15 +2,15 @@ package org.cryptomator.data.util; import android.util.Base64; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils; + import java.io.ByteArrayInputStream; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.digest.DigestUtils; - public class X509CertificateHelper { private static final String CERT_BEGIN = "-----BEGIN CERTIFICATE-----\n"; diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/FixedGoogleAccountCredential.java b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/FixedGoogleAccountCredential.java index d0525a4e..b8a2b4e8 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/FixedGoogleAccountCredential.java +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/FixedGoogleAccountCredential.java @@ -32,16 +32,16 @@ class FixedGoogleAccountCredential extends GoogleAccountCredential { private String accountName; + private FixedGoogleAccountCredential(Context context, String scopesStr) { + super(context, scopesStr); + } + public static FixedGoogleAccountCredential usingOAuth2(Context context, Collection scopes) { Preconditions.checkArgument(scopes != null && scopes.iterator().hasNext()); String scopesStr = "oauth2:" + Joiner.on(' ').join(scopes); return new FixedGoogleAccountCredential(context, scopesStr); } - private FixedGoogleAccountCredential(Context context, String scopesStr) { - super(context, scopesStr); - } - @Override public void initialize(HttpRequest request) { FixedRequestHandler handler = new FixedRequestHandler(); @@ -81,7 +81,9 @@ class FixedGoogleAccountCredential extends GoogleAccountCredential { @Beta class FixedRequestHandler implements HttpExecuteInterceptor, HttpUnsuccessfulResponseHandler { - /** Whether we've received a 401 error code indicating the token is invalid. */ + /** + * Whether we've received a 401 error code indicating the token is invalid. + */ boolean received401; String token; diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.java b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.java index 13c64b0a..6dc79510 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.java +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveClientFactory.java @@ -30,14 +30,12 @@ class GoogleDriveClientFactory { } Drive getClient(String accountName) throws FatalBackendException { - if(sharedPreferencesHandler.debugMode()) { + if (sharedPreferencesHandler.debugMode()) { Logger.getLogger("com.google.api.client").setLevel(Level.CONFIG); Logger.getLogger("com.google.api.client").addHandler(new Handler() { @Override public void publish(LogRecord record) { - if(record.getMessage().startsWith("-------------- RESPONSE --------------") - || record.getMessage().startsWith("-------------- REQUEST --------------") - || record.getMessage().startsWith("{\n \"files\": [\n")) { + if (record.getMessage().startsWith("-------------- RESPONSE --------------") || record.getMessage().startsWith("-------------- REQUEST --------------") || record.getMessage().startsWith("{\n \"files\": [\n")) { Timber.tag("GoogleDriveClient").d(record.getMessage()); } } diff --git a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.java b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.java index 0bb53f0f..1eedb5ed 100644 --- a/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.java +++ b/data/src/notFoss/java/org/cryptomator/data/cloud/googledrive/GoogleDriveImpl.java @@ -1,17 +1,16 @@ package org.cryptomator.data.cloud.googledrive; -import static org.cryptomator.data.cloud.googledrive.GoogleDriveCloudNodeFactory.from; -import static org.cryptomator.data.cloud.googledrive.GoogleDriveCloudNodeFactory.isFolder; -import static org.cryptomator.domain.usecases.cloud.Progress.progress; -import static org.cryptomator.util.file.LruFileCacheUtil.retrieveFromLruCache; -import static org.cryptomator.util.file.LruFileCacheUtil.storeToLruCache; -import static org.cryptomator.util.file.LruFileCacheUtil.Cache.GOOGLE_DRIVE; +import android.content.Context; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import com.google.api.client.googleapis.json.GoogleJsonResponseException; +import com.google.api.client.http.HttpResponseException; +import com.google.api.services.drive.Drive; +import com.google.api.services.drive.model.About; +import com.google.api.services.drive.model.File; +import com.google.api.services.drive.model.FileList; +import com.google.api.services.drive.model.Revision; +import com.google.api.services.drive.model.RevisionList; +import com.tomclaw.cache.DiskLruCache; import org.cryptomator.data.util.TransferredBytesAwareOutputStream; import org.cryptomator.domain.CloudNode; @@ -29,20 +28,21 @@ import org.cryptomator.util.Optional; import org.cryptomator.util.SharedPreferencesHandler; import org.cryptomator.util.file.LruFileCacheUtil; -import com.google.api.client.googleapis.json.GoogleJsonResponseException; -import com.google.api.client.http.HttpResponseException; -import com.google.api.services.drive.Drive; -import com.google.api.services.drive.model.About; -import com.google.api.services.drive.model.File; -import com.google.api.services.drive.model.FileList; -import com.google.api.services.drive.model.Revision; -import com.google.api.services.drive.model.RevisionList; -import com.tomclaw.cache.DiskLruCache; - -import android.content.Context; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import timber.log.Timber; +import static org.cryptomator.data.cloud.googledrive.GoogleDriveCloudNodeFactory.from; +import static org.cryptomator.data.cloud.googledrive.GoogleDriveCloudNodeFactory.isFolder; +import static org.cryptomator.domain.usecases.cloud.Progress.progress; +import static org.cryptomator.util.file.LruFileCacheUtil.Cache.GOOGLE_DRIVE; +import static org.cryptomator.util.file.LruFileCacheUtil.retrieveFromLruCache; +import static org.cryptomator.util.file.LruFileCacheUtil.storeToLruCache; + class GoogleDriveImpl { private static final int STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416; @@ -284,8 +284,7 @@ class GoogleDriveImpl { .update( // file.getDriveId(), // metadata, // - in) - .setFields("id,modifiedTime,name,size") // + in).setFields("id,modifiedTime,name,size") // .setSupportsAllDrives(true) // .execute(); } diff --git a/data/src/test/java/org/cryptomator/data/ApplicationStub.java b/data/src/test/java/org/cryptomator/data/ApplicationStub.java index 079304c8..aba58b63 100755 --- a/data/src/test/java/org/cryptomator/data/ApplicationStub.java +++ b/data/src/test/java/org/cryptomator/data/ApplicationStub.java @@ -3,4 +3,5 @@ package org.cryptomator.data; import android.app.Application; public class ApplicationStub extends Application { + } diff --git a/data/src/test/java/org/cryptomator/data/cloud/CloudFileMatcher.java b/data/src/test/java/org/cryptomator/data/cloud/CloudFileMatcher.java index 7f60c447..0606331f 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/CloudFileMatcher.java +++ b/data/src/test/java/org/cryptomator/data/cloud/CloudFileMatcher.java @@ -24,6 +24,10 @@ public class CloudFileMatcher extends TypeSafeDiagnosingMatcher { Matchers.hasProperty("parent", is(file.getParent()))); } + public static CloudFileMatcher cloudFile(CloudFile file) { + return new CloudFileMatcher(file); + } + @Override public void describeTo(Description description) { delegate.describeTo(description); @@ -39,8 +43,4 @@ public class CloudFileMatcher extends TypeSafeDiagnosingMatcher { mismatchDescription.appendText("not ").appendDescriptionOf(delegate); return false; } - - public static CloudFileMatcher cloudFile(CloudFile file) { - return new CloudFileMatcher(file); - } } diff --git a/data/src/test/java/org/cryptomator/data/cloud/CloudFolderMatcher.java b/data/src/test/java/org/cryptomator/data/cloud/CloudFolderMatcher.java index 3db412b7..cfd30394 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/CloudFolderMatcher.java +++ b/data/src/test/java/org/cryptomator/data/cloud/CloudFolderMatcher.java @@ -22,6 +22,10 @@ public class CloudFolderMatcher extends TypeSafeDiagnosingMatcher { Matchers.hasProperty("parent", is(folder.getParent()))); } + public static CloudFolderMatcher cloudFolder(CloudFolder folder) { + return new CloudFolderMatcher(folder); + } + @Override public void describeTo(Description description) { delegate.describeTo(description); @@ -37,8 +41,4 @@ public class CloudFolderMatcher extends TypeSafeDiagnosingMatcher { mismatchDescription.appendText("not ").appendDescriptionOf(delegate); return false; } - - public static CloudFolderMatcher cloudFolder(CloudFolder folder) { - return new CloudFolderMatcher(folder); - } } diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7Test.java b/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7Test.java index 88407ec9..2a4e8c44 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7Test.java +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormat7Test.java @@ -446,8 +446,7 @@ public class CryptoImplVaultFormat7Test { TestFolder testFile15FolderRename = new TestFolder(aaFolder, shortenedFileNameRename, "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/" + shortenedFileNameRename); TestFile testFile15WhatTheHellCloudFileRename = new TestFile(aaFolder, shortenedFileNameRename, "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/" + shortenedFileNameRename, Optional.of(20l), Optional.empty()); - TestFile testFile15ContentFileRename = new TestFile(testFile15FolderRename, "contents.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/" + shortenedFileNameRename + "/contents.c9r", Optional.of(10l), - Optional.empty()); + TestFile testFile15ContentFileRename = new TestFile(testFile15FolderRename, "contents.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/" + shortenedFileNameRename + "/contents.c9r", Optional.of(10l), Optional.empty()); TestFile testFile15NameFileRename = new TestFile(testFile15FolderRename, "name.c9s", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/" + shortenedFileNameRename + "/name.c9s", Optional.of(511l), Optional.empty()); Mockito.when(fileNameCryptor.encryptFilename(BaseEncoding.base64Url(), file15Name + " (1)", dirIdRoot.getBytes())).thenReturn(file15Cipher + "(1)"); @@ -939,8 +938,7 @@ public class CryptoImplVaultFormat7Test { CryptoFolder cryptoFolder15 = new CryptoFolder(root, "Directory 15", "/Directory 15/", testDir15DirFile); - Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))) - .thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); + Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))).thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); Mockito.when(cloudContentRepository.folder(rootFolder, "d")).thenReturn(d); Mockito.when(cloudContentRepository.folder(d, "11")).thenReturn(bbLvl2Dir); Mockito.when(cloudContentRepository.folder(bbLvl2Dir, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")).thenReturn(bbFolder); @@ -980,8 +978,7 @@ public class CryptoImplVaultFormat7Test { Mockito.when(fileNameCryptor.encryptFilename(BaseEncoding.base64Url(), dir15Name, dirId1.getBytes())).thenReturn(dir15Cipher); - Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))) - .thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); + Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))).thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); Mockito.when(cloudContentRepository.folder(aaFolder, shortenedFileName)).thenReturn(testDir15); Mockito.when(cloudContentRepository.folder(rootFolder, "d")).thenReturn(d); Mockito.when(cloudContentRepository.folder(d, "11")).thenReturn(bbLvl2Dir); @@ -1033,8 +1030,7 @@ public class CryptoImplVaultFormat7Test { Mockito.when(fileNameCryptor.encryptFilename(BaseEncoding.base64Url(), dir15Name, dirId1.getBytes())).thenReturn(dir15Cipher); - Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))) - .thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); + Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))).thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); Mockito.when(cloudContentRepository.folder(aaFolder, shortenedFileName)).thenReturn(testDir15); Mockito.when(cloudContentRepository.folder(rootFolder, "d")).thenReturn(d); Mockito.when(cloudContentRepository.folder(d, "11")).thenReturn(bbLvl2Dir); diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormatPre7Test.java b/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormatPre7Test.java index 71466776..915a9a79 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormatPre7Test.java +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/CryptoImplVaultFormatPre7Test.java @@ -860,8 +860,7 @@ class CryptoImplVaultFormatPre7Test { Mockito.when(fileNameCryptor.encryptFilename(dir15Name, dirId1.getBytes())).thenReturn(dir15Cipher); - Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))) - .thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); + Mockito.when(cloudContentRepository.file(aaFolder, "dir15.c9r", Optional.ofNullable(null))).thenReturn(new TestFile(aaFolder, "dir15.c9r", "/d/00/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/dir15.c9r", Optional.empty(), Optional.empty())); Mockito.when(dirIdCache.put(Mockito.eq(cryptoFolder1), Mockito.any())).thenReturn(new DirIdCache.DirIdInfo(dirId1, bbFolder)); Mockito.when(dirIdCache.put(Mockito.eq(cryptoFolder15), Mockito.any())).thenReturn(new DirIdCache.DirIdInfo(dirId1, bbFolder)); diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/RootTestFolder.java b/data/src/test/java/org/cryptomator/data/cloud/crypto/RootTestFolder.java index e06dd943..f8564b7a 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/RootTestFolder.java +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/RootTestFolder.java @@ -15,12 +15,15 @@ class RootTestFolder extends TestFolder { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; - if (!super.equals(o)) + } + if (!super.equals(o)) { return false; + } RootTestFolder that = (RootTestFolder) o; diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFile.java b/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFile.java index 66cbeae9..17585c50 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFile.java +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFile.java @@ -55,21 +55,27 @@ class TestFile implements CloudFile { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } TestFile testFile = (TestFile) o; - if (!Objects.equals(parent, testFile.parent)) + if (!Objects.equals(parent, testFile.parent)) { return false; - if (!Objects.equals(name, testFile.name)) + } + if (!Objects.equals(name, testFile.name)) { return false; - if (!Objects.equals(path, testFile.path)) + } + if (!Objects.equals(path, testFile.path)) { return false; - if (!Objects.equals(size, testFile.size)) + } + if (!Objects.equals(size, testFile.size)) { return false; + } return Objects.equals(modified, testFile.modified); } diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFolder.java b/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFolder.java index f2b16bde..a8b2cfce 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFolder.java +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/TestFolder.java @@ -24,17 +24,21 @@ class TestFolder implements CloudFolder { @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } TestFolder that = (TestFolder) o; - if (!Objects.equals(parent, that.parent)) + if (!Objects.equals(parent, that.parent)) { return false; - if (!Objects.equals(name, that.name)) + } + if (!Objects.equals(name, that.name)) { return false; + } return Objects.equals(path, that.path); } diff --git a/data/src/test/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParserTest.java b/data/src/test/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParserTest.java index aff2053b..9a8fa2ac 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParserTest.java +++ b/data/src/test/java/org/cryptomator/data/cloud/webdav/network/PropfindResponseParserTest.java @@ -49,7 +49,7 @@ public class PropfindResponseParserTest { private static final String RESPONSE_ONE_FILE_NO_SERVER = "directory-one-file-no-server"; private static final String RESPONSE_ONE_FILE_AND_FOLDERS = "directory-and-file"; private static final String RESPONSE_MAL_FORMATTED_XMLPULLPARSER_EXCEPTION = "malformatted-response-xmlpullparser"; - + private final Comparator ASCENDING_BY_DEPTH = (o1, o2) -> o1.getDepth() - o2.getDepth(); private PropfindResponseParser inTest; @BeforeEach @@ -144,6 +144,4 @@ public class PropfindResponseParserTest { } return result; } - - private final Comparator ASCENDING_BY_DEPTH = (o1, o2) -> o1.getDepth() - o2.getDepth(); } diff --git a/domain/src/debug/java/org/cryptomator/domain/executor/BackgroundTasks.java b/domain/src/debug/java/org/cryptomator/domain/executor/BackgroundTasks.java index ca3889a1..84499e3e 100644 --- a/domain/src/debug/java/org/cryptomator/domain/executor/BackgroundTasks.java +++ b/domain/src/debug/java/org/cryptomator/domain/executor/BackgroundTasks.java @@ -14,35 +14,6 @@ public class BackgroundTasks { private static final ObjectCounts counts = new ObjectCounts(); - public static class Registration { - private final Class type; - private boolean unregistered = false; - - public Registration(Class type) { - this.type = type; - } - - public synchronized void unregister() { - if (unregistered) { - return; - } - - unregistered = true; - - lock.lock(); - - try { - int count = counts.removeAndGet(type); - Timber.tag("BackgroundTasks").d(caller("unregister", count, counts.count())); - if (count == 0) { - reachedZero.signalAll(); - } - } finally { - lock.unlock(); - } - } - } - public static void awaitCompleted() { lock.lock(); try { @@ -90,4 +61,34 @@ public class BackgroundTasks { .append(caller.getLineNumber()) // .toString(); } + + public static class Registration { + + private final Class type; + private boolean unregistered = false; + + public Registration(Class type) { + this.type = type; + } + + public synchronized void unregister() { + if (unregistered) { + return; + } + + unregistered = true; + + lock.lock(); + + try { + int count = counts.removeAndGet(type); + Timber.tag("BackgroundTasks").d(caller("unregister", count, counts.count())); + if (count == 0) { + reachedZero.signalAll(); + } + } finally { + lock.unlock(); + } + } + } } diff --git a/domain/src/main/java/org/cryptomator/domain/DropboxCloud.java b/domain/src/main/java/org/cryptomator/domain/DropboxCloud.java index c3184679..b8f4fc8a 100644 --- a/domain/src/main/java/org/cryptomator/domain/DropboxCloud.java +++ b/domain/src/main/java/org/cryptomator/domain/DropboxCloud.java @@ -14,6 +14,17 @@ public class DropboxCloud implements Cloud { this.username = builder.username; } + public static Builder aDropboxCloud() { + return new Builder(); + } + + public static Builder aCopyOf(DropboxCloud dropboxCloud) { + return new Builder() // + .withId(dropboxCloud.id()) // + .withAccessToken(dropboxCloud.accessToken()) // + .withUsername(dropboxCloud.username()); + } + @Override public Long id() { return id; @@ -52,23 +63,32 @@ public class DropboxCloud implements Cloud { return true; } - public static Builder aDropboxCloud() { - return new Builder(); - } - - public static Builder aCopyOf(DropboxCloud dropboxCloud) { - return new Builder() // - .withId(dropboxCloud.id()) // - .withAccessToken(dropboxCloud.accessToken()) // - .withUsername(dropboxCloud.username()); - } - @NotNull @Override public String toString() { return "DROPBOX"; } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((DropboxCloud) obj); + } + + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + + private boolean internalEquals(DropboxCloud obj) { + return id != null && id.equals(obj.id); + } + public static class Builder { private Long id; @@ -99,22 +119,4 @@ public class DropboxCloud implements Cloud { } - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((DropboxCloud) obj); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } - - private boolean internalEquals(DropboxCloud obj) { - return id != null && id.equals(obj.id); - } - } diff --git a/domain/src/main/java/org/cryptomator/domain/GoogleDriveCloud.java b/domain/src/main/java/org/cryptomator/domain/GoogleDriveCloud.java index 3e692137..e8b27ce9 100644 --- a/domain/src/main/java/org/cryptomator/domain/GoogleDriveCloud.java +++ b/domain/src/main/java/org/cryptomator/domain/GoogleDriveCloud.java @@ -14,6 +14,17 @@ public class GoogleDriveCloud implements Cloud { this.username = builder.username; } + public static Builder aGoogleDriveCloud() { + return new Builder(); + } + + public static Builder aCopyOf(GoogleDriveCloud googleDriveCloud) { + return new Builder() // + .withId(googleDriveCloud.id()) // + .withAccessToken(googleDriveCloud.accessToken()) // + .withUsername(googleDriveCloud.username()); + } + @Override public Long id() { return id; @@ -52,23 +63,32 @@ public class GoogleDriveCloud implements Cloud { return true; } - public static Builder aGoogleDriveCloud() { - return new Builder(); - } - - public static Builder aCopyOf(GoogleDriveCloud googleDriveCloud) { - return new Builder() // - .withId(googleDriveCloud.id()) // - .withAccessToken(googleDriveCloud.accessToken()) // - .withUsername(googleDriveCloud.username()); - } - @NotNull @Override public String toString() { return "GOOGLE_DRIVE"; } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((GoogleDriveCloud) obj); + } + + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + + private boolean internalEquals(GoogleDriveCloud obj) { + return id != null && id.equals(obj.id); + } + public static class Builder { private Long id; @@ -99,22 +119,4 @@ public class GoogleDriveCloud implements Cloud { } - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((GoogleDriveCloud) obj); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } - - private boolean internalEquals(GoogleDriveCloud obj) { - return id != null && id.equals(obj.id); - } - } diff --git a/domain/src/main/java/org/cryptomator/domain/LocalStorageCloud.java b/domain/src/main/java/org/cryptomator/domain/LocalStorageCloud.java index 689b5c36..ee895359 100644 --- a/domain/src/main/java/org/cryptomator/domain/LocalStorageCloud.java +++ b/domain/src/main/java/org/cryptomator/domain/LocalStorageCloud.java @@ -15,6 +15,15 @@ public class LocalStorageCloud implements Cloud { this.rootUri = builder.rootUri; } + public static Builder aLocalStorage() { + return new Builder(); + } + + public static Builder aCopyOf(LocalStorageCloud localStorageCloud) { + return new Builder() // + .withId(localStorageCloud.id()); + } + @Override public Long id() { return id; @@ -54,21 +63,32 @@ public class LocalStorageCloud implements Cloud { return false; } - public static Builder aLocalStorage() { - return new Builder(); - } - - public static Builder aCopyOf(LocalStorageCloud localStorageCloud) { - return new Builder() // - .withId(localStorageCloud.id()); - } - @NotNull @Override public String toString() { return "LOCAL"; } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((LocalStorageCloud) obj); + } + + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + + private boolean internalEquals(LocalStorageCloud obj) { + return id != null && id.equals(obj.id); + } + public static class Builder { private Long id; @@ -97,22 +117,4 @@ public class LocalStorageCloud implements Cloud { return "LOCAL"; } } - - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((LocalStorageCloud) obj); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } - - private boolean internalEquals(LocalStorageCloud obj) { - return id != null && id.equals(obj.id); - } } diff --git a/domain/src/main/java/org/cryptomator/domain/OnedriveCloud.java b/domain/src/main/java/org/cryptomator/domain/OnedriveCloud.java index a350a3e0..5b082012 100644 --- a/domain/src/main/java/org/cryptomator/domain/OnedriveCloud.java +++ b/domain/src/main/java/org/cryptomator/domain/OnedriveCloud.java @@ -14,6 +14,17 @@ public class OnedriveCloud implements Cloud { this.username = builder.username; } + public static Builder aOnedriveCloud() { + return new Builder(); + } + + public static Builder aCopyOf(OnedriveCloud oneDriveCloud) { + return new Builder() // + .withId(oneDriveCloud.id()) // + .withAccessToken(oneDriveCloud.accessToken()) // + .withUsername(oneDriveCloud.username()); + } + @Override public Long id() { return id; @@ -58,15 +69,24 @@ public class OnedriveCloud implements Cloud { return "ONEDRIVE"; } - public static Builder aOnedriveCloud() { - return new Builder(); + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((OnedriveCloud) obj); } - public static Builder aCopyOf(OnedriveCloud oneDriveCloud) { - return new Builder() // - .withId(oneDriveCloud.id()) // - .withAccessToken(oneDriveCloud.accessToken()) // - .withUsername(oneDriveCloud.username()); + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + + private boolean internalEquals(OnedriveCloud obj) { + return id != null && id.equals(obj.id); } public static class Builder { @@ -99,22 +119,4 @@ public class OnedriveCloud implements Cloud { } - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((OnedriveCloud) obj); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } - - private boolean internalEquals(OnedriveCloud obj) { - return id != null && id.equals(obj.id); - } - } diff --git a/domain/src/main/java/org/cryptomator/domain/Vault.java b/domain/src/main/java/org/cryptomator/domain/Vault.java index 7a1be5e2..4f70be7b 100644 --- a/domain/src/main/java/org/cryptomator/domain/Vault.java +++ b/domain/src/main/java/org/cryptomator/domain/Vault.java @@ -5,24 +5,6 @@ import java.io.Serializable; public class Vault implements Serializable { private static final Long NOT_SET = Long.MIN_VALUE; - - public static Builder aVault() { - return new Builder(); - } - - public static Builder aCopyOf(Vault vault) { - return new Builder() // - .withId(vault.getId()) // - .withCloud(vault.getCloud()) // - .withCloudType(vault.getCloudType()) // - .withName(vault.getName()) // - .withPath(vault.getPath()) // - .withUnlocked(vault.isUnlocked()) // - .withSavedPassword(vault.getPassword()) // - .withVersion(vault.getVersion()) // - .withPosition(vault.getPosition()); - } - private final Long id; private final String name; private final String path; @@ -45,6 +27,23 @@ public class Vault implements Serializable { this.position = builder.position; } + public static Builder aVault() { + return new Builder(); + } + + public static Builder aCopyOf(Vault vault) { + return new Builder() // + .withId(vault.getId()) // + .withCloud(vault.getCloud()) // + .withCloudType(vault.getCloudType()) // + .withName(vault.getName()) // + .withPath(vault.getPath()) // + .withUnlocked(vault.isUnlocked()) // + .withSavedPassword(vault.getPassword()) // + .withVersion(vault.getVersion()) // + .withPosition(vault.getPosition()); + } + public Long getId() { return id; } @@ -81,6 +80,26 @@ public class Vault implements Serializable { return position; } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((Vault) obj); + } + + private boolean internalEquals(Vault obj) { + return id != null && id.equals(obj.id); + } + + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + public static class Builder { private Long id = NOT_SET; @@ -190,22 +209,4 @@ public class Vault implements Serializable { } } } - - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((Vault) obj); - } - - private boolean internalEquals(Vault obj) { - return id != null && id.equals(obj.id); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } } diff --git a/domain/src/main/java/org/cryptomator/domain/WebDavCloud.java b/domain/src/main/java/org/cryptomator/domain/WebDavCloud.java index 6d9a1cea..2ffba185 100644 --- a/domain/src/main/java/org/cryptomator/domain/WebDavCloud.java +++ b/domain/src/main/java/org/cryptomator/domain/WebDavCloud.java @@ -18,6 +18,19 @@ public class WebDavCloud implements Cloud { this.certificate = builder.certificate; } + public static Builder aWebDavCloudCloud() { + return new Builder(); + } + + public static Builder aCopyOf(WebDavCloud webDavCloud) { + return new Builder() // + .withId(webDavCloud.id()) // + .withUrl(webDavCloud.url()) // + .withUsername(webDavCloud.username()) // + .withPassword(webDavCloud.password()) // + .withCertificate(webDavCloud.certificate()); + } + @Override public Long id() { return id; @@ -68,25 +81,32 @@ public class WebDavCloud implements Cloud { return true; } - public static Builder aWebDavCloudCloud() { - return new Builder(); - } - - public static Builder aCopyOf(WebDavCloud webDavCloud) { - return new Builder() // - .withId(webDavCloud.id()) // - .withUrl(webDavCloud.url()) // - .withUsername(webDavCloud.username()) // - .withPassword(webDavCloud.password()) // - .withCertificate(webDavCloud.certificate()); - } - @NotNull @Override public String toString() { return "WEBDAV"; } + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + if (obj == this) { + return true; + } + return internalEquals((WebDavCloud) obj); + } + + @Override + public int hashCode() { + return id == null ? 0 : id.hashCode(); + } + + private boolean internalEquals(WebDavCloud obj) { + return id != null && id.equals(obj.id); + } + public static class Builder { private Long id; @@ -129,22 +149,4 @@ public class WebDavCloud implements Cloud { } - @Override - public boolean equals(Object obj) { - if (obj == null || getClass() != obj.getClass()) - return false; - if (obj == this) - return true; - return internalEquals((WebDavCloud) obj); - } - - @Override - public int hashCode() { - return id == null ? 0 : id.hashCode(); - } - - private boolean internalEquals(WebDavCloud obj) { - return id != null && id.equals(obj.id); - } - } diff --git a/domain/src/main/java/org/cryptomator/domain/di/PerView.java b/domain/src/main/java/org/cryptomator/domain/di/PerView.java index 83f4f487..a69ea8f1 100755 --- a/domain/src/main/java/org/cryptomator/domain/di/PerView.java +++ b/domain/src/main/java/org/cryptomator/domain/di/PerView.java @@ -4,4 +4,5 @@ import javax.inject.Scope; @Scope public @interface PerView { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/AlreadyExistException.java b/domain/src/main/java/org/cryptomator/domain/exception/AlreadyExistException.java index fba7f2cd..04b12e91 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/AlreadyExistException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/AlreadyExistException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class AlreadyExistException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/ForbiddenException.java b/domain/src/main/java/org/cryptomator/domain/exception/ForbiddenException.java index 068a1a90..cc52ceb5 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/ForbiddenException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/ForbiddenException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class ForbiddenException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/NotImplementedException.java b/domain/src/main/java/org/cryptomator/domain/exception/NotImplementedException.java index 1495df35..e3b40b47 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/NotImplementedException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/NotImplementedException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class NotImplementedException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/ParentFolderDoesNotExistException.java b/domain/src/main/java/org/cryptomator/domain/exception/ParentFolderDoesNotExistException.java index ba130414..030600d4 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/ParentFolderDoesNotExistException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/ParentFolderDoesNotExistException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class ParentFolderDoesNotExistException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/ServerNotWebdavCompatibleException.java b/domain/src/main/java/org/cryptomator/domain/exception/ServerNotWebdavCompatibleException.java index 9fd652fd..60287ac6 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/ServerNotWebdavCompatibleException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/ServerNotWebdavCompatibleException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class ServerNotWebdavCompatibleException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/TypeMismatchException.java b/domain/src/main/java/org/cryptomator/domain/exception/TypeMismatchException.java index 79fd8de2..12ef5f62 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/TypeMismatchException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/TypeMismatchException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class TypeMismatchException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/UnauthorizedException.java b/domain/src/main/java/org/cryptomator/domain/exception/UnauthorizedException.java index 1d8b2bc8..eade2112 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/UnauthorizedException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/UnauthorizedException.java @@ -1,4 +1,5 @@ package org.cryptomator.domain.exception; public class UnauthorizedException extends BackendException { + } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavNotSupportedException.java b/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavNotSupportedException.java index dd9bb44c..2f27c334 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavNotSupportedException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavNotSupportedException.java @@ -3,6 +3,7 @@ package org.cryptomator.domain.exception.authentication; import org.cryptomator.domain.Cloud; public class WebDavNotSupportedException extends AuthenticationException { + public WebDavNotSupportedException(Cloud cloud) { super(cloud, "WebDav not supported by server"); } diff --git a/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavServerNotFoundException.java b/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavServerNotFoundException.java index 556660d5..4e7365d6 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavServerNotFoundException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/authentication/WebDavServerNotFoundException.java @@ -3,6 +3,7 @@ package org.cryptomator.domain.exception.authentication; import org.cryptomator.domain.Cloud; public class WebDavServerNotFoundException extends AuthenticationException { + public WebDavServerNotFoundException(Cloud cloud) { super(cloud); } diff --git a/domain/src/main/java/org/cryptomator/domain/executor/PostExecutionThread.java b/domain/src/main/java/org/cryptomator/domain/executor/PostExecutionThread.java index 19315a1d..25b96a83 100644 --- a/domain/src/main/java/org/cryptomator/domain/executor/PostExecutionThread.java +++ b/domain/src/main/java/org/cryptomator/domain/executor/PostExecutionThread.java @@ -6,7 +6,6 @@ import io.reactivex.Scheduler; * Thread abstraction created to change the execution context from any thread to any other thread. * Useful to encapsulate a UI Thread for example, since some job will be done in background, an * implementation of this interface will change context and update the UI. - * */ public interface PostExecutionThread { diff --git a/domain/src/main/java/org/cryptomator/domain/executor/ThreadExecutor.java b/domain/src/main/java/org/cryptomator/domain/executor/ThreadExecutor.java index de1806a6..1b03f869 100644 --- a/domain/src/main/java/org/cryptomator/domain/executor/ThreadExecutor.java +++ b/domain/src/main/java/org/cryptomator/domain/executor/ThreadExecutor.java @@ -5,7 +5,7 @@ import java.util.concurrent.Executor; /** * Executor implementation can be based on different frameworks or techniques of asynchronous * execution, but every implementation will execute a use case out of the UI thread. - * */ public interface ThreadExecutor extends Executor { + } diff --git a/domain/src/main/java/org/cryptomator/domain/repository/CloudContentRepository.java b/domain/src/main/java/org/cryptomator/domain/repository/CloudContentRepository.java index 7ed7d1f1..836f9c84 100644 --- a/domain/src/main/java/org/cryptomator/domain/repository/CloudContentRepository.java +++ b/domain/src/main/java/org/cryptomator/domain/repository/CloudContentRepository.java @@ -43,21 +43,18 @@ public interface CloudContentRepository getUpdateCheck(String version) throws BackendException; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/DoLicenseCheck.java b/domain/src/main/java/org/cryptomator/domain/usecases/DoLicenseCheck.java index fc0f6e7c..c2dcdc74 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/DoLicenseCheck.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/DoLicenseCheck.java @@ -1,11 +1,6 @@ package org.cryptomator.domain.usecases; -import java.security.Key; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.ECPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.X509EncodedKeySpec; +import com.google.common.io.BaseEncoding; import org.cryptomator.domain.exception.BackendException; import org.cryptomator.domain.exception.FatalBackendException; @@ -15,7 +10,12 @@ import org.cryptomator.domain.repository.UpdateCheckRepository; import org.cryptomator.generator.Parameter; import org.cryptomator.generator.UseCase; -import com.google.common.io.BaseEncoding; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.ECPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtException; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/DoUpdate.java b/domain/src/main/java/org/cryptomator/domain/usecases/DoUpdate.java index f8dfaff3..e9fb0004 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/DoUpdate.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/DoUpdate.java @@ -1,12 +1,12 @@ package org.cryptomator.domain.usecases; -import java.io.File; - import org.cryptomator.domain.exception.BackendException; import org.cryptomator.domain.repository.UpdateCheckRepository; import org.cryptomator.generator.Parameter; import org.cryptomator.generator.UseCase; +import java.io.File; + @UseCase public class DoUpdate { diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/NoOpResultHandler.java b/domain/src/main/java/org/cryptomator/domain/usecases/NoOpResultHandler.java index df4b408c..5abef9ab 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/NoOpResultHandler.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/NoOpResultHandler.java @@ -1,6 +1,7 @@ package org.cryptomator.domain.usecases; public abstract class NoOpResultHandler implements ResultHandler { + @Override public void onFinished() { // no-op diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/ProgressAwareResultHandler.java b/domain/src/main/java/org/cryptomator/domain/usecases/ProgressAwareResultHandler.java index 9a37a743..993654dd 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/ProgressAwareResultHandler.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/ProgressAwareResultHandler.java @@ -8,28 +8,6 @@ import org.cryptomator.domain.usecases.cloud.ProgressState; */ public abstract class ProgressAwareResultHandler implements ResultHandler, ProgressAware { - public static class NoOp extends ProgressAwareResultHandler { - @Override - public void onSuccess(T result) { - // no-op - } - - @Override - public void onError(Throwable e) { - // no-op - } - - @Override - public void onFinished() { - // no-op - } - - @Override - public void onProgress(Progress progress) { - // no-op - } - } - public static ProgressAwareResultHandler from(final ResultHandler resultHandler) { return new ProgressAwareResultHandler() { @Override @@ -78,4 +56,27 @@ public abstract class ProgressAwareResultHandler imp }; } + public static class NoOp extends ProgressAwareResultHandler { + + @Override + public void onSuccess(T result) { + // no-op + } + + @Override + public void onError(Throwable e) { + // no-op + } + + @Override + public void onFinished() { + // no-op + } + + @Override + public void onProgress(Progress progress) { + // no-op + } + } + } diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/ResultHandler.java b/domain/src/main/java/org/cryptomator/domain/usecases/ResultHandler.java index 5535c585..15ca5665 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/ResultHandler.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/ResultHandler.java @@ -2,21 +2,21 @@ package org.cryptomator.domain.usecases; /** * A handler for use case results. - * + * * @param The type of result this handler can handle. */ public interface ResultHandler { /** * Invoked after successful execution of a use case. - * + * * @param result the use case result */ void onSuccess(T result); /** * Invoked after failed execution of a use case. - * + * * @param e the error that occured */ void onError(Throwable e); diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/ResultWithProgress.java b/domain/src/main/java/org/cryptomator/domain/usecases/ResultWithProgress.java index eb18b4c3..c5465781 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/ResultWithProgress.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/ResultWithProgress.java @@ -5,6 +5,14 @@ import org.cryptomator.domain.usecases.cloud.ProgressState; public class ResultWithProgress { + private final Progress progress; + private final T value; + + private ResultWithProgress(T value, Progress progress) { + this.value = value; + this.progress = progress; + } + public static ResultWithProgress progress(Progress progress) { return new ResultWithProgress<>(null, progress); } @@ -17,14 +25,6 @@ public class ResultWithProgress { return new ResultWithProgress<>(null, Progress.started(state)); } - private final Progress progress; - private final T value; - - private ResultWithProgress(T value, Progress progress) { - this.value = value; - this.progress = progress; - } - public Progress progress() { return progress; } diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/ByteArrayDataSource.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/ByteArrayDataSource.java index 3f5c59d9..4cdb810c 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/ByteArrayDataSource.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/ByteArrayDataSource.java @@ -10,16 +10,16 @@ import java.io.InputStream; public class ByteArrayDataSource implements DataSource { - public static DataSource from(byte[] bytes) { - return new ByteArrayDataSource(bytes); - } - private final byte[] bytes; private ByteArrayDataSource(byte[] bytes) { this.bytes = bytes; } + public static DataSource from(byte[] bytes) { + return new ByteArrayDataSource(bytes); + } + @Override public Optional size(Context context) { long size = bytes.length; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareDataSource.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareDataSource.java index 91adf61f..3791e9d1 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareDataSource.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareDataSource.java @@ -10,10 +10,6 @@ import java.io.InputStream; public class CancelAwareDataSource implements DataSource { - public static CancelAwareDataSource wrap(DataSource delegate, Flag cancelled) { - return new CancelAwareDataSource(delegate, cancelled); - } - private final DataSource delegate; private final Flag cancelled; @@ -22,6 +18,10 @@ public class CancelAwareDataSource implements DataSource { this.cancelled = cancelled; } + public static CancelAwareDataSource wrap(DataSource delegate, Flag cancelled) { + return new CancelAwareDataSource(delegate, cancelled); + } + @Override public Optional size(Context context) { if (cancelled.get()) { diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareInputStream.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareInputStream.java index 416021e3..dfadcad5 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareInputStream.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/CancelAwareInputStream.java @@ -1,18 +1,14 @@ package org.cryptomator.domain.usecases.cloud; +import androidx.annotation.NonNull; + import org.cryptomator.domain.exception.CancellationException; import java.io.IOException; import java.io.InputStream; -import androidx.annotation.NonNull; - class CancelAwareInputStream extends InputStream { - public static CancelAwareInputStream wrap(InputStream delegate, Flag cancelled) { - return new CancelAwareInputStream(delegate, cancelled); - } - private final InputStream delegate; private final Flag cancelled; @@ -21,6 +17,10 @@ class CancelAwareInputStream extends InputStream { this.cancelled = cancelled; } + public static CancelAwareInputStream wrap(InputStream delegate, Flag cancelled) { + return new CancelAwareInputStream(delegate, cancelled); + } + @Override public int read() throws IOException { if (cancelled.get()) { diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/DownloadState.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/DownloadState.java index 4ffc1ed0..06c4da79 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/DownloadState.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/DownloadState.java @@ -7,6 +7,11 @@ public class DownloadState implements FileTransferState { private final CloudFile file; private final boolean download; + private DownloadState(CloudFile file, boolean download) { + this.download = download; + this.file = file; + } + public static DownloadState download(CloudFile file) { return new DownloadState(file, true); } @@ -15,11 +20,6 @@ public class DownloadState implements FileTransferState { return new DownloadState(file, false); } - private DownloadState(CloudFile file, boolean download) { - this.download = download; - this.file = file; - } - @Override public CloudFile file() { return file; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/FileBasedDataSource.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/FileBasedDataSource.java index bff61d92..fea189d5 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/FileBasedDataSource.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/FileBasedDataSource.java @@ -11,16 +11,16 @@ import java.io.InputStream; public class FileBasedDataSource implements DataSource { - public static FileBasedDataSource from(File file) { - return new FileBasedDataSource(file); - } - private final File file; private FileBasedDataSource(File file) { this.file = file; } + public static FileBasedDataSource from(File file) { + return new FileBasedDataSource(file); + } + @Override public Optional size(Context context) { return Optional.of(file.length()); diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/Progress.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/Progress.java index 86428d21..1ad32154 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/Progress.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/Progress.java @@ -20,6 +20,22 @@ public class Progress { this.value = min(MAX_VALUE, max(MIN_VALUE, value)); } + public static ProgressBuilder progress(T state) { + return new ProgressBuilder<>(state); + } + + public static Progress completed() { + return progress((T) null).between(0).and(1).thatIsCompleted(); + } + + public static Progress completed(T state) { + return progress(state).between(0).and(1).thatIsCompleted(); + } + + public static Progress started(T state) { + return progress(state).between(0).and(1).withValue(0); + } + public boolean stateOrCompletionChanged(Progress other) { return other == null || // other.state != state || // @@ -63,22 +79,6 @@ public class Progress { return sb.toString(); } - public static ProgressBuilder progress(T state) { - return new ProgressBuilder<>(state); - } - - public static Progress completed() { - return progress((T) null).between(0).and(1).thatIsCompleted(); - } - - public static Progress completed(T state) { - return progress(state).between(0).and(1).thatIsCompleted(); - } - - public static Progress started(T state) { - return progress(state).between(0).and(1).withValue(0); - } - public Progress withState(S state) { return new Progress<>(state, value, complete); } diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadFile.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadFile.java index 4b785256..ddf1bd67 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadFile.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadFile.java @@ -14,6 +14,17 @@ public class UploadFile { this.replacing = builder.replacing; } + public static Builder aCopyOf(UploadFile uploadFile) { + return new Builder() // + .withFileName(uploadFile.getFileName()) // + .withDataSource(uploadFile.getDataSource()) // + .thatIsReplacing(uploadFile.getReplacing()); + } + + public static Builder anUploadFile() { + return new Builder(); + } + public String getFileName() { return fileName; } @@ -26,17 +37,6 @@ public class UploadFile { return replacing; } - public static Builder aCopyOf(UploadFile uploadFile) { - return new Builder() // - .withFileName(uploadFile.getFileName()) // - .withDataSource(uploadFile.getDataSource()) // - .thatIsReplacing(uploadFile.getReplacing()); - } - - public static Builder anUploadFile() { - return new Builder(); - } - public static class Builder { private String fileName; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadState.java b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadState.java index c8c6948e..939eb400 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadState.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/cloud/UploadState.java @@ -7,6 +7,11 @@ public class UploadState implements FileTransferState { private final CloudFile file; private final boolean upload; + private UploadState(CloudFile file, boolean upload) { + this.upload = upload; + this.file = file; + } + public static UploadState upload(CloudFile file) { return new UploadState(file, true); } @@ -15,11 +20,6 @@ public class UploadState implements FileTransferState { return new UploadState(file, false); } - private UploadState(CloudFile file, boolean upload) { - this.upload = upload; - this.file = file; - } - @Override public CloudFile file() { return file; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateVault.java b/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateVault.java index 6df1bcde..f163819b 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateVault.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateVault.java @@ -21,8 +21,7 @@ class CreateVault { private final String vaultName; private final String password; - public CreateVault(CloudContentRepository cloudContentRepository, VaultRepository vaultRepository, CloudRepository cloudRepository, @Parameter CloudFolder folder, @Parameter String vaultName, - @Parameter String password) { + public CreateVault(CloudContentRepository cloudContentRepository, VaultRepository vaultRepository, CloudRepository cloudRepository, @Parameter CloudFolder folder, @Parameter String vaultName, @Parameter String password) { this.cloudContentRepository = cloudContentRepository; this.vaultRepository = vaultRepository; this.cloudRepository = cloudRepository; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/MoveVaultHelper.kt b/domain/src/main/java/org/cryptomator/domain/usecases/vault/MoveVaultHelper.kt index e42c5bbf..1495e19c 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/vault/MoveVaultHelper.kt +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/MoveVaultHelper.kt @@ -2,11 +2,13 @@ package org.cryptomator.domain.usecases.vault; import org.cryptomator.domain.Vault import org.cryptomator.domain.repository.VaultRepository -import java.util.* +import java.util.Collections +import java.util.Comparator class MoveVaultHelper { companion object { + fun updateVaultPosition(fromPosition: Int, toPosition: Int, vaultRepository: VaultRepository): List { val vaults = vaultRepository.vaults() @@ -24,14 +26,14 @@ class MoveVaultHelper { return reorderVaults(vaults) } - private fun reorderVaults(vaults: MutableList) : List { + private fun reorderVaults(vaults: MutableList): List { for (i in 0 until vaults.size) { vaults[i] = Vault.aCopyOf(vaults[i]).withPosition(i).build() } return vaults; } - fun reorderVaults(vaultRepository: VaultRepository) : List { + fun reorderVaults(vaultRepository: VaultRepository): List { val vaults = vaultRepository.vaults() vaults.sortWith(VaultComparator()) return reorderVaults(vaults) @@ -44,6 +46,7 @@ class MoveVaultHelper { } internal class VaultComparator : Comparator { + override fun compare(o1: Vault, o2: Vault): Int { return o1.position - o2.position } diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/RenameVault.java b/domain/src/main/java/org/cryptomator/domain/usecases/vault/RenameVault.java index 264586bb..82f4bffa 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/vault/RenameVault.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/RenameVault.java @@ -20,8 +20,8 @@ class RenameVault { private final CloudContentRepository cloudContentRepository; private final CloudRepository cloudRepository; private final VaultRepository vaultRepository; - private Vault vault; private final String newVaultName; + private Vault vault; public RenameVault(CloudContentRepository cloudContentRepository, CloudRepository cloudRepository, VaultRepository vaultRepository, @Parameter Vault vault, @Parameter String newVaultName) { this.cloudContentRepository = cloudContentRepository; diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/VaultOrUnlockToken.java b/domain/src/main/java/org/cryptomator/domain/usecases/vault/VaultOrUnlockToken.java index e2bbb055..1a8efb51 100644 --- a/domain/src/main/java/org/cryptomator/domain/usecases/vault/VaultOrUnlockToken.java +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/VaultOrUnlockToken.java @@ -7,14 +7,6 @@ import java.io.Serializable; public class VaultOrUnlockToken implements Serializable { - public static VaultOrUnlockToken from(Vault vault) { - return new VaultOrUnlockToken(vault, null); - } - - public static VaultOrUnlockToken from(UnlockToken unlockToken) { - return new VaultOrUnlockToken(null, unlockToken); - } - private final Vault vault; private final UnlockToken unlockToken; @@ -23,6 +15,14 @@ public class VaultOrUnlockToken implements Serializable { this.unlockToken = unlockToken; } + public static VaultOrUnlockToken from(Vault vault) { + return new VaultOrUnlockToken(vault, null); + } + + public static VaultOrUnlockToken from(UnlockToken unlockToken) { + return new VaultOrUnlockToken(null, unlockToken); + } + public Optional getVault() { return Optional.ofNullable(vault); } diff --git a/domain/src/release/java/org.cryptomator.domain.executor/BackgroundTasks.java b/domain/src/release/java/org.cryptomator.domain.executor/BackgroundTasks.java index 3c33204c..b002d0ff 100644 --- a/domain/src/release/java/org.cryptomator.domain.executor/BackgroundTasks.java +++ b/domain/src/release/java/org.cryptomator.domain.executor/BackgroundTasks.java @@ -2,14 +2,15 @@ package org.cryptomator.domain.executor; public class BackgroundTasks { - public static class Registration { - public void unregister() { - // empty in production code, only used in debug / test variant - } - } - public static Registration register(Class type) { // empty in production code, only used in debug / test variant return new Registration(); } + + public static class Registration { + + public void unregister() { + // empty in production code, only used in debug / test variant + } + } } diff --git a/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.java b/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.java index abf9f35a..bd488556 100644 --- a/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.java +++ b/domain/src/test/java/org/cryptomator/domain/usecases/cloud/DataSourceCapturingAnswer.java @@ -8,9 +8,9 @@ import java.io.InputStream; class DataSourceCapturingAnswer implements org.mockito.stubbing.Answer { - private ByteArrayOutputStream out; private final T result; private final int argIndex; + private ByteArrayOutputStream out; DataSourceCapturingAnswer(T result, int argIndex) { this.result = result; diff --git a/eclipse+formatter.xml b/eclipse+formatter.xml deleted file mode 100755 index a98d7ca1..00000000 --- a/eclipse+formatter.xml +++ /dev/null @@ -1,634 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/generator-api/src/main/java/org/cryptomator/generator/BottomSheet.java b/generator-api/src/main/java/org/cryptomator/generator/BottomSheet.java index f6298914..a6b4870b 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/BottomSheet.java +++ b/generator-api/src/main/java/org/cryptomator/generator/BottomSheet.java @@ -1,11 +1,11 @@ package org.cryptomator.generator; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + @Retention(RUNTIME) @Target(TYPE) public @interface BottomSheet { diff --git a/generator-api/src/main/java/org/cryptomator/generator/InjectIntent.java b/generator-api/src/main/java/org/cryptomator/generator/InjectIntent.java index d946fcb4..d6960836 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/InjectIntent.java +++ b/generator-api/src/main/java/org/cryptomator/generator/InjectIntent.java @@ -9,4 +9,5 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; @Retention(SOURCE) @Target(FIELD) public @interface InjectIntent { + } diff --git a/generator-api/src/main/java/org/cryptomator/generator/InstanceState.java b/generator-api/src/main/java/org/cryptomator/generator/InstanceState.java index c9e426dd..b3da9e87 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/InstanceState.java +++ b/generator-api/src/main/java/org/cryptomator/generator/InstanceState.java @@ -9,4 +9,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(FIELD) public @interface InstanceState { + } diff --git a/generator-api/src/main/java/org/cryptomator/generator/Optional.java b/generator-api/src/main/java/org/cryptomator/generator/Optional.java index 1ff9d196..2a215ae1 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/Optional.java +++ b/generator-api/src/main/java/org/cryptomator/generator/Optional.java @@ -10,4 +10,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.SOURCE) @Documented public @interface Optional { + } diff --git a/generator-api/src/main/java/org/cryptomator/generator/Parameter.java b/generator-api/src/main/java/org/cryptomator/generator/Parameter.java index b800f3e6..4f4c79e7 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/Parameter.java +++ b/generator-api/src/main/java/org/cryptomator/generator/Parameter.java @@ -9,4 +9,5 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; @Retention(SOURCE) @Target(PARAMETER) public @interface Parameter { + } diff --git a/generator-api/src/main/java/org/cryptomator/generator/UseCase.java b/generator-api/src/main/java/org/cryptomator/generator/UseCase.java index 10c0d0f4..976bf47a 100644 --- a/generator-api/src/main/java/org/cryptomator/generator/UseCase.java +++ b/generator-api/src/main/java/org/cryptomator/generator/UseCase.java @@ -9,4 +9,5 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; @Retention(SOURCE) @Target(TYPE) public @interface UseCase { + } diff --git a/generator/src/main/java/org/cryptomator/generator/model/ActivitiesModel.java b/generator/src/main/java/org/cryptomator/generator/model/ActivitiesModel.java index d594ac97..6b02eaf6 100644 --- a/generator/src/main/java/org/cryptomator/generator/model/ActivitiesModel.java +++ b/generator/src/main/java/org/cryptomator/generator/model/ActivitiesModel.java @@ -7,14 +7,14 @@ public class ActivitiesModel { private final Set activities; - public static ActivitiesModel.Builder builder() { - return new Builder(); - } - private ActivitiesModel(Set activities) { this.activities = activities; } + public static ActivitiesModel.Builder builder() { + return new Builder(); + } + public Set getActivities() { return activities; } diff --git a/generator/src/main/java/org/cryptomator/generator/model/ActivityModel.java b/generator/src/main/java/org/cryptomator/generator/model/ActivityModel.java index 4aac9b55..7f2f51c6 100644 --- a/generator/src/main/java/org/cryptomator/generator/model/ActivityModel.java +++ b/generator/src/main/java/org/cryptomator/generator/model/ActivityModel.java @@ -46,25 +46,6 @@ public class ActivityModel implements Comparable { } } - private Optional presenterIntentField(Optional presenterField, Optional intentField) { - if (!presenterField.isPresent() || !intentField.isPresent()) { - return Optional.empty(); - } - Type presenterType = presenterField.get().type(); - List intentFields = presenterType.fields().filter(field -> field.hasAnnotation(InjectIntent.class)).collect(toList()); - if (intentFields.size() > 1) { - throw new ProcessorException("Only one field annotated with InjectIntent is allowed per Presenter", presenterType.element()); - } else if (intentFields.isEmpty()) { - return java.util.Optional.empty(); - } else { - Field presenterIntentField = intentFields.get(0); - if (!presenterIntentField.type().qualifiedName().equals(intentField.get().type().qualifiedName())) { - throw new ProcessorException("Intent field in presenter must have the same declaringType as intent field in activity", presenterIntentField.element()); - } - return java.util.Optional.of(presenterIntentField); - } - } - private static Optional presenterField(Type type) { return type // .fields() // @@ -93,6 +74,25 @@ public class ActivityModel implements Comparable { return type.getQualifiedName().toString(); } + private Optional presenterIntentField(Optional presenterField, Optional intentField) { + if (!presenterField.isPresent() || !intentField.isPresent()) { + return Optional.empty(); + } + Type presenterType = presenterField.get().type(); + List intentFields = presenterType.fields().filter(field -> field.hasAnnotation(InjectIntent.class)).collect(toList()); + if (intentFields.size() > 1) { + throw new ProcessorException("Only one field annotated with InjectIntent is allowed per Presenter", presenterType.element()); + } else if (intentFields.isEmpty()) { + return java.util.Optional.empty(); + } else { + Field presenterIntentField = intentFields.get(0); + if (!presenterIntentField.type().qualifiedName().equals(intentField.get().type().qualifiedName())) { + throw new ProcessorException("Intent field in presenter must have the same declaringType as intent field in activity", presenterIntentField.element()); + } + return java.util.Optional.of(presenterIntentField); + } + } + public String getPresenterFieldName() { return presenterFieldName; } diff --git a/generator/src/main/java/org/cryptomator/generator/model/FragmentsModel.java b/generator/src/main/java/org/cryptomator/generator/model/FragmentsModel.java index b4864115..f63f9749 100644 --- a/generator/src/main/java/org/cryptomator/generator/model/FragmentsModel.java +++ b/generator/src/main/java/org/cryptomator/generator/model/FragmentsModel.java @@ -7,14 +7,14 @@ public class FragmentsModel { private final Set fragments; - public static FragmentsModel.Builder builder() { - return new Builder(); - } - private FragmentsModel(Set fragments) { this.fragments = fragments; } + public static FragmentsModel.Builder builder() { + return new Builder(); + } + public Set getFragments() { return fragments; } diff --git a/generator/src/main/java/org/cryptomator/generator/model/IntentsModel.java b/generator/src/main/java/org/cryptomator/generator/model/IntentsModel.java index af384366..ae3fe753 100644 --- a/generator/src/main/java/org/cryptomator/generator/model/IntentsModel.java +++ b/generator/src/main/java/org/cryptomator/generator/model/IntentsModel.java @@ -8,15 +8,15 @@ public class IntentsModel { private final Set builders; private final Set readers; - public static IntentsModel.Builder builder() { - return new Builder(); - } - private IntentsModel(Set builders, Set readers) { this.builders = builders; this.readers = readers; } + public static IntentsModel.Builder builder() { + return new Builder(); + } + public Set getBuilders() { return builders; } diff --git a/generator/src/main/java/org/cryptomator/generator/utils/Method.java b/generator/src/main/java/org/cryptomator/generator/utils/Method.java index 82eb56db..fb44762c 100644 --- a/generator/src/main/java/org/cryptomator/generator/utils/Method.java +++ b/generator/src/main/java/org/cryptomator/generator/utils/Method.java @@ -22,14 +22,6 @@ public class Method implements Comparable { this.delegate = executableElement; } - public Element element() { - return delegate; - } - - public String name() { - return delegate.getSimpleName().toString(); - } - public static boolean isRegularMethod(ExecutableElement executableElement) { String name = executableElement.getSimpleName().toString(); return !"".equals(name) && !name.startsWith("<"); @@ -40,6 +32,14 @@ public class Method implements Comparable { return name.equals(""); } + public Element element() { + return delegate; + } + + public String name() { + return delegate.getSimpleName().toString(); + } + public boolean isStatic() { return delegate.getModifiers().contains(Modifier.STATIC); } diff --git a/generator/src/main/java/org/cryptomator/generator/utils/Type.java b/generator/src/main/java/org/cryptomator/generator/utils/Type.java index 884b1a9f..196731d4 100644 --- a/generator/src/main/java/org/cryptomator/generator/utils/Type.java +++ b/generator/src/main/java/org/cryptomator/generator/utils/Type.java @@ -20,10 +20,6 @@ public class Type implements Comparable { private final Optional element; private final Utils utils; - public Utils getUtils() { - return utils; - } - public Type(Utils utils, TypeMirror mirror) { if (utils == null) { throw new IllegalArgumentException("utils must not be null"); @@ -52,6 +48,10 @@ public class Type implements Comparable { this.element = Optional.of(element); } + public Utils getUtils() { + return utils; + } + public TypeElement element() { return element.get(); } @@ -92,8 +92,7 @@ public class Type implements Comparable { .sorted((e1, e2) -> e1.getSimpleName().toString().compareTo(e2.getSimpleName().toString())) // .map(ExecutableElement.class::cast) // .filter(Method::isConstructor) // - .map(executableElement -> new Method(utils, executableElement))) - .orElse(Stream.empty()); // + .map(executableElement -> new Method(utils, executableElement))).orElse(Stream.empty()); // } public Stream methods() { @@ -103,8 +102,7 @@ public class Type implements Comparable { .sorted((e1, e2) -> e1.getSimpleName().toString().compareTo(e2.getSimpleName().toString())) // .map(ExecutableElement.class::cast) // .filter(Method::isRegularMethod) // - .map(executableElement -> new Method(utils, executableElement))) - .orElse(Stream.empty()); + .map(executableElement -> new Method(utils, executableElement))).orElse(Stream.empty()); } public Stream fields() { @@ -120,10 +118,12 @@ public class Type implements Comparable { @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((Type) obj); } diff --git a/intellij+formatter.xml b/intellij+formatter.xml deleted file mode 100644 index 06b20272..00000000 --- a/intellij+formatter.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java index 6a20f8fb..c87faf61 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java @@ -55,15 +55,20 @@ public class CloudContentRepositoryBlackboxTest { private static Cloud cloud; private static TestCloud inTestCloud; private static boolean setupCloudCompleted = false; - + @Rule + public final ActivityTestRule activityTestRule = new ActivityTestRule<>(SplashActivity.class); + @Rule + public ExpectedException thrown = ExpectedException.none(); private CloudContentRepository inTest; private CloudFolder root; - @Rule - public final ActivityTestRule activityTestRule = new ActivityTestRule<>(SplashActivity.class); + public CloudContentRepositoryBlackboxTest(TestCloud testCloud) { + if (inTestCloud != null && inTestCloud != testCloud) { + setupCloudCompleted = false; + } - @Rule - public ExpectedException thrown = ExpectedException.none(); + inTestCloud = testCloud; + } @Parameterized.Parameters(name = "{0}") public static TestCloud[] data() { @@ -77,21 +82,13 @@ public class CloudContentRepositoryBlackboxTest { new CryptoTestCloud()}; } - public CloudContentRepositoryBlackboxTest(TestCloud testCloud) { - if (inTestCloud != null && inTestCloud != testCloud) { - setupCloudCompleted = false; - } - - inTestCloud = testCloud; - } - @Before public void setup() throws BackendException { ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule // .getActivity() // .getApplication()) // - .getComponent(); + .getComponent(); if (!setupCloudCompleted) { if (inTestCloud instanceof CryptoTestCloud) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java index 79dce26a..686fb187 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java @@ -35,6 +35,25 @@ class CloudNodeMatchers { return new FileMatcher(); } + public static Matcher folder(final String name) { + return (Matcher) new TypeSafeDiagnosingMatcher() { + @Override + protected boolean matchesSafely(CloudFolder file, org.hamcrest.Description description) { + if (name.equals(file.getName())) { + return true; + } else { + description.appendText("folder with name '").appendText(file.getName()).appendText("'"); + return false; + } + } + + @Override + public void describeTo(org.hamcrest.Description description) { + description.appendText("folder with name '").appendText(name).appendText("'"); + } + }; + } + public static class FileMatcher extends TypeSafeDiagnosingMatcher { private String nameToCheck; @@ -104,23 +123,4 @@ class CloudNodeMatchers { return modified.isPresent() && !modified.get().before(min) && !modified.get().after(max); } } - - public static Matcher folder(final String name) { - return (Matcher) new TypeSafeDiagnosingMatcher() { - @Override - protected boolean matchesSafely(CloudFolder file, org.hamcrest.Description description) { - if (name.equals(file.getName())) { - return true; - } else { - description.appendText("folder with name '").appendText(file.getName()).appendText("'"); - return false; - } - } - - @Override - public void describeTo(org.hamcrest.Description description) { - description.appendText("folder with name '").appendText(name).appendText("'"); - } - }; - } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java index 2062adc3..663e5bb7 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java @@ -8,6 +8,7 @@ import org.cryptomator.presentation.di.component.ApplicationComponent; import org.cryptomator.util.crypto.CredentialCryptor; public class DropboxTestCloud extends TestCloud { + private final Context context; public DropboxTestCloud(Context context) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java index 974e52cf..1aaa37b6 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java @@ -25,6 +25,7 @@ import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.chec import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.openCloudServices; public class GoogledriveTestCloud extends TestCloud { + @Override public Cloud getInstance(ApplicationComponent appComponent) { login(); @@ -67,9 +68,9 @@ public class GoogledriveTestCloud extends TestCloud { try { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(GOOGLE_DRIVE, R.id.tv_cloud_name)) // - .check(matches(withText(InstrumentationRegistry // - .getTargetContext() // - .getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " Google Drive"))); + .check(matches(withText(InstrumentationRegistry // + .getTargetContext() // + .getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " Google Drive"))); } catch (AssertionFailedError e) { return false; } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java index 348c2ca1..8e7ae7b4 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java @@ -21,6 +21,7 @@ import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.open import static org.cryptomator.presentation.ui.activity.LoginLocalClouds.chooseFolder; public class LocalStorageTestCloud extends TestCloud { + @Override public Cloud getInstance(ApplicationComponent appComponent) { login(); diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java index 22e10bd5..4d57b3a3 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java @@ -7,6 +7,7 @@ import org.cryptomator.presentation.di.component.ApplicationComponent; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; public class LocalTestCloud extends TestCloud { + @Override public Cloud getInstance(ApplicationComponent appComponent) { getInstrumentation() // diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java index fe5edd14..bf80def9 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java @@ -8,6 +8,7 @@ import org.cryptomator.domain.OnedriveCloud; import org.cryptomator.presentation.di.component.ApplicationComponent; public class OnedriveTestCloud extends TestCloud { + private final Context context; public OnedriveTestCloud(Context context) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java index ac90ac71..76f6fc55 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java @@ -4,5 +4,6 @@ import org.cryptomator.domain.Cloud; import org.cryptomator.presentation.di.component.ApplicationComponent; public abstract class TestCloud { + public abstract Cloud getInstance(ApplicationComponent appComponent); } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/WebdavTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/WebdavTestCloud.java index 0345acdd..6abb564e 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/WebdavTestCloud.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/WebdavTestCloud.java @@ -8,6 +8,7 @@ import org.cryptomator.presentation.di.component.ApplicationComponent; import org.cryptomator.util.crypto.CredentialCryptor; public class WebdavTestCloud extends TestCloud { + private final Context context; public WebdavTestCloud(Context context) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java index ec493e14..a9369781 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java @@ -3,16 +3,17 @@ package org.cryptomator.presentation.ui; import android.content.res.Resources; import android.view.View; +import androidx.recyclerview.widget.RecyclerView; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import androidx.recyclerview.widget.RecyclerView; - /** * Created by dannyroa on 5/10/15. */ public class RecyclerViewMatcher { + private final int recyclerViewId; public RecyclerViewMatcher(int recyclerViewId) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java index a65823f6..964e60c7 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java @@ -1,5 +1,11 @@ package org.cryptomator.presentation.ui; +import androidx.test.espresso.ViewInteraction; +import androidx.test.rule.ActivityTestRule; +import androidx.test.uiautomator.UiDevice; +import androidx.test.uiautomator.UiObjectNotFoundException; +import androidx.test.uiautomator.UiSelector; + import org.cryptomator.domain.Cloud; import org.cryptomator.domain.CloudFolder; import org.cryptomator.domain.CloudNode; @@ -12,12 +18,6 @@ import org.hamcrest.Matchers; import java.util.List; -import androidx.test.espresso.ViewInteraction; -import androidx.test.rule.ActivityTestRule; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; - import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; import static androidx.test.espresso.action.ViewActions.click; @@ -36,6 +36,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.core.Is.is; public class TestUtil { + public static final int DROPBOX = 0; public static final int GOOGLE_DRIVE = 1; public static final int ONEDRIVE = 2; @@ -94,7 +95,7 @@ public class TestUtil { onView(allOf( // withId(R.id.title), // withText(R.string.snack_bar_action_title_settings))) // - .perform(click()); + .perform(click()); awaitCompleted(); diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/BasicNodeOperationsUtil.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/BasicNodeOperationsUtil.java index 4bd00dd5..d4a8f792 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/BasicNodeOperationsUtil.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/BasicNodeOperationsUtil.java @@ -24,7 +24,7 @@ public class BasicNodeOperationsUtil { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(nodePosition, R.id.settings)) // - .perform(click()); + .perform(click()); awaitCompleted(); } @@ -39,7 +39,7 @@ public class BasicNodeOperationsUtil { onView(allOf( // withId(R.id.tv_empty_folder_hint), // withText(R.string.screen_file_browser_msg_empty_folder))) // - .check(matches(withText(R.string.screen_file_browser_msg_empty_folder))); + .check(matches(withText(R.string.screen_file_browser_msg_empty_folder))); } static void checkFileOrFolderAlreadyExistsErrorMessage(String nodeName) { diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/CloudsOperationsTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/CloudsOperationsTest.java index 8d3deb43..dc0ad8d5 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/CloudsOperationsTest.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/CloudsOperationsTest.java @@ -45,11 +45,50 @@ import static org.hamcrest.core.AllOf.allOf; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class CloudsOperationsTest { + private final UiDevice device = UiDevice.getInstance(getInstrumentation()); @Rule public ActivityTestRule activityTestRule // = new ActivityTestRule<>(SplashActivity.class); - private final UiDevice device = UiDevice.getInstance(getInstrumentation()); + public static void openCloudServices(UiDevice device) { + openSettings(device); + + ViewInteraction recyclerView = onView(allOf(withId(R.id.recycler_view), childAtPosition(withId(android.R.id.list_container), 0))); + recyclerView.perform(RecyclerViewActions.actionOnItemAtPosition(3, click())); + + awaitCompleted(); + } + + public static void checkLoginResult(String cloudName, int cloudPosition) { + String displayText = InstrumentationRegistry // + .getTargetContext() // + .getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " " + cloudName; + + UiObject signOutText = UiDevice.getInstance(getInstrumentation()).findObject(new UiSelector().text(displayText)); + signOutText.waitForExists(15000); + + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(cloudPosition, R.id.cloudName)) // + .check(matches(withText(displayText))); + } + + private static Matcher childAtPosition(final Matcher parentMatcher, final int position) { + + return new TypeSafeMatcher() { + @Override + public void describeTo(Description description) { + description.appendText("Child at position " + position + " in parent "); + parentMatcher.describeTo(description); + } + + @Override + public boolean matchesSafely(View view) { + ViewParent parent = view.getParent(); + return parent instanceof ViewGroup && parentMatcher.matches(parent) // + && view.equals(((ViewGroup) parent).getChildAt(position)); + } + }; + } @Test public void test01EnableDebugModeLeadsToDebugMode() { @@ -206,44 +245,4 @@ public class CloudsOperationsTest { LoginLocalClouds.loginLocalClouds(device); } - - public static void openCloudServices(UiDevice device) { - openSettings(device); - - ViewInteraction recyclerView = onView(allOf(withId(R.id.recycler_view), childAtPosition(withId(android.R.id.list_container), 0))); - recyclerView.perform(RecyclerViewActions.actionOnItemAtPosition(3, click())); - - awaitCompleted(); - } - - public static void checkLoginResult(String cloudName, int cloudPosition) { - String displayText = InstrumentationRegistry // - .getTargetContext() // - .getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " " + cloudName; - - UiObject signOutText = UiDevice.getInstance(getInstrumentation()).findObject(new UiSelector().text(displayText)); - signOutText.waitForExists(15000); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(cloudPosition, R.id.cloudName)) // - .check(matches(withText(displayText))); - } - - private static Matcher childAtPosition(final Matcher parentMatcher, final int position) { - - return new TypeSafeMatcher() { - @Override - public void describeTo(Description description) { - description.appendText("Child at position " + position + " in parent "); - parentMatcher.describeTo(description); - } - - @Override - public boolean matchesSafely(View view) { - ViewParent parent = view.getParent(); - return parent instanceof ViewGroup && parentMatcher.matches(parent) // - && view.equals(((ViewGroup) parent).getChildAt(position)); - } - }; - } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FileOperationsTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FileOperationsTest.java index 6b329444..75d688fa 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FileOperationsTest.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FileOperationsTest.java @@ -60,21 +60,45 @@ public class FileOperationsTest { private final UiDevice device = UiDevice.getInstance(getInstrumentation()); private final Context context = InstrumentationRegistry.getTargetContext(); - + private final Integer cloudId; @Rule public ActivityTestRule activityTestRule // = new ActivityTestRule<>(SplashActivity.class); - private String packageName; - private final Integer cloudId; + + public FileOperationsTest(Integer cloudId, String cloudName) { + this.cloudId = cloudId; + } @Parameterized.Parameters(name = "{1}") public static Iterable data() { return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}}); } - public FileOperationsTest(Integer cloudId, String cloudName) { - this.cloudId = cloudId; + static void isPermissionShown(UiDevice device) { + if (!device // + .findObject(new UiSelector().text("ALLOW")) // + .waitForExists(1000L)) { + throw new AssertionError("View with text not found!"); + } + } + + static void grantPermission(UiDevice device) { + try { + device // + .findObject(new UiSelector().text("ALLOW")) // + .click(); + } catch (UiObjectNotFoundException e) { + throw new AssertionError("Permission not found"); + } + } + + static void openFile(int nodePosition) { + awaitCompleted(); + + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(nodePosition, R.id.cloudFileText)) // + .perform(click()); } @Test @@ -105,7 +129,7 @@ public class FileOperationsTest { try { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(1, R.id.cloudFileText)) // - .check(matches(withText(nodeName))); + .check(matches(withText(nodeName))); throw new AssertionError("Canceling the upload should not lead to new cloud node"); } catch (NullPointerException e) { @@ -506,13 +530,13 @@ public class FileOperationsTest { private void chooseShareLocation(int nodePosition) { onView(withRecyclerView(R.id.locationsRecyclerView) // .atPositionOnView(nodePosition, R.id.vaultName)) // - .perform(click()); + .perform(click()); device.waitForWindowUpdate(packageName, 300); onView(withRecyclerView(R.id.locationsRecyclerView) // .atPositionOnView(nodePosition, R.id.chooseFolderLocation)) // - .perform(click()); + .perform(click()); openFolder(0); @@ -525,7 +549,7 @@ public class FileOperationsTest { private void checkPathInSharingScreen(String path, int nodePosition) { onView(withRecyclerView(R.id.locationsRecyclerView) // .atPositionOnView(nodePosition, R.id.chosenLocation)) // - .check(matches(withText(path))); + .check(matches(withText(path))); } private void deleteTestFolder() { @@ -580,7 +604,7 @@ public class FileOperationsTest { onView(allOf( // withId(button1), // withText(R.string.dialog_rename_node_positive_button))) // - .perform(click()); + .perform(click()); awaitCompleted(); } @@ -590,7 +614,7 @@ public class FileOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(nodePosition, R.id.cloudFileText)) // - .check(matches(withText(assertNodeText))); + .check(matches(withText(assertNodeText))); } private void openMoveFile() { @@ -602,24 +626,6 @@ public class FileOperationsTest { awaitCompleted(); } - static void isPermissionShown(UiDevice device) { - if (!device // - .findObject(new UiSelector().text("ALLOW")) // - .waitForExists(1000L)) { - throw new AssertionError("View with text not found!"); - } - } - - static void grantPermission(UiDevice device) { - try { - device // - .findObject(new UiSelector().text("ALLOW")) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Permission not found"); - } - } - private void openEncryptWithCryptomator() { openShareFile(); try { @@ -659,12 +665,4 @@ public class FileOperationsTest { throw new AssertionError("Folder 0 not found"); } } - - static void openFile(int nodePosition) { - awaitCompleted(); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.cloudFileText)) // - .perform(click()); - } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FolderOperationsTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FolderOperationsTest.java index 618ebae3..73590067 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FolderOperationsTest.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FolderOperationsTest.java @@ -42,22 +42,31 @@ import static org.hamcrest.Matchers.allOf; @FixMethodOrder(MethodSorters.NAME_ASCENDING) @RunWith(Parameterized.class) public class FolderOperationsTest { + + private final UiDevice device = UiDevice.getInstance(getInstrumentation()); + private final Context context = InstrumentationRegistry.getTargetContext(); + private final Integer cloudId; @Rule public ActivityTestRule activityTestRule // = new ActivityTestRule<>(SplashActivity.class); - private final UiDevice device = UiDevice.getInstance(getInstrumentation()); - private final Context context = InstrumentationRegistry.getTargetContext(); - - private final Integer cloudId; + public FolderOperationsTest(Integer cloudId, String cloudName) { + this.cloudId = cloudId; + } @Parameterized.Parameters(name = "{1}") public static Iterable data() { return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}}); } - public FolderOperationsTest(Integer cloudId, String cloudName) { - this.cloudId = cloudId; + static void openFolder(int nodePosition) { + awaitCompleted(); + + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(nodePosition, R.id.cloudFolderText)) // + .perform(click()); + + awaitCompleted(); } @Test @@ -259,7 +268,7 @@ public class FolderOperationsTest { onView(allOf( // withId(android.R.id.button1), // withText(R.string.screen_enter_vault_name_button_text))) // - .perform(click()); + .perform(click()); awaitCompleted(); } @@ -272,7 +281,7 @@ public class FolderOperationsTest { onView(allOf( // withId(R.id.tv_folder_path), // withText(path))) // - .check(matches(withText(path))); + .check(matches(withText(path))); awaitCompleted(); } @@ -291,7 +300,7 @@ public class FolderOperationsTest { onView(allOf( // withId(android.R.id.button1), // withText(R.string.dialog_rename_node_positive_button))) // - .perform(click()); + .perform(click()); awaitCompleted(); } @@ -299,16 +308,6 @@ public class FolderOperationsTest { private void checkFolderDisplayText(String assertNodeText, int nodePosition) { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(nodePosition, R.id.cloudFolderText)) // - .check(matches(withText(assertNodeText))); - } - - static void openFolder(int nodePosition) { - awaitCompleted(); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.cloudFolderText)) // - .perform(click()); - - awaitCompleted(); + .check(matches(withText(assertNodeText))); } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginLocalClouds.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginLocalClouds.java index ba9fc221..7493cba7 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginLocalClouds.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginLocalClouds.java @@ -75,6 +75,6 @@ public class LoginLocalClouds { private static void checkResult(String folderName) { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(0, R.id.cloudText)) // - .perform(click()); + .perform(click()); } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginWebdavClouds.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginWebdavClouds.java index 1290bcb2..fe2e0284 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginWebdavClouds.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginWebdavClouds.java @@ -17,48 +17,19 @@ import static org.cryptomator.presentation.ui.activity.LoginWebdavClouds.WebdavC import static org.hamcrest.Matchers.allOf; class LoginWebdavClouds { + private static final String localUrl = "192.168.0.108"; - enum WebdavCloudCredentials { - GMX("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "jraufelder@gmx.de", "mG7!3B3Mx"), // - /* - * FREENET("https://webmail.freenet.de/webdav", "webmail.freenet.de", "milestone@freenet.de", "rF7!3B3Et") - * - * , // - * /* - * AUTHENTICATION_FAIL("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "bla@bla.de", "bla"), // - * SELF_SIGNED_HTTPS("https://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), // - * REDIRECT_TO_HTTPS("http://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), // - * REDIRECT_TO_URL("https://" + localUrl + "/bar/baz", localUrl + "/bar/baz", "bla@bla.de", "bla") - */; - - private final String url; - private final String displayUrl; - private final String username; - private final String password; - - WebdavCloudCredentials(String url, String displayUrl, String username, String password) { - this.url = url; - this.displayUrl = displayUrl; - this.username = username; - this.password = password; - } - - static List notSpecialWebdavClouds() { - return Collections.singletonList(GMX/* , FREENET */); - } - } - static void loginWebdavClouds(SplashActivity activity) { loginStandardWebdavClouds(); /* * loginAuthenticationFailWebdavCloud(activity); - * + * * loginSelfSignedWebdavCloud(); - * + * * loginRedirectToHttpsWebdavCloud(); - * + * * loginRedirectToUrlWebdavCloud(); */ } @@ -84,31 +55,36 @@ class LoginWebdavClouds { .perform(click()); } + private static void startLoginProcess() { + onView(withId(R.id.createCloudButton)) // + .perform(click()); + } + /* * private static void loginAuthenticationFailWebdavCloud(SplashActivity activity) { * createNewCloud(); * enterCredentials(AUTHENTICATION_FAIL); * startLoginProcess(); - * + * * onView(withText(R.string.error_authentication_failed)) // * .inRoot(withDecorView(not(is(activity.getWindow().getDecorView())))) // * .check(matches(isDisplayed())); - * + * * onView(allOf( // * withId(R.id.et_url_port), // * withText(AUTHENTICATION_FAIL.url))); - * + * * onView(allOf( // * withId(R.id.et_user), // * withText(AUTHENTICATION_FAIL.username))); - * + * * onView(allOf( // * withId(R.id.et_password), // * withText(AUTHENTICATION_FAIL.password))); - * + * * pressBack(); * } - * + * * private static void loginSelfSignedWebdavCloud() { * createNewCloud(); * enterCredentials(SELF_SIGNED_HTTPS); @@ -117,7 +93,7 @@ class LoginWebdavClouds { * startLoginProcess(); * checkResult(SELF_SIGNED_HTTPS); * } - * + * * private static void loginRedirectToHttpsWebdavCloud() { * createNewCloud(); * enterCredentials(REDIRECT_TO_HTTPS); @@ -127,7 +103,7 @@ class LoginWebdavClouds { * startLoginProcess(); * checkResult(REDIRECT_TO_HTTPS); * } - * + * * private static void loginRedirectToUrlWebdavCloud() { * createNewCloud(); * enterCredentials(REDIRECT_TO_URL); @@ -137,11 +113,6 @@ class LoginWebdavClouds { * } */ - private static void startLoginProcess() { - onView(withId(R.id.createCloudButton)) // - .perform(click()); - } - private static void enterCredentials(WebdavCloudCredentials webdavCloudCredential) { onView(withId(R.id.urlPortEditText)) // .perform(replaceText(webdavCloudCredential.url)); @@ -164,4 +135,34 @@ class LoginWebdavClouds { withId(R.id.cloudSubText), // withText(webdavCloudCredential.username + " • "))); } + + enum WebdavCloudCredentials { + GMX("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "jraufelder@gmx.de", "mG7!3B3Mx"), // + /* + * FREENET("https://webmail.freenet.de/webdav", "webmail.freenet.de", "milestone@freenet.de", "rF7!3B3Et") + * + * , // + * /* + * AUTHENTICATION_FAIL("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "bla@bla.de", "bla"), // + * SELF_SIGNED_HTTPS("https://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), // + * REDIRECT_TO_HTTPS("http://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), // + * REDIRECT_TO_URL("https://" + localUrl + "/bar/baz", localUrl + "/bar/baz", "bla@bla.de", "bla") + */; + + private final String url; + private final String displayUrl; + private final String username; + private final String password; + + WebdavCloudCredentials(String url, String displayUrl, String username, String password) { + this.url = url; + this.displayUrl = displayUrl; + this.username = username; + this.password = password; + } + + static List notSpecialWebdavClouds() { + return Collections.singletonList(GMX/* , FREENET */); + } + } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/VaultsOperationsTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/VaultsOperationsTest.java index 27c3fe97..2c2b6cec 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/VaultsOperationsTest.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/VaultsOperationsTest.java @@ -58,15 +58,15 @@ public class VaultsOperationsTest { private final Integer cloudId; + public VaultsOperationsTest(Integer cloudId, String cloudName) { + this.cloudId = cloudId; + } + @Parameterized.Parameters(name = "{1}") public static Iterable data() { return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}}); } - public VaultsOperationsTest(Integer cloudId, String cloudName) { - this.cloudId = cloudId; - } - @Test public void test00CreateNewVaultsLeadsToNewVaults() { ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule.getActivity().getApplication()).getComponent(); @@ -175,7 +175,7 @@ public class VaultsOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(cloudId, R.id.settings)) // - .perform(click()); + .perform(click()); waitForIdle(device); @@ -222,7 +222,7 @@ public class VaultsOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(position, R.id.settings)) // - .perform(click()); + .perform(click()); waitForIdle(device); @@ -250,37 +250,37 @@ public class VaultsOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(vaultPosition, R.id.cloud)) // - .perform(click()); + .perform(click()); String vaultnameAndPassword = "tempVault"; awaitCompleted(); switch (vaultPosition) { - case WEBDAV: - awaitCompleted(); + case WEBDAV: + awaitCompleted(); - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(0, R.id.cloudText)) // - .perform(click()); - break; - case LOCAL: - awaitCompleted(); + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(0, R.id.cloudText)) // + .perform(click()); + break; + case LOCAL: + awaitCompleted(); - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(0, R.id.cloudText)) // - .perform(click()); + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(0, R.id.cloudText)) // + .perform(click()); - awaitCompleted(); + awaitCompleted(); - isPermissionShown(device); - grantPermission(device); + isPermissionShown(device); + grantPermission(device); - removeFolderInCloud(appComponent, path, CloudType.LOCAL); - removeFolderInCloud(appComponent, "0/testVault/", CloudType.LOCAL); - removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.LOCAL); + removeFolderInCloud(appComponent, path, CloudType.LOCAL); + removeFolderInCloud(appComponent, "0/testVault/", CloudType.LOCAL); + removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.LOCAL); - break; + break; } awaitCompleted(); @@ -317,26 +317,26 @@ public class VaultsOperationsTest { private void openVault(int vaultPosition) { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(vaultPosition, R.id.cloud)) // - .perform(click()); + .perform(click()); awaitCompleted(); switch (vaultPosition) { - case WEBDAV: - awaitCompleted(); + case WEBDAV: + awaitCompleted(); - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(0, R.id.cloudText)) // - .perform(click()); - break; - case LOCAL: - awaitCompleted(); + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(0, R.id.cloudText)) // + .perform(click()); + break; + case LOCAL: + awaitCompleted(); - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(0, R.id.cloudText)) // - .perform(click()); + onView(withRecyclerView(R.id.recyclerView) // + .atPositionOnView(0, R.id.cloudText)) // + .perform(click()); - break; + break; } awaitCompleted(); @@ -355,7 +355,7 @@ public class VaultsOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(vaultPosition, R.id.vaultName)) // - .perform(click()); + .perform(click()); device // .findObject(new UiSelector().text("Password")) // @@ -376,7 +376,7 @@ public class VaultsOperationsTest { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(position, R.id.settings)) // - .perform(click()); + .perform(click()); waitForIdle(device); @@ -403,10 +403,10 @@ public class VaultsOperationsTest { private void checkVault(int position, String name) { onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(position, R.id.vaultName)) // - .check(matches(withText(name))); + .check(matches(withText(name))); onView(withRecyclerView(R.id.recyclerView) // .atPositionOnView(position, R.id.vaultPath)) // - .check(matches(withText("/0/" + name))); + .check(matches(withText("/0/" + name))); } } diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/UiTestSuite.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/UiTestSuite.java index 8f3abc47..e711df54 100644 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/UiTestSuite.java +++ b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/UiTestSuite.java @@ -17,4 +17,5 @@ import org.junit.runners.Suite; FileOperationsTest.class // }) public class UiTestSuite { + } diff --git a/presentation/src/debug/res/drawable/ic_launcher_background.xml b/presentation/src/debug/res/drawable/ic_launcher_background.xml index adffe5a8..d8544c4f 100644 --- a/presentation/src/debug/res/drawable/ic_launcher_background.xml +++ b/presentation/src/debug/res/drawable/ic_launcher_background.xml @@ -1,78 +1,176 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:width="108dp" + android:height="108dp" + android:viewportWidth="108" + android:viewportHeight="108"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml index 036d09bc..4a0eb132 100644 --- a/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09bc..4a0eb132 100644 --- a/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/presentation/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/presentation/src/debug/res/values/ic_launcher_background.xml b/presentation/src/debug/res/values/ic_launcher_background.xml index e50a17c8..23e58742 100644 --- a/presentation/src/debug/res/values/ic_launcher_background.xml +++ b/presentation/src/debug/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #F1C40F - \ No newline at end of file + #F1C40F + diff --git a/presentation/src/foss/java/org/cryptomator/presentation/presenter/AuthenticateCloudPresenter.kt b/presentation/src/foss/java/org/cryptomator/presentation/presenter/AuthenticateCloudPresenter.kt index a8fee1c0..5bdc211c 100644 --- a/presentation/src/foss/java/org/cryptomator/presentation/presenter/AuthenticateCloudPresenter.kt +++ b/presentation/src/foss/java/org/cryptomator/presentation/presenter/AuthenticateCloudPresenter.kt @@ -123,6 +123,7 @@ class AuthenticateCloudPresenter @Inject constructor( // } private inner class DropboxAuthStrategy : AuthStrategy { + private var authenticationStarted = false override fun supports(cloud: CloudModel): Boolean { return cloud.cloudType() == CloudTypeModel.DROPBOX @@ -179,6 +180,7 @@ class AuthenticateCloudPresenter @Inject constructor( // } private inner class OnedriveAuthStrategy : AuthStrategy { + private var authenticationStarted = false override fun supports(cloud: CloudModel): Boolean { return cloud.cloudType() == CloudTypeModel.ONEDRIVE @@ -220,6 +222,7 @@ class AuthenticateCloudPresenter @Inject constructor( // } private inner class WebDAVAuthStrategy : AuthStrategy { + override fun supports(cloud: CloudModel): Boolean { return cloud.cloudType() == CloudTypeModel.WEBDAV } @@ -279,6 +282,7 @@ class AuthenticateCloudPresenter @Inject constructor( // } private inner class LocalStorageAuthStrategy : AuthStrategy { + private var authenticationStarted = false override fun supports(cloud: CloudModel): Boolean { return cloud.cloudType() == CloudTypeModel.LOCAL @@ -315,6 +319,7 @@ class AuthenticateCloudPresenter @Inject constructor( // } private inner class FailingAuthStrategy : AuthStrategy { + override fun supports(cloud: CloudModel): Boolean { return false } @@ -326,11 +331,13 @@ class AuthenticateCloudPresenter @Inject constructor( // } private interface AuthStrategy { + fun supports(cloud: CloudModel): Boolean fun resumed(intent: AuthenticateCloudIntent) } companion object { + const val WEBDAV_ACCEPTED_UNTRUSTED_CERTIFICATE = "acceptedUntrustedCertificate" } diff --git a/presentation/src/main/java/org/cryptomator/presentation/AutoPhotoUploadReceiver.kt b/presentation/src/main/java/org/cryptomator/presentation/AutoPhotoUploadReceiver.kt index 213a72cf..abdfb0c5 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/AutoPhotoUploadReceiver.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/AutoPhotoUploadReceiver.kt @@ -10,6 +10,7 @@ import org.cryptomator.util.file.MimeTypes import timber.log.Timber class AutoPhotoUploadReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { if (!SharedPreferencesHandler(context).usePhotoUpload()) { return diff --git a/presentation/src/main/java/org/cryptomator/presentation/CryptomatorApp.kt b/presentation/src/main/java/org/cryptomator/presentation/CryptomatorApp.kt index 685dbc73..0a038af9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/CryptomatorApp.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/CryptomatorApp.kt @@ -9,7 +9,6 @@ import android.os.Build import android.os.IBinder import androidx.appcompat.app.AppCompatDelegate import androidx.multidex.MultiDexApplication -import io.reactivex.plugins.RxJavaPlugins import org.cryptomator.data.cloud.crypto.Cryptors import org.cryptomator.data.cloud.crypto.CryptorsModule import org.cryptomator.data.repository.RepositoryModule @@ -25,8 +24,9 @@ import org.cryptomator.presentation.service.AutoUploadService import org.cryptomator.presentation.service.CryptorsService import org.cryptomator.util.NoOpActivityLifecycleCallbacks import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import java.util.concurrent.atomic.AtomicInteger +import io.reactivex.plugins.RxJavaPlugins +import timber.log.Timber class CryptomatorApp : MultiDexApplication(), HasComponent { @@ -48,7 +48,8 @@ class CryptomatorApp : MultiDexApplication(), HasComponent } "fdroid" -> { "F-Droid Edition" - } else -> "Google Play Edition" + } + else -> "Google Play Edition" } Timber.tag("App").i("Cryptomator v%s (%d) \"%s\" started on android %s / API%d using a %s", // BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, flavor, // @@ -180,6 +181,7 @@ class CryptomatorApp : MultiDexApplication(), HasComponent } companion object { + private lateinit var applicationContext: Context fun applicationContext(): Context { return applicationContext diff --git a/presentation/src/main/java/org/cryptomator/presentation/UIThread.kt b/presentation/src/main/java/org/cryptomator/presentation/UIThread.kt index 5f4b6d69..be266642 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/UIThread.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/UIThread.kt @@ -1,10 +1,10 @@ package org.cryptomator.presentation -import io.reactivex.Scheduler -import io.reactivex.android.schedulers.AndroidSchedulers import org.cryptomator.domain.executor.PostExecutionThread import javax.inject.Inject import javax.inject.Singleton +import io.reactivex.Scheduler +import io.reactivex.android.schedulers.AndroidSchedulers /** * MainThread (UI Thread) implementation based on a [io.reactivex.Scheduler] @@ -12,6 +12,7 @@ import javax.inject.Singleton */ @Singleton class UIThread @Inject constructor() : PostExecutionThread { + override fun getScheduler(): Scheduler { return AndroidSchedulers.mainThread() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/di/HasComponent.java b/presentation/src/main/java/org/cryptomator/presentation/di/HasComponent.java index 2edc3955..63fcd5d5 100755 --- a/presentation/src/main/java/org/cryptomator/presentation/di/HasComponent.java +++ b/presentation/src/main/java/org/cryptomator/presentation/di/HasComponent.java @@ -4,5 +4,6 @@ package org.cryptomator.presentation.di; * Interface representing a contract for clients that contains a component for dependency injection. */ public interface HasComponent { + C getComponent(); } diff --git a/presentation/src/main/java/org/cryptomator/presentation/di/component/ActivityComponent.java b/presentation/src/main/java/org/cryptomator/presentation/di/component/ActivityComponent.java index db438ffd..673b0d2e 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/di/component/ActivityComponent.java +++ b/presentation/src/main/java/org/cryptomator/presentation/di/component/ActivityComponent.java @@ -6,30 +6,30 @@ import org.cryptomator.domain.di.PerView; import org.cryptomator.presentation.di.module.ActivityModule; import org.cryptomator.presentation.ui.activity.AuthenticateCloudActivity; import org.cryptomator.presentation.ui.activity.AutoUploadChooseVaultActivity; +import org.cryptomator.presentation.ui.activity.BiometricAuthSettingsActivity; import org.cryptomator.presentation.ui.activity.BrowseFilesActivity; import org.cryptomator.presentation.ui.activity.ChooseCloudServiceActivity; import org.cryptomator.presentation.ui.activity.CloudConnectionListActivity; import org.cryptomator.presentation.ui.activity.CloudSettingsActivity; import org.cryptomator.presentation.ui.activity.CreateVaultActivity; import org.cryptomator.presentation.ui.activity.EmptyDirIdFileInfoActivity; -import org.cryptomator.presentation.ui.activity.BiometricAuthSettingsActivity; import org.cryptomator.presentation.ui.activity.ImagePreviewActivity; +import org.cryptomator.presentation.ui.activity.LicenseCheckActivity; import org.cryptomator.presentation.ui.activity.LicensesActivity; import org.cryptomator.presentation.ui.activity.SetPasswordActivity; import org.cryptomator.presentation.ui.activity.SettingsActivity; import org.cryptomator.presentation.ui.activity.SharedFilesActivity; import org.cryptomator.presentation.ui.activity.SplashActivity; import org.cryptomator.presentation.ui.activity.TextEditorActivity; -import org.cryptomator.presentation.ui.activity.LicenseCheckActivity; import org.cryptomator.presentation.ui.activity.VaultListActivity; import org.cryptomator.presentation.ui.activity.WebDavAddOrChangeActivity; import org.cryptomator.presentation.ui.fragment.AutoUploadChooseVaultFragment; +import org.cryptomator.presentation.ui.fragment.BiometricAuthSettingsFragment; import org.cryptomator.presentation.ui.fragment.BrowseFilesFragment; import org.cryptomator.presentation.ui.fragment.ChooseCloudServiceFragment; import org.cryptomator.presentation.ui.fragment.CloudConnectionListFragment; import org.cryptomator.presentation.ui.fragment.CloudSettingsFragment; import org.cryptomator.presentation.ui.fragment.EmptyDirIdFileInfoFragment; -import org.cryptomator.presentation.ui.fragment.BiometricAuthSettingsFragment; import org.cryptomator.presentation.ui.fragment.ImagePreviewFragment; import org.cryptomator.presentation.ui.fragment.SetPasswordFragment; import org.cryptomator.presentation.ui.fragment.SharedFilesFragment; diff --git a/presentation/src/main/java/org/cryptomator/presentation/di/module/ActivityModule.java b/presentation/src/main/java/org/cryptomator/presentation/di/module/ActivityModule.java index 3c88c628..9a2ad085 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/di/module/ActivityModule.java +++ b/presentation/src/main/java/org/cryptomator/presentation/di/module/ActivityModule.java @@ -1,4 +1,3 @@ - package org.cryptomator.presentation.di.module; import android.app.Activity; @@ -10,6 +9,7 @@ import dagger.Provides; @Module public class ActivityModule { + private final Activity activity; public ActivityModule(Activity activity) { diff --git a/presentation/src/main/java/org/cryptomator/presentation/e/c.java b/presentation/src/main/java/org/cryptomator/presentation/e/c.java index 8cba6ec2..f746838e 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/e/c.java +++ b/presentation/src/main/java/org/cryptomator/presentation/e/c.java @@ -6,9 +6,9 @@ import java.util.Set; /** * This file is the obfuscated AutoUploadFilesStore of Cryptomator in version 1.5.10 * and is used to recover it in version 1.5.11 and 1.5.11-beta2 - * + *

* TODO Delete as soon as possible - * + *

* See more information: https://github.com/cryptomator/android/issues/250 */ @@ -26,7 +26,7 @@ public final class c implements Serializable { public boolean equals(Object paramObject) { if (this != paramObject) { if (paramObject instanceof c) { - Object paramObject2 = ((c)paramObject).vlb; + Object paramObject2 = ((c) paramObject).vlb; return (this.vlb == null) ? ((paramObject2 == null)) : this.vlb.equals(paramObject2); } return false; @@ -52,6 +52,8 @@ public final class c implements Serializable { } public static final class a { - private a() {} + + private a() { + } } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/exception/DefaultExceptionHandler.kt b/presentation/src/main/java/org/cryptomator/presentation/exception/DefaultExceptionHandler.kt index e0caebbd..51e3ff16 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/exception/DefaultExceptionHandler.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/exception/DefaultExceptionHandler.kt @@ -4,8 +4,8 @@ import android.content.Context import org.cryptomator.domain.di.PerView import org.cryptomator.presentation.R import org.cryptomator.presentation.ui.activity.view.View -import timber.log.Timber import javax.inject.Inject +import timber.log.Timber @PerView class DefaultExceptionHandler @Inject constructor(context: Context) : ExceptionHandler() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt b/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt index 33d72964..b50bfc4a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt @@ -5,7 +5,12 @@ import android.content.Context import org.cryptomator.cryptolib.api.InvalidPassphraseException import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException import org.cryptomator.domain.di.PerView -import org.cryptomator.domain.exception.* +import org.cryptomator.domain.exception.CloudAlreadyExistsException +import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException +import org.cryptomator.domain.exception.NetworkConnectionException +import org.cryptomator.domain.exception.NoSuchCloudFileException +import org.cryptomator.domain.exception.UnableToDecryptWebdavPasswordException +import org.cryptomator.domain.exception.VaultAlreadyExistException import org.cryptomator.domain.exception.authentication.AuthenticationException import org.cryptomator.domain.exception.license.LicenseNotValidException import org.cryptomator.domain.exception.license.NoLicenseAvailableException @@ -13,9 +18,10 @@ import org.cryptomator.domain.exception.update.GeneralUpdateErrorException import org.cryptomator.domain.exception.update.SSLHandshakePreAndroid5UpdateCheckException import org.cryptomator.presentation.R import org.cryptomator.presentation.ui.activity.view.View -import timber.log.Timber -import java.util.* +import java.util.ArrayList +import java.util.Collections import javax.inject.Inject +import timber.log.Timber @PerView class ExceptionHandlers @Inject constructor(private val context: Context, defaultExceptionHandler: DefaultExceptionHandler) : Iterable { diff --git a/presentation/src/main/java/org/cryptomator/presentation/exception/NoSuchVaultExceptionHandler.kt b/presentation/src/main/java/org/cryptomator/presentation/exception/NoSuchVaultExceptionHandler.kt index 65eede96..3d0eae28 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/exception/NoSuchVaultExceptionHandler.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/exception/NoSuchVaultExceptionHandler.kt @@ -6,6 +6,7 @@ import org.cryptomator.presentation.ui.dialog.VaultNotFoundDialog.Companion.with import org.cryptomator.util.ExceptionUtil class NoSuchVaultExceptionHandler : ExceptionHandler() { + override fun supports(e: Throwable): Boolean { return ExceptionUtil.contains(e, NoSuchVaultException::class.java) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/i/a.java b/presentation/src/main/java/org/cryptomator/presentation/i/a.java index 9444f86d..f91cd954 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/i/a.java +++ b/presentation/src/main/java/org/cryptomator/presentation/i/a.java @@ -6,9 +6,9 @@ import java.util.Set; /** * This file is the obfuscated AutoUploadFilesStore of Cryptomator in version 1.5.11-beta1 * and is used to recover it in version 1.5.11-beta2 - * + *

* TODO Delete as soon as possible - * + *

* See more information: https://github.com/cryptomator/android/issues/250 */ @@ -28,7 +28,7 @@ public final class a implements Serializable { public boolean equals(Object paramObject) { if (this != paramObject) { if (paramObject instanceof a) { - Object paramObject2 = ((a)paramObject).b; + Object paramObject2 = ((a) paramObject).b; return (this.b == null) ? ((paramObject2 == null)) : this.b.equals(paramObject2); } return false; diff --git a/presentation/src/main/java/org/cryptomator/presentation/intent/ChooseCloudNodeSettings.java b/presentation/src/main/java/org/cryptomator/presentation/intent/ChooseCloudNodeSettings.java index 721d8a9e..bfeb8104 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/intent/ChooseCloudNodeSettings.java +++ b/presentation/src/main/java/org/cryptomator/presentation/intent/ChooseCloudNodeSettings.java @@ -1,5 +1,7 @@ package org.cryptomator.presentation.intent; +import androidx.annotation.Nullable; + import org.cryptomator.presentation.model.CloudFolderModel; import java.io.Serializable; @@ -7,17 +9,14 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; -import androidx.annotation.Nullable; - import static org.cryptomator.presentation.intent.ChooseCloudNodeSettings.SelectionMode.FILES_ONLY; import static org.cryptomator.presentation.intent.ChooseCloudNodeSettings.SelectionMode.FOLDERS_ONLY; public class ChooseCloudNodeSettings implements Serializable { + public static final int NO_ICON = -1; private static final Pattern ANY_NAME = Pattern.compile(".*"); private static final Pattern NO_NAME = Pattern.compile(""); - public static final int NO_ICON = -1; - private final String extraTitle; private final String extraText; private final String buttonText; @@ -43,6 +42,10 @@ public class ChooseCloudNodeSettings implements Serializable { this.navigationMode = builder.navigationMode; } + public static Builder chooseCloudNodeSettings() { + return new Builder(); + } + @Nullable public String extraTitle() { return extraTitle; @@ -85,18 +88,39 @@ public class ChooseCloudNodeSettings implements Serializable { return navigationMode; } - public static Builder chooseCloudNodeSettings() { - return new Builder(); + public enum SelectionMode { + FILES_ONLY(true, true), FOLDERS_ONLY(false, true); + + private final boolean allowsFolders; + private final boolean allowsFiles; + + SelectionMode(boolean allowsFiles, boolean allowsFolders) { + this.allowsFiles = allowsFiles; + this.allowsFolders = allowsFolders; + } + + public boolean allowsFolders() { + return allowsFolders; + } + + public boolean allowsFiles() { + return allowsFiles; + } + + } + + public enum NavigationMode { + BROWSE_FILES, MOVE_CLOUD_NODE, SELECT_ITEMS } public static class Builder { + private final Pattern excludeFoldersContainingNamePattern = NO_NAME; private String extraTitle; private String extraText; private String buttonText; private SelectionMode selectionMode; private Pattern namePattern = ANY_NAME; - private final Pattern excludeFoldersContainingNamePattern = NO_NAME; private int extraToolbarIcon = NO_ICON; private NavigationMode navigationMode = NavigationMode.BROWSE_FILES; private List excludeFolders; @@ -171,29 +195,4 @@ public class ChooseCloudNodeSettings implements Serializable { } - public enum SelectionMode { - FILES_ONLY(true, true), FOLDERS_ONLY(false, true); - - private final boolean allowsFolders; - private final boolean allowsFiles; - - SelectionMode(boolean allowsFiles, boolean allowsFolders) { - this.allowsFiles = allowsFiles; - this.allowsFolders = allowsFolders; - } - - public boolean allowsFolders() { - return allowsFolders; - } - - public boolean allowsFiles() { - return allowsFiles; - } - - } - - public enum NavigationMode { - BROWSE_FILES, MOVE_CLOUD_NODE, SELECT_ITEMS - } - } diff --git a/presentation/src/main/java/org/cryptomator/presentation/intent/CloudSettingsIntent.java b/presentation/src/main/java/org/cryptomator/presentation/intent/CloudSettingsIntent.java index 4533c599..f0c520b3 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/intent/CloudSettingsIntent.java +++ b/presentation/src/main/java/org/cryptomator/presentation/intent/CloudSettingsIntent.java @@ -5,4 +5,5 @@ import org.cryptomator.presentation.ui.activity.CloudSettingsActivity; @Intent(CloudSettingsActivity.class) public interface CloudSettingsIntent { + } diff --git a/presentation/src/main/java/org/cryptomator/presentation/intent/SettingsIntent.java b/presentation/src/main/java/org/cryptomator/presentation/intent/SettingsIntent.java index b9f296ba..ae308096 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/intent/SettingsIntent.java +++ b/presentation/src/main/java/org/cryptomator/presentation/intent/SettingsIntent.java @@ -5,4 +5,5 @@ import org.cryptomator.presentation.ui.activity.SettingsActivity; @Intent(SettingsActivity.class) public interface SettingsIntent { + } diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/CrashLogging.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/CrashLogging.kt index 1cba6304..fd101201 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/CrashLogging.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/CrashLogging.kt @@ -10,6 +10,7 @@ class CrashLogging private constructor(private val systemUncaughtExceptionHandle } companion object { + fun setup() { Thread.setDefaultUncaughtExceptionHandler(CrashLogging(Thread.getDefaultUncaughtExceptionHandler())) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/DebugLogger.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/DebugLogger.kt index 0a7fb570..55f646c0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/DebugLogger.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/DebugLogger.kt @@ -3,6 +3,7 @@ package org.cryptomator.presentation.logging import timber.log.Timber.DebugTree class DebugLogger : DebugTree() { + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { val loggingMessage = if (t != null) { """ diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/FormattedTime.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/FormattedTime.kt index cc61c120..148113c0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/FormattedTime.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/FormattedTime.kt @@ -1,7 +1,8 @@ package org.cryptomator.presentation.logging import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale internal class FormattedTime private constructor(private val timestamp: Long) { @@ -16,6 +17,7 @@ internal class FormattedTime private constructor(private val timestamp: Long) { } companion object { + private const val FORMAT = "yyyyMMddHHmmss.SSS" @Volatile diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/GeneratedErrorCode.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/GeneratedErrorCode.kt index 9f654038..27bded58 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/GeneratedErrorCode.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/GeneratedErrorCode.kt @@ -1,6 +1,6 @@ package org.cryptomator.presentation.logging -import java.util.* +import java.util.Locale internal object GeneratedErrorCode { diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/Logfiles.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/Logfiles.kt index 065ac882..8ae305aa 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/Logfiles.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/Logfiles.kt @@ -2,7 +2,7 @@ package org.cryptomator.presentation.logging import android.content.Context import java.io.File -import java.util.* +import java.util.ArrayList object Logfiles { diff --git a/presentation/src/main/java/org/cryptomator/presentation/logging/ReleaseLogger.kt b/presentation/src/main/java/org/cryptomator/presentation/logging/ReleaseLogger.kt index e89a6833..7ea1ba05 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/logging/ReleaseLogger.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/logging/ReleaseLogger.kt @@ -43,6 +43,7 @@ class ReleaseLogger(context: Context) : Timber.Tree() { } companion object { + private const val LOG_LEVEL_WHEN_DEBUG_IS_DISABLED = Log.INFO @Volatile diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/AutoUploadFilesStore.kt b/presentation/src/main/java/org/cryptomator/presentation/model/AutoUploadFilesStore.kt index d2f08ecf..5b932565 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/AutoUploadFilesStore.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/AutoUploadFilesStore.kt @@ -5,7 +5,9 @@ import java.io.Serializable data class AutoUploadFilesStore( val uris: Set ) : Serializable { + companion object { + private const val serialVersionUID: Long = 8901228478188469059 } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/CloudTypeModel.kt b/presentation/src/main/java/org/cryptomator/presentation/model/CloudTypeModel.kt index ca16deb3..edb4256a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/CloudTypeModel.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/CloudTypeModel.kt @@ -31,6 +31,7 @@ enum class CloudTypeModel(builder: Builder) { val isMultiInstance: Boolean = builder.multiInstances private class Builder(val cloudName: String, val displayNameResource: Int) { + var cloudImageResource = 0 var cloudImageLargeResource = 0 var multiInstances = false @@ -52,6 +53,7 @@ enum class CloudTypeModel(builder: Builder) { } companion object { + fun valueOf(type: CloudType): CloudTypeModel { return valueOf(type.name) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/FileProgressStateModel.kt b/presentation/src/main/java/org/cryptomator/presentation/model/FileProgressStateModel.kt index 562fa8f1..14e8fbec 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/FileProgressStateModel.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/FileProgressStateModel.kt @@ -12,6 +12,7 @@ class FileProgressStateModel(file: CloudFile, icon: FileIcon, name: String, imag } companion object { + const val UPLOAD = "UPLOAD" const val ENCRYPTION = "ENCRYPTION" const val DOWNLOAD = "DOWNLOAD" diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressModel.kt b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressModel.kt index 8e7ce1dd..f2b7e1fe 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressModel.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressModel.kt @@ -13,6 +13,7 @@ class ProgressModel constructor(private val state: ProgressStateModel, private v } companion object { + @JvmField val GENERIC = ProgressModel(ProgressStateModel.UNKNOWN) diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt index f67a55c0..18a2372f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt @@ -23,10 +23,12 @@ open class ProgressStateModel private constructor(private val name: String, imag } interface Image { + fun id(): Int } interface Text { + fun id(): Int } @@ -35,6 +37,7 @@ open class ProgressStateModel private constructor(private val name: String, imag } companion object { + val AUTHENTICATION = ProgressStateModel("AUTHENTICATION", text(R.string.action_progress_authentication)) val RENAMING = ProgressStateModel("RENAMING", text(R.string.action_progress_renaming)) val MOVING = ProgressStateModel("MOVING", text(R.string.action_progress_moving), false) diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudModelComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudModelComparator.kt index c3209967..e9fd6527 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudModelComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudModelComparator.kt @@ -3,9 +3,11 @@ package org.cryptomator.presentation.model.comparator import android.content.Context import org.cryptomator.presentation.model.CloudModel import org.cryptomator.presentation.model.WebDavCloudModel -import java.util.* +import java.util.Comparator +import java.util.Locale class CloudModelComparator(private val context: Context) : Comparator { + override fun compare(o1: CloudModel, o2: CloudModel): Int { return if (o1 is WebDavCloudModel && o2 is WebDavCloudModel) { o1.url().compareTo(o2.url().toUpperCase(Locale.getDefault()), ignoreCase = true) diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateNewestFirstComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateNewestFirstComparator.kt index aa1f652d..cfb81d5a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateNewestFirstComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateNewestFirstComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelDateNewestFirstComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>?, o2: CloudNodeModel<*>?): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateOldestFirstComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateOldestFirstComparator.kt index 4413c812..0d189dde 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateOldestFirstComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelDateOldestFirstComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelDateOldestFirstComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>?, o2: CloudNodeModel<*>?): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameAZComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameAZComparator.kt index a1a85088..c2426363 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameAZComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameAZComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelNameAZComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>, o2: CloudNodeModel<*>): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameZAComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameZAComparator.kt index dab09afa..ca374873 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameZAComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelNameZAComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelNameZAComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>, o2: CloudNodeModel<*>): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeBiggestFirstComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeBiggestFirstComparator.kt index 79660cf7..58db65c6 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeBiggestFirstComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeBiggestFirstComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelSizeBiggestFirstComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>?, o2: CloudNodeModel<*>?): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeSmallestFirstComparator.kt b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeSmallestFirstComparator.kt index 339dc84f..3772b7a9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeSmallestFirstComparator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/comparator/CloudNodeModelSizeSmallestFirstComparator.kt @@ -3,9 +3,9 @@ package org.cryptomator.presentation.model.comparator import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel -import kotlin.Comparator class CloudNodeModelSizeSmallestFirstComparator : Comparator> { + override fun compare(o1: CloudNodeModel<*>?, o2: CloudNodeModel<*>?): Int { return if (o1 is CloudFolderModel && o2 is CloudFileModel) { -1 diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudFolderModelMapper.kt b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudFolderModelMapper.kt index 9642ff9d..38dc25e9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudFolderModelMapper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudFolderModelMapper.kt @@ -6,6 +6,7 @@ import org.cryptomator.presentation.model.CloudFolderModel import javax.inject.Inject class CloudFolderModelMapper @Inject constructor() : ModelMapper() { + override fun fromModel(model: CloudFolderModel): CloudFolder { return model.toCloudNode() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudModelMapper.kt b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudModelMapper.kt index 9beca39f..0e0a0837 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudModelMapper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudModelMapper.kt @@ -2,11 +2,19 @@ package org.cryptomator.presentation.model.mappers import org.cryptomator.domain.Cloud import org.cryptomator.domain.di.PerView -import org.cryptomator.presentation.model.* +import org.cryptomator.presentation.model.CloudModel +import org.cryptomator.presentation.model.CloudTypeModel +import org.cryptomator.presentation.model.CryptoCloudModel +import org.cryptomator.presentation.model.DropboxCloudModel +import org.cryptomator.presentation.model.GoogleDriveCloudModel +import org.cryptomator.presentation.model.LocalStorageModel +import org.cryptomator.presentation.model.OnedriveCloudModel +import org.cryptomator.presentation.model.WebDavCloudModel import javax.inject.Inject @PerView class CloudModelMapper @Inject constructor() : ModelMapper() { + override fun fromModel(model: CloudModel): Cloud { return model.toCloud() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudNodeModelMapper.kt b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudNodeModelMapper.kt index 2f0410ee..86d47fa2 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudNodeModelMapper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/CloudNodeModelMapper.kt @@ -8,6 +8,7 @@ import org.cryptomator.presentation.model.CloudNodeModel import javax.inject.Inject class CloudNodeModelMapper @Inject constructor(private val cloudFileModelMapper: CloudFileModelMapper, private val cloudFolderModelMapper: CloudFolderModelMapper) : ModelMapper, CloudNode>() { + override fun fromModel(model: CloudNodeModel<*>): CloudNode { return model.toCloudNode() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressModelMapper.kt b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressModelMapper.kt index b3a571ad..44232c24 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressModelMapper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressModelMapper.kt @@ -5,6 +5,7 @@ import org.cryptomator.presentation.model.ProgressModel import javax.inject.Inject class ProgressModelMapper @Inject internal constructor(private val progressStateModelMapper: ProgressStateModelMapper) : ModelMapper>() { + /** * @throws IllegalStateException */ diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressStateModelMapper.kt b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressStateModelMapper.kt index 4bf42e6f..11a9f370 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressStateModelMapper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/mappers/ProgressStateModelMapper.kt @@ -11,6 +11,7 @@ import org.cryptomator.presentation.util.FileUtil import javax.inject.Inject class ProgressStateModelMapper @Inject internal constructor(private val fileUtil: FileUtil) : ModelMapper() { + /** * @throws IllegalStateException */ diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/BiometricAuthSettingsPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/BiometricAuthSettingsPresenter.kt index be51938a..4a3ee4fe 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/BiometricAuthSettingsPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/BiometricAuthSettingsPresenter.kt @@ -16,9 +16,9 @@ import org.cryptomator.presentation.ui.activity.view.BiometricAuthSettingsView import org.cryptomator.presentation.workflow.ActivityResult import org.cryptomator.presentation.workflow.AuthenticationExceptionHandler import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import java.util.* import javax.inject.Inject +import timber.log.Timber @PerView class BiometricAuthSettingsPresenter @Inject constructor( // diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt index d053b17a..e9151719 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt @@ -43,7 +43,6 @@ import org.cryptomator.util.Supplier import org.cryptomator.util.file.FileCacheUtils import org.cryptomator.util.file.MimeType import org.cryptomator.util.file.MimeTypes -import timber.log.Timber import java.io.* import java.security.DigestInputStream import java.security.MessageDigest @@ -51,6 +50,7 @@ import java.util.* import javax.inject.Inject import kotlin.collections.ArrayList import kotlin.reflect.KClass +import timber.log.Timber @PerView class BrowseFilesPresenter @Inject constructor( // @@ -1179,6 +1179,7 @@ class BrowseFilesPresenter @Inject constructor( // private val enableRefreshOnBackpressSupplier = RefreshSupplier() class RefreshSupplier : Supplier { + private var inSelectionMode = false private var inAction = false fun setInAction(inAction: Boolean): RefreshSupplier { @@ -1197,6 +1198,7 @@ class BrowseFilesPresenter @Inject constructor( // } companion object { + const val OPEN_FILE_FINISHED = 12 val EXPORT_AFTER_APP_CHOOSER: ExportOperation = object : ExportOperation { override fun export(presenter: BrowseFilesPresenter, downloadFiles: List) { diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/ChooseCloudServicePresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/ChooseCloudServicePresenter.kt index 9091c8a6..f5935d56 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/ChooseCloudServicePresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/ChooseCloudServicePresenter.kt @@ -34,7 +34,7 @@ class ChooseCloudServicePresenter @Inject constructor( // val cloudTypeModels: MutableList = ArrayList(listOf(*CloudTypeModel.values())) cloudTypeModels.remove(CloudTypeModel.CRYPTO) - if(BuildConfig.FLAVOR == "fdroid") { + if (BuildConfig.FLAVOR == "fdroid") { cloudTypeModels.remove(CloudTypeModel.GOOGLE_DRIVE) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudConnectionListPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudConnectionListPresenter.kt index b4a11094..fae5629b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudConnectionListPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudConnectionListPresenter.kt @@ -26,10 +26,10 @@ import org.cryptomator.presentation.model.WebDavCloudModel import org.cryptomator.presentation.model.mappers.CloudModelMapper import org.cryptomator.presentation.ui.activity.view.CloudConnectionListView import org.cryptomator.presentation.workflow.ActivityResult -import timber.log.Timber import java.util.* import java.util.concurrent.atomic.AtomicReference import javax.inject.Inject +import timber.log.Timber @PerView class CloudConnectionListPresenter @Inject constructor( // @@ -208,6 +208,7 @@ class CloudConnectionListPresenter @Inject constructor( // } companion object { + const val SELECTED_CLOUD = "selectedCloudConnection" } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudSettingsPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudSettingsPresenter.kt index c8893477..b4f1af61 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudSettingsPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/CloudSettingsPresenter.kt @@ -20,7 +20,7 @@ import org.cryptomator.presentation.model.WebDavCloudModel import org.cryptomator.presentation.model.mappers.CloudModelMapper import org.cryptomator.presentation.ui.activity.view.CloudSettingsView import org.cryptomator.presentation.workflow.ActivityResult -import java.util.* +import java.util.EnumSet import javax.inject.Inject @PerView @@ -30,6 +30,7 @@ class CloudSettingsPresenter @Inject constructor( // private val logoutCloudUsecase: LogoutCloudUseCase, // private val cloudModelMapper: CloudModelMapper, // exceptionMappings: ExceptionHandlers) : Presenter(exceptionMappings) { + private val nonSingleLoginClouds: Set = EnumSet.of( // CloudTypeModel.CRYPTO, // CloudTypeModel.LOCAL, // @@ -114,10 +115,11 @@ class CloudSettingsPresenter @Inject constructor( // } private inner class CloudsSubscriber : DefaultResultHandler>() { + override fun onSuccess(clouds: List) { val cloudModel = cloudModelMapper.toModels(clouds) // .filter { isSingleLoginCloud(it) } // - .filter { cloud -> !(BuildConfig.FLAVOR == "fdroid" && cloud.cloudType() == CloudTypeModel.GOOGLE_DRIVE)} // + .filter { cloud -> !(BuildConfig.FLAVOR == "fdroid" && cloud.cloudType() == CloudTypeModel.GOOGLE_DRIVE) } // .toMutableList() // .also { it.add(aWebdavCloud()) diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/ContextHolder.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/ContextHolder.kt index ad4de169..83f184a3 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/ContextHolder.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/ContextHolder.kt @@ -3,5 +3,6 @@ package org.cryptomator.presentation.presenter import android.content.Context interface ContextHolder { + fun context(): Context } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/EmptyDirIdFileInfoPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/EmptyDirIdFileInfoPresenter.kt index e59ae5e0..25dd5a32 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/EmptyDirIdFileInfoPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/EmptyDirIdFileInfoPresenter.kt @@ -9,6 +9,7 @@ import javax.inject.Inject @PerView class EmptyDirIdFileInfoPresenter @Inject constructor(exceptionMappings: ExceptionHandlers) : Presenter(exceptionMappings) { + fun onShowMoreInfoButtonPressed() { val intent = Intent(Intent.ACTION_VIEW) intent.data = Uri.parse("https://cryptomator.org/help/articles/sanitizer") diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/ImagePreviewPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/ImagePreviewPresenter.kt index da636827..11783100 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/ImagePreviewPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/ImagePreviewPresenter.kt @@ -30,10 +30,15 @@ import org.cryptomator.presentation.util.ShareFileHelper import org.cryptomator.presentation.workflow.ActivityResult import org.cryptomator.presentation.workflow.PermissionsResult import org.cryptomator.util.ExceptionUtil -import timber.log.Timber -import java.io.* -import java.util.* +import java.io.File +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.util.ArrayList import javax.inject.Inject +import timber.log.Timber @PerView class ImagePreviewPresenter @Inject constructor( // diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/LicenseCheckPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/LicenseCheckPresenter.kt index 278a6dfb..d50d2bd8 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/LicenseCheckPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/LicenseCheckPresenter.kt @@ -7,8 +7,8 @@ import org.cryptomator.domain.usecases.NoOpResultHandler import org.cryptomator.presentation.exception.ExceptionHandlers import org.cryptomator.presentation.ui.activity.view.UpdateLicenseView import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import javax.inject.Inject +import timber.log.Timber class LicenseCheckPresenter @Inject internal constructor( exceptionHandlers: ExceptionHandlers, // @@ -32,6 +32,7 @@ class LicenseCheckPresenter @Inject internal constructor( } private inner class CheckLicenseStatusSubscriber : NoOpResultHandler() { + override fun onSuccess(licenseCheck: LicenseCheck) { super.onSuccess(licenseCheck) view?.closeDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/Presenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/Presenter.kt index da26d858..f2974613 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/Presenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/Presenter.kt @@ -22,14 +22,12 @@ import org.cryptomator.presentation.workflow.AsyncResult import org.cryptomator.presentation.workflow.PermissionsResult import org.cryptomator.presentation.workflow.Workflow import org.cryptomator.util.Supplier -import timber.log.Timber import java.io.Serializable -import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.HashMap -import kotlin.collections.HashSet +import java.util.Collections +import timber.log.Timber abstract class Presenter protected constructor(private val exceptionMappings: ExceptionHandlers) : ActivityHolder { + var isPaused = false private set private var refreshOnBackpressEnabled = Supplier { true } @@ -158,18 +156,21 @@ abstract class Presenter protected constructor(private val exceptionMa } open inner class DefaultResultHandler : NoOpResultHandler() { + override fun onError(e: Throwable) { showError(e) } } open inner class DefaultProgressAwareResultHandler : ProgressAwareResultHandler.NoOp() { + override fun onError(e: Throwable) { showError(e) } } open inner class ProgressCompletingResultHandler : DefaultResultHandler() { + override fun onFinished() { view?.showProgress(ProgressModel.COMPLETED) } @@ -322,6 +323,7 @@ abstract class Presenter protected constructor(private val exceptionMa } companion object { + const val SINGLE_RESULT = "singleResult" } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/SettingsPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/SettingsPresenter.kt index 18e824ef..3889b8f7 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/SettingsPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/SettingsPresenter.kt @@ -28,7 +28,6 @@ import org.cryptomator.presentation.util.FileUtil import org.cryptomator.presentation.workflow.PermissionsResult import org.cryptomator.util.Optional import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import java.io.File import java.io.FileInputStream import java.io.FileOutputStream @@ -36,6 +35,7 @@ import java.io.IOException import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream import javax.inject.Inject +import timber.log.Timber @PerView class SettingsPresenter @Inject internal constructor( @@ -72,7 +72,8 @@ class SettingsPresenter @Inject internal constructor( } "fdroid" -> { "F-Droid" - } else -> "Google Play" + } + else -> "Google Play" } return StringBuilder().append("## ").append(context().getString(R.string.error_report_subject)).append("\n\n") // .append("### ").append(context().getString(R.string.error_report_section_summary)).append('\n') // @@ -162,6 +163,7 @@ class SettingsPresenter @Inject internal constructor( } private inner class CreateErrorReportArchiveTask : AsyncTask() { + override fun doInBackground(vararg params: Void?): File? { return try { createErrorReportArchive() @@ -232,6 +234,7 @@ class SettingsPresenter @Inject internal constructor( } companion object { + private const val EOF = -1 } diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/SharedFilesPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/SharedFilesPresenter.kt index bbd737d6..7d2ee9e7 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/SharedFilesPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/SharedFilesPresenter.kt @@ -29,9 +29,9 @@ import org.cryptomator.presentation.workflow.PermissionsResult import org.cryptomator.util.Optional import org.cryptomator.util.SharedPreferencesHandler import org.cryptomator.util.file.FileCacheUtils -import timber.log.Timber import java.util.* import javax.inject.Inject +import timber.log.Timber @PerView class SharedFilesPresenter @Inject constructor( // diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/SplashPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/SplashPresenter.kt index ba6cfd0d..5f614bcc 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/SplashPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/SplashPresenter.kt @@ -8,6 +8,7 @@ import javax.inject.Inject @PerView class SplashPresenter @Inject constructor(exceptionMappings: ExceptionHandlers) : Presenter(exceptionMappings) { + override fun resumed() { Intents.vaultListIntent().startActivity(this) finish() diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/TextEditorPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/TextEditorPresenter.kt index 94d19f1f..c31aba85 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/TextEditorPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/TextEditorPresenter.kt @@ -26,6 +26,7 @@ class TextEditorPresenter @Inject constructor( // private val contentResolverUtil: ContentResolverUtil, // private val uploadFilesUseCase: UploadFilesUseCase, // exceptionMappings: ExceptionHandlers) : Presenter(exceptionMappings) { + private val textFile = AtomicReference() @JvmField diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/UriBasedDataSource.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/UriBasedDataSource.kt index a1354c6f..3015272a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/UriBasedDataSource.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/UriBasedDataSource.kt @@ -29,6 +29,7 @@ class UriBasedDataSource private constructor(private val uri: Uri) : DataSource } companion object { + @JvmStatic fun from(uri: Uri): UriBasedDataSource { return UriBasedDataSource(uri) diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt index 3da329f4..e3555a74 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/VaultListPresenter.kt @@ -18,27 +18,56 @@ import org.cryptomator.domain.exception.NetworkConnectionException import org.cryptomator.domain.exception.authentication.AuthenticationException import org.cryptomator.domain.exception.license.LicenseNotValidException import org.cryptomator.domain.exception.update.SSLHandshakePreAndroid5UpdateCheckException -import org.cryptomator.domain.usecases.* +import org.cryptomator.domain.usecases.DoLicenseCheckUseCase +import org.cryptomator.domain.usecases.DoUpdateCheckUseCase +import org.cryptomator.domain.usecases.DoUpdateUseCase +import org.cryptomator.domain.usecases.GetDecryptedCloudForVaultUseCase +import org.cryptomator.domain.usecases.LicenseCheck +import org.cryptomator.domain.usecases.NoOpResultHandler +import org.cryptomator.domain.usecases.UpdateCheck import org.cryptomator.domain.usecases.cloud.GetRootFolderUseCase -import org.cryptomator.domain.usecases.vault.* +import org.cryptomator.domain.usecases.vault.ChangePasswordUseCase +import org.cryptomator.domain.usecases.vault.DeleteVaultUseCase +import org.cryptomator.domain.usecases.vault.GetVaultListUseCase +import org.cryptomator.domain.usecases.vault.LockVaultUseCase +import org.cryptomator.domain.usecases.vault.MoveVaultPositionUseCase +import org.cryptomator.domain.usecases.vault.PrepareUnlockUseCase +import org.cryptomator.domain.usecases.vault.RemoveStoredVaultPasswordsUseCase +import org.cryptomator.domain.usecases.vault.RenameVaultUseCase +import org.cryptomator.domain.usecases.vault.SaveVaultUseCase +import org.cryptomator.domain.usecases.vault.UnlockToken +import org.cryptomator.domain.usecases.vault.UnlockVaultUseCase +import org.cryptomator.domain.usecases.vault.VaultOrUnlockToken import org.cryptomator.generator.Callback import org.cryptomator.presentation.BuildConfig import org.cryptomator.presentation.R import org.cryptomator.presentation.exception.ExceptionHandlers import org.cryptomator.presentation.intent.Intents -import org.cryptomator.presentation.model.* +import org.cryptomator.presentation.model.CloudModel +import org.cryptomator.presentation.model.CloudTypeModel +import org.cryptomator.presentation.model.ProgressModel +import org.cryptomator.presentation.model.ProgressStateModel +import org.cryptomator.presentation.model.VaultModel import org.cryptomator.presentation.model.mappers.CloudFolderModelMapper import org.cryptomator.presentation.service.AutoUploadService import org.cryptomator.presentation.ui.activity.LicenseCheckActivity import org.cryptomator.presentation.ui.activity.view.VaultListView -import org.cryptomator.presentation.ui.dialog.* +import org.cryptomator.presentation.ui.dialog.AppIsObscuredInfoDialog +import org.cryptomator.presentation.ui.dialog.AskForLockScreenDialog +import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppAvailableDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppDialog import org.cryptomator.presentation.util.FileUtil -import org.cryptomator.presentation.workflow.* +import org.cryptomator.presentation.workflow.ActivityResult +import org.cryptomator.presentation.workflow.AddExistingVaultWorkflow +import org.cryptomator.presentation.workflow.AuthenticationExceptionHandler +import org.cryptomator.presentation.workflow.CreateNewVaultWorkflow +import org.cryptomator.presentation.workflow.Workflow import org.cryptomator.util.Optional import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import java.io.Serializable import javax.inject.Inject +import timber.log.Timber @PerView class VaultListPresenter @Inject constructor( // @@ -65,6 +94,7 @@ class VaultListPresenter @Inject constructor( // private val cloudFolderModelMapper: CloudFolderModelMapper, // private val sharedPreferencesHandler: SharedPreferencesHandler, // exceptionMappings: ExceptionHandlers) : Presenter(exceptionMappings) { + private var vaultAction: VaultAction? = null private var changedVaultPassword = false private var startedUsingPrepareUnlock = false @@ -696,6 +726,7 @@ class VaultListPresenter @Inject constructor( // } companion object { + val NO_OP_PENDING_UNLOCK: PendingUnlock = object : PendingUnlock(null) { override fun continueIfComplete(presenter: VaultListPresenter) { // empty diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/WebDavAddOrChangePresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/WebDavAddOrChangePresenter.kt index 07e92b89..72165d8a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/WebDavAddOrChangePresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/WebDavAddOrChangePresenter.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.presenter import android.widget.Toast -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.cryptomator.domain.Cloud import org.cryptomator.domain.WebDavCloud import org.cryptomator.domain.di.PerView @@ -18,6 +17,7 @@ import org.cryptomator.presentation.workflow.ActivityResult import org.cryptomator.presentation.workflow.AuthenticationExceptionHandler import org.cryptomator.util.crypto.CredentialCryptor import javax.inject.Inject +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull @PerView class WebDavAddOrChangePresenter @Inject internal constructor( // diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt index 9d8abcfc..e2622e66 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt @@ -7,7 +7,9 @@ import android.app.PendingIntent import android.app.PendingIntent.FLAG_CANCEL_CURRENT import android.content.Context import android.content.Intent -import android.content.Intent.* +import android.content.Intent.ACTION_MAIN +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import androidx.core.app.NotificationCompat import org.cryptomator.presentation.R import org.cryptomator.presentation.service.AutoUploadService.cancelAutoUploadIntent @@ -17,6 +19,7 @@ import org.cryptomator.presentation.util.ResourceHelper.Companion.getString import java.lang.String.format class AutoUploadNotification(private val context: Context, private val amountOfPictures: Int) { + private val builder: NotificationCompat.Builder private var notificationManager: NotificationManager? = null private var alreadyUploadedPictures = 0 @@ -122,6 +125,7 @@ class AutoUploadNotification(private val context: Context, private val amountOfP } companion object { + private const val NOTIFICATION_ID = 94874 private const val NOTIFICATION_CHANNEL_ID = "65478" private const val NOTIFICATION_CHANNEL_NAME = "Cryptomator" diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java index df8d3151..716023aa 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java +++ b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadService.java @@ -1,15 +1,14 @@ package org.cryptomator.presentation.service; -import static java.lang.String.format; -import static org.cryptomator.domain.usecases.cloud.UploadFile.anUploadFile; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import androidx.annotation.Nullable; import org.cryptomator.domain.Cloud; import org.cryptomator.domain.CloudFile; @@ -34,24 +33,42 @@ import org.cryptomator.presentation.util.FileUtil; import org.cryptomator.util.Optional; import org.cryptomator.util.SharedPreferencesHandler; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; - -import androidx.annotation.Nullable; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import timber.log.Timber; +import static java.lang.String.format; +import static org.cryptomator.domain.usecases.cloud.UploadFile.anUploadFile; + public class AutoUploadService extends Service { private static final String ACTION_CANCEL_AUTO_UPLOAD = "CANCEL_AUTO_UPLOAD"; private static final String ACTION_START_AUTO_UPLOAD = "START_AUTO_UPLOAD"; private static Cloud cloud; + private AutoUploadNotification notification; + private CloudContentRepository cloudContentRepository; + private ContentResolverUtil contentResolverUtil; + private FileUtil fileUtil; + private List uploadFiles; + private CloudFolder parent; + private Context context; + private long startTimeAutoUploadNotificationDelay; + private long elapsedTimeAutoUploadNotificationDelay = 0L; + private Thread worker; + private volatile boolean cancelled; + private final Flag cancelledFlag = new Flag() { + @Override + public boolean get() { + return cancelled; + } + }; public static Intent cancelAutoUploadIntent(Context context) { Intent cancelAutoUploadIntent = new Intent(context, AutoUploadService.class); @@ -66,28 +83,6 @@ public class AutoUploadService extends Service { return startAutoUpload; } - private AutoUploadNotification notification; - - private CloudContentRepository cloudContentRepository; - private ContentResolverUtil contentResolverUtil; - private FileUtil fileUtil; - private List uploadFiles; - private CloudFolder parent; - private Context context; - - private long startTimeAutoUploadNotificationDelay; - private long elapsedTimeAutoUploadNotificationDelay = 0L; - - private Thread worker; - - private volatile boolean cancelled; - private final Flag cancelledFlag = new Flag() { - @Override - public boolean get() { - return cancelled; - } - }; - private void startBackgroundImageUpload(Cloud cloud) { try { uploadFiles = getUploadFiles(fileUtil.getAutoUploadFilesStore()); @@ -144,8 +139,9 @@ public class AutoUploadService extends Service { startTimeAutoUploadNotificationDelay = System.currentTimeMillis(); elapsedTimeAutoUploadNotificationDelay = 0; }); - } else + } else { elapsedTimeAutoUploadNotificationDelay = new Date().getTime() - startTimeAutoUploadNotificationDelay; + } } private ArrayList getUploadFiles(AutoUploadFilesStore autoUploadFilesStore) { @@ -272,6 +268,12 @@ public class AutoUploadService extends Service { return new Binder(); } + private void hideNotification() { + if (notification != null) { + notification.hide(); + } + } + public class Binder extends android.os.Binder { Binder() { @@ -284,10 +286,4 @@ public class AutoUploadService extends Service { context = myContext; } } - - private void hideNotification() { - if (notification != null) { - notification.hide(); - } - } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/CryptorsService.java b/presentation/src/main/java/org/cryptomator/presentation/service/CryptorsService.java index 6d3951e5..5b70c905 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/CryptorsService.java +++ b/presentation/src/main/java/org/cryptomator/presentation/service/CryptorsService.java @@ -1,15 +1,5 @@ package org.cryptomator.presentation.service; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.cryptomator.data.cloud.crypto.Cryptors; -import org.cryptomator.presentation.util.FileUtil; -import org.cryptomator.util.Consumer; -import org.cryptomator.util.LockTimeout; -import org.cryptomator.util.SharedPreferencesHandler; - import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; @@ -19,30 +9,30 @@ import android.os.IBinder; import androidx.annotation.Nullable; +import org.cryptomator.data.cloud.crypto.Cryptors; +import org.cryptomator.presentation.util.FileUtil; +import org.cryptomator.util.Consumer; +import org.cryptomator.util.LockTimeout; +import org.cryptomator.util.SharedPreferencesHandler; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import timber.log.Timber; public class CryptorsService extends Service { private static final String ACTION_LOCK_ALL = "CRYPTOMATOR_LOCK_ALL"; - - public static Intent lockAllIntent(Context context) { - Intent lockAllIntent = new Intent(context, CryptorsService.class); - lockAllIntent.setAction(ACTION_LOCK_ALL); - return lockAllIntent; - } - private final Cryptors.Default cryptors = new Cryptors.Default(); - private SharedPreferencesHandler sharedPreferencesHandler; - private UnlockedNotification notification; private final AutolockTimeout autolockTimeout = new AutolockTimeout(); - private volatile boolean running = true; - private volatile boolean lockSuspended = false; - private BroadcastReceiver screenLockReceiver; - private FileUtil fileUtil; - private final Lock unlockedLock = new ReentrantLock(); private final Condition vaultsUnlockedAndInBackground = unlockedLock.newCondition(); - + private SharedPreferencesHandler sharedPreferencesHandler; + private UnlockedNotification notification; + private final Consumer onLockTimeoutChanged = this::onLockTimeoutChanged; + private volatile boolean running = true; + private volatile boolean lockSuspended = false; private final Thread worker = new Thread(new Runnable() { @Override public void run() { @@ -64,6 +54,14 @@ public class CryptorsService extends Service { } } }); + private BroadcastReceiver screenLockReceiver; + private FileUtil fileUtil; + + public static Intent lockAllIntent(Context context) { + Intent lockAllIntent = new Intent(context, CryptorsService.class); + lockAllIntent.setAction(ACTION_LOCK_ALL); + return lockAllIntent; + } private void waitUntilVaultsUnlockedAndInBackground() throws InterruptedException { unlockedLock.lock(); @@ -158,14 +156,22 @@ public class CryptorsService extends Service { notification.update(); } - private final Consumer onLockTimeoutChanged = this::onLockTimeoutChanged; - @Nullable @Override public IBinder onBind(Intent intent) { return new Binder(); } + private void stopCryptorsService() { + Intent myService = new Intent(CryptorsService.this, CryptorsService.class); + stopService(myService); + } + + private void destroyCryptorsAndHideNotification() { + cryptors.destroyAll(); + notification.hide(); + } + public class Binder extends android.os.Binder { Binder() { @@ -194,6 +200,7 @@ public class CryptorsService extends Service { } class ScreenLockReceiver extends BroadcastReceiver { + @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF) && // @@ -207,14 +214,4 @@ public class CryptorsService extends Service { } } } - - private void stopCryptorsService() { - Intent myService = new Intent(CryptorsService.this, CryptorsService.class); - stopService(myService); - } - - private void destroyCryptorsAndHideNotification() { - cryptors.destroyAll(); - notification.hide(); - } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt b/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt index ad414e27..644a4ab6 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt @@ -65,6 +65,7 @@ class OpenWritableFileNotification(private val context: Context, private val uri } companion object { + private const val NOTIFICATION_ID = 94875 private const val NOTIFICATION_CHANNEL_ID = "65478" private const val NOTIFICATION_CHANNEL_NAME = "Cryptomator" diff --git a/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java b/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java index 5b50e415..52c53c92 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java +++ b/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java @@ -33,9 +33,8 @@ class UnlockedNotification { private final Service service; private final NotificationCompat.Builder builder; - - private int unlocked = 0; private final AutolockTimeout autolockTimeout; + private int unlocked = 0; public UnlockedNotification(Service service, AutolockTimeout autolockTimeout) { this.service = service; diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/AutoUploadChooseVaultActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/AutoUploadChooseVaultActivity.kt index c8a25f49..d4c54335 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/AutoUploadChooseVaultActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/AutoUploadChooseVaultActivity.kt @@ -3,7 +3,6 @@ package org.cryptomator.presentation.ui.activity import android.os.Build import androidx.annotation.RequiresApi import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFolderModel @@ -16,6 +15,7 @@ import org.cryptomator.presentation.ui.dialog.NotEnoughVaultsDialog import org.cryptomator.presentation.ui.fragment.AutoUploadChooseVaultFragment import org.cryptomator.presentation.util.BiometricAuthentication import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class AutoUploadChooseVaultActivity : BaseActivity(), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BaseActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BaseActivity.kt index 19db7276..88448bf1 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BaseActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BaseActivity.kt @@ -32,10 +32,10 @@ import org.cryptomator.presentation.ui.activity.view.View import org.cryptomator.presentation.ui.dialog.GenericProgressDialog import org.cryptomator.presentation.ui.snackbar.SnackbarAction import org.cryptomator.util.SharedPreferencesHandler -import timber.log.Timber import java.lang.String.format import javax.inject.Inject import kotlin.reflect.KClass +import timber.log.Timber abstract class BaseActivity : AppCompatActivity(), View, ActivityCompat.OnRequestPermissionsResultCallback, HasComponent { @@ -384,6 +384,7 @@ abstract class BaseActivity : AppCompatActivity(), View, ActivityCompat.OnReques } companion object { + const val NO_MENU = -1 private const val ACTIVE_DIALOG = "activeDialog" } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BiometricAuthSettingsActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BiometricAuthSettingsActivity.kt index 928bd8e9..a4de1005 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BiometricAuthSettingsActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BiometricAuthSettingsActivity.kt @@ -4,7 +4,6 @@ import android.os.Build import androidx.annotation.RequiresApi import androidx.biometric.BiometricManager import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.domain.Vault import org.cryptomator.generator.Activity import org.cryptomator.presentation.R @@ -17,6 +16,7 @@ import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog import org.cryptomator.presentation.ui.fragment.BiometricAuthSettingsFragment import org.cryptomator.presentation.util.BiometricAuthentication import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class BiometricAuthSettingsActivity : BaseActivity(), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BrowseFilesActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BrowseFilesActivity.kt index 32550388..210cb3c6 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BrowseFilesActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/BrowseFilesActivity.kt @@ -7,20 +7,26 @@ import android.view.View import androidx.appcompat.widget.SearchView import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.domain.CloudNode import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent import org.cryptomator.presentation.R import org.cryptomator.presentation.intent.BrowseFilesIntent import org.cryptomator.presentation.intent.ChooseCloudNodeSettings -import org.cryptomator.presentation.intent.ChooseCloudNodeSettings.NavigationMode.* +import org.cryptomator.presentation.intent.ChooseCloudNodeSettings.NavigationMode.BROWSE_FILES +import org.cryptomator.presentation.intent.ChooseCloudNodeSettings.NavigationMode.MOVE_CLOUD_NODE +import org.cryptomator.presentation.intent.ChooseCloudNodeSettings.NavigationMode.SELECT_ITEMS import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel import org.cryptomator.presentation.model.ProgressModel import org.cryptomator.presentation.model.ProgressModel.Companion.COMPLETED -import org.cryptomator.presentation.model.comparator.* +import org.cryptomator.presentation.model.comparator.CloudNodeModelDateNewestFirstComparator +import org.cryptomator.presentation.model.comparator.CloudNodeModelDateOldestFirstComparator +import org.cryptomator.presentation.model.comparator.CloudNodeModelNameAZComparator +import org.cryptomator.presentation.model.comparator.CloudNodeModelNameZAComparator +import org.cryptomator.presentation.model.comparator.CloudNodeModelSizeBiggestFirstComparator +import org.cryptomator.presentation.model.comparator.CloudNodeModelSizeSmallestFirstComparator import org.cryptomator.presentation.presenter.BrowseFilesPresenter import org.cryptomator.presentation.presenter.BrowseFilesPresenter.Companion.OPEN_FILE_FINISHED import org.cryptomator.presentation.ui.activity.view.BrowseFilesView @@ -28,11 +34,22 @@ import org.cryptomator.presentation.ui.bottomsheet.FileSettingsBottomSheet import org.cryptomator.presentation.ui.bottomsheet.FolderSettingsBottomSheet import org.cryptomator.presentation.ui.bottomsheet.VaultContentActionBottomSheet import org.cryptomator.presentation.ui.callback.BrowseFilesCallback -import org.cryptomator.presentation.ui.dialog.* +import org.cryptomator.presentation.ui.dialog.CloudNodeRenameDialog +import org.cryptomator.presentation.ui.dialog.ConfirmDeleteCloudNodeDialog +import org.cryptomator.presentation.ui.dialog.CreateFolderDialog +import org.cryptomator.presentation.ui.dialog.ExportCloudFilesDialog +import org.cryptomator.presentation.ui.dialog.FileNameDialog +import org.cryptomator.presentation.ui.dialog.FileTypeNotSupportedDialog +import org.cryptomator.presentation.ui.dialog.NoDirFileDialog +import org.cryptomator.presentation.ui.dialog.ReplaceDialog +import org.cryptomator.presentation.ui.dialog.SymLinkDialog +import org.cryptomator.presentation.ui.dialog.UploadCloudFileDialog import org.cryptomator.presentation.ui.fragment.BrowseFilesFragment -import java.util.* +import java.util.ArrayList +import java.util.Locale import java.util.regex.Pattern import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class BrowseFilesActivity : BaseActivity(), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ChooseCloudServiceActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ChooseCloudServiceActivity.kt index 1ef30889..f9d0caf9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ChooseCloudServiceActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ChooseCloudServiceActivity.kt @@ -2,7 +2,6 @@ package org.cryptomator.presentation.ui.activity import android.view.MenuItem import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent import org.cryptomator.presentation.R @@ -13,6 +12,7 @@ import org.cryptomator.presentation.presenter.ChooseCloudServicePresenter import org.cryptomator.presentation.ui.activity.view.ChooseCloudServiceView import org.cryptomator.presentation.ui.fragment.ChooseCloudServiceFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class ChooseCloudServiceActivity : BaseActivity(), ChooseCloudServiceView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudConnectionListActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudConnectionListActivity.kt index 432a7baf..a4281b4d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudConnectionListActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudConnectionListActivity.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.ui.activity import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.domain.Vault import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent @@ -13,8 +12,9 @@ import org.cryptomator.presentation.ui.activity.view.CloudConnectionListView import org.cryptomator.presentation.ui.bottomsheet.CloudConnectionSettingsBottomSheet import org.cryptomator.presentation.ui.dialog.DeleteCloudConnectionWithVaultsDialog import org.cryptomator.presentation.ui.fragment.CloudConnectionListFragment -import java.util.* +import java.util.ArrayList import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class CloudConnectionListActivity : BaseActivity(), diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudSettingsActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudSettingsActivity.kt index 311966a2..f572bc5d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudSettingsActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CloudSettingsActivity.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.ui.activity import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel @@ -9,6 +8,7 @@ import org.cryptomator.presentation.presenter.CloudSettingsPresenter import org.cryptomator.presentation.ui.activity.view.CloudSettingsView import org.cryptomator.presentation.ui.fragment.CloudSettingsFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class CloudSettingsActivity : BaseActivity(), CloudSettingsView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CreateVaultActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CreateVaultActivity.kt index d4c46164..2a194ac2 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CreateVaultActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/CreateVaultActivity.kt @@ -1,13 +1,14 @@ package org.cryptomator.presentation.ui.activity import android.view.inputmethod.EditorInfo -import kotlinx.android.synthetic.main.content_create_vault.* -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.presenter.CreateVaultPresenter import org.cryptomator.presentation.ui.activity.view.CreateVaultView import javax.inject.Inject +import kotlinx.android.synthetic.main.content_create_vault.createVaultButton +import kotlinx.android.synthetic.main.content_create_vault.vaultNameEditText +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity(layout = R.layout.activity_create_vault) class CreateVaultActivity : BaseActivity(), CreateVaultView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/EmptyDirIdFileInfoActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/EmptyDirIdFileInfoActivity.kt index 5217c478..3ef741f0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/EmptyDirIdFileInfoActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/EmptyDirIdFileInfoActivity.kt @@ -1,6 +1,5 @@ package org.cryptomator.presentation.ui.activity -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent import org.cryptomator.presentation.R @@ -9,6 +8,7 @@ import org.cryptomator.presentation.presenter.EmptyDirIdFileInfoPresenter import org.cryptomator.presentation.ui.activity.view.EmptyDirFileView import org.cryptomator.presentation.ui.fragment.EmptyDirIdFileInfoFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity(layout = R.layout.activity_empty_dir_file_info) class EmptyDirIdFileInfoActivity : BaseActivity(), EmptyDirFileView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ImagePreviewActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ImagePreviewActivity.kt index 5d70f3b1..7834f891 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ImagePreviewActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/ImagePreviewActivity.kt @@ -1,14 +1,18 @@ package org.cryptomator.presentation.ui.activity import android.net.Uri -import android.view.View.* +import android.view.View.GONE +import android.view.View.SYSTEM_UI_FLAG_FULLSCREEN +import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION +import android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY +import android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION +import android.view.View.VISIBLE import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentStatePagerAdapter import androidx.viewpager.widget.PagerAdapter import androidx.viewpager.widget.ViewPager -import kotlinx.android.synthetic.main.activity_image_preview.* import org.cryptomator.domain.exception.FatalBackendException import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent @@ -22,6 +26,12 @@ import org.cryptomator.presentation.ui.dialog.ConfirmDeleteCloudNodeDialog import org.cryptomator.presentation.ui.fragment.ImagePreviewFragment import org.cryptomator.util.Optional import javax.inject.Inject +import kotlinx.android.synthetic.main.activity_image_preview.controlView +import kotlinx.android.synthetic.main.activity_image_preview.deleteImage +import kotlinx.android.synthetic.main.activity_image_preview.exportImage +import kotlinx.android.synthetic.main.activity_image_preview.shareImage +import kotlinx.android.synthetic.main.activity_image_preview.toolbar +import kotlinx.android.synthetic.main.activity_image_preview.viewPager @Activity(layout = R.layout.activity_image_preview) class ImagePreviewActivity : BaseActivity(), ImagePreviewView, ConfirmDeleteCloudNodeDialog.Callback { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicenseCheckActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicenseCheckActivity.kt index a2e03e2e..6598d667 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicenseCheckActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicenseCheckActivity.kt @@ -3,7 +3,6 @@ package org.cryptomator.presentation.ui.activity import android.content.Intent import android.net.Uri import android.os.Bundle -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.intent.Intents.vaultListIntent @@ -11,9 +10,10 @@ import org.cryptomator.presentation.presenter.LicenseCheckPresenter import org.cryptomator.presentation.ui.activity.view.UpdateLicenseView import org.cryptomator.presentation.ui.dialog.LicenseConfirmationDialog import org.cryptomator.presentation.ui.dialog.UpdateLicenseDialog -import java.util.* +import java.util.Locale import javax.inject.Inject import kotlin.system.exitProcess +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class LicenseCheckActivity : BaseActivity(), UpdateLicenseDialog.Callback, LicenseConfirmationDialog.Callback, UpdateLicenseView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicensesActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicensesActivity.kt index 8e753b09..970ef25c 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicensesActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/LicensesActivity.kt @@ -1,8 +1,8 @@ package org.cryptomator.presentation.ui.activity -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity(layout = R.layout.activity_licenses) class LicensesActivity : BaseActivity() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SetPasswordActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SetPasswordActivity.kt index 66a8af5f..c684b6fd 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SetPasswordActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SetPasswordActivity.kt @@ -1,13 +1,13 @@ package org.cryptomator.presentation.ui.activity import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.presenter.SetPasswordPresenter import org.cryptomator.presentation.ui.activity.view.SetPasswordView import org.cryptomator.presentation.ui.fragment.SetPasswordFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class SetPasswordActivity : BaseActivity(), SetPasswordView { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SettingsActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SettingsActivity.kt index 3fbf28e4..375c5a62 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SettingsActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SettingsActivity.kt @@ -3,15 +3,19 @@ package org.cryptomator.presentation.ui.activity import android.content.Intent import android.net.Uri import android.view.View -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.model.ProgressModel import org.cryptomator.presentation.presenter.SettingsPresenter import org.cryptomator.presentation.ui.activity.view.SettingsView -import org.cryptomator.presentation.ui.dialog.* +import org.cryptomator.presentation.ui.dialog.DebugModeDisclaimerDialog +import org.cryptomator.presentation.ui.dialog.DisableAppWhenObscuredDisclaimerDialog +import org.cryptomator.presentation.ui.dialog.DisableSecureScreenDisclaimerDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppAvailableDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppDialog import org.cryptomator.presentation.ui.fragment.SettingsFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity(layout = R.layout.activity_settings) class SettingsActivity : BaseActivity(), diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SharedFilesActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SharedFilesActivity.kt index d77d4747..d83c0f75 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SharedFilesActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/SharedFilesActivity.kt @@ -8,7 +8,6 @@ import android.net.Uri import android.os.Build import androidx.annotation.RequiresApi import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFolderModel @@ -17,13 +16,18 @@ import org.cryptomator.presentation.model.SharedFileModel import org.cryptomator.presentation.model.VaultModel import org.cryptomator.presentation.presenter.SharedFilesPresenter import org.cryptomator.presentation.ui.activity.view.SharedFilesView -import org.cryptomator.presentation.ui.dialog.* +import org.cryptomator.presentation.ui.dialog.BiometricAuthKeyInvalidatedDialog +import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog +import org.cryptomator.presentation.ui.dialog.NotEnoughVaultsDialog +import org.cryptomator.presentation.ui.dialog.ReplaceDialog +import org.cryptomator.presentation.ui.dialog.UploadCloudFileDialog import org.cryptomator.presentation.ui.fragment.SharedFilesFragment import org.cryptomator.presentation.util.BiometricAuthentication -import timber.log.Timber import java.lang.String.format -import java.util.* +import java.util.ArrayList import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar +import timber.log.Timber @Activity class SharedFilesActivity : BaseActivity(), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/TextEditorActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/TextEditorActivity.kt index cf74574a..837a6d05 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/TextEditorActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/TextEditorActivity.kt @@ -4,7 +4,6 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.widget.SearchView import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent import org.cryptomator.presentation.R @@ -14,6 +13,7 @@ import org.cryptomator.presentation.ui.activity.view.TextEditorView import org.cryptomator.presentation.ui.dialog.UnsavedChangesDialog import org.cryptomator.presentation.ui.fragment.TextEditorFragment import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class TextEditorActivity : BaseActivity(), diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/VaultListActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/VaultListActivity.kt index b3784a71..c78e153b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/VaultListActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/VaultListActivity.kt @@ -6,8 +6,6 @@ import android.os.Build import android.view.View import androidx.annotation.RequiresApi import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.activity_layout_obscure_aware.* -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.domain.Vault import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent @@ -25,12 +23,23 @@ import org.cryptomator.presentation.ui.activity.view.VaultListView import org.cryptomator.presentation.ui.bottomsheet.AddVaultBottomSheet import org.cryptomator.presentation.ui.bottomsheet.SettingsVaultBottomSheet import org.cryptomator.presentation.ui.callback.VaultListCallback -import org.cryptomator.presentation.ui.dialog.* +import org.cryptomator.presentation.ui.dialog.AskForLockScreenDialog +import org.cryptomator.presentation.ui.dialog.BetaConfirmationDialog +import org.cryptomator.presentation.ui.dialog.BiometricAuthKeyInvalidatedDialog +import org.cryptomator.presentation.ui.dialog.ChangePasswordDialog +import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppAvailableDialog +import org.cryptomator.presentation.ui.dialog.UpdateAppDialog +import org.cryptomator.presentation.ui.dialog.VaultDeleteConfirmationDialog +import org.cryptomator.presentation.ui.dialog.VaultNotFoundDialog +import org.cryptomator.presentation.ui.dialog.VaultRenameDialog import org.cryptomator.presentation.ui.fragment.VaultListFragment import org.cryptomator.presentation.ui.layout.ObscuredAwareCoordinatorLayout.Listener import org.cryptomator.presentation.util.BiometricAuthentication -import java.util.* +import java.util.Locale import javax.inject.Inject +import kotlinx.android.synthetic.main.activity_layout_obscure_aware.activityRootView +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity(layout = R.layout.activity_layout_obscure_aware) class VaultListActivity : BaseActivity(), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/WebDavAddOrChangeActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/WebDavAddOrChangeActivity.kt index 15715be8..db1ae167 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/WebDavAddOrChangeActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/WebDavAddOrChangeActivity.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.ui.activity import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.toolbar_layout.* import org.cryptomator.domain.exception.FatalBackendException import org.cryptomator.generator.Activity import org.cryptomator.generator.InjectIntent @@ -14,6 +13,7 @@ import org.cryptomator.presentation.ui.fragment.WebDavAddOrChangeFragment import java.net.URI import java.net.URISyntaxException import javax.inject.Inject +import kotlinx.android.synthetic.main.toolbar_layout.toolbar @Activity class WebDavAddOrChangeActivity : BaseActivity(), diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/CloudConnectionListView.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/CloudConnectionListView.kt index b94912e9..e18f5da0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/CloudConnectionListView.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/CloudConnectionListView.kt @@ -2,7 +2,7 @@ package org.cryptomator.presentation.ui.activity.view import org.cryptomator.domain.Vault import org.cryptomator.presentation.model.CloudModel -import java.util.* +import java.util.ArrayList interface CloudConnectionListView : View { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/BiometricAuthSettingsAdapter.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/BiometricAuthSettingsAdapter.kt index e1e2bfef..2b45f0c1 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/BiometricAuthSettingsAdapter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/BiometricAuthSettingsAdapter.kt @@ -2,11 +2,13 @@ package org.cryptomator.presentation.ui.adapter import android.view.View import com.google.android.material.switchmaterial.SwitchMaterial -import kotlinx.android.synthetic.main.item_biometric_auth_vault.view.* import org.cryptomator.presentation.R import org.cryptomator.presentation.model.VaultModel import org.cryptomator.presentation.ui.adapter.BiometricAuthSettingsAdapter.BiometricAuthSettingsViewHolder import javax.inject.Inject +import kotlinx.android.synthetic.main.item_biometric_auth_vault.view.cloud +import kotlinx.android.synthetic.main.item_biometric_auth_vault.view.toggleBiometricAuth +import kotlinx.android.synthetic.main.item_biometric_auth_vault.view.vaultName class BiometricAuthSettingsAdapter // @Inject @@ -15,6 +17,7 @@ constructor() : RecyclerViewBaseAdapter(CloudModelComparator(context)) { interface Callback { + fun onCloudConnectionClicked(cloudModel: CloudModel) fun onCloudSettingsClicked(cloudModel: CloudModel) diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudSettingsAdapter.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudSettingsAdapter.kt index 5a22acbd..33417210 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudSettingsAdapter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudSettingsAdapter.kt @@ -2,17 +2,18 @@ package org.cryptomator.presentation.ui.adapter import android.content.Context import android.view.View -import kotlinx.android.synthetic.main.item_cloud_setting.view.* import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel import org.cryptomator.presentation.model.CloudTypeModel import org.cryptomator.presentation.ui.adapter.CloudSettingsAdapter.CloudSettingViewHolder import javax.inject.Inject +import kotlinx.android.synthetic.main.item_cloud_setting.view.* class CloudSettingsAdapter @Inject constructor(private val context: Context) : RecyclerViewBaseAdapter() { interface OnItemClickListener { + fun onCloudClicked(cloudModel: CloudModel) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudsAdapter.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudsAdapter.kt index 9d1cf790..af9d6162 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudsAdapter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/CloudsAdapter.kt @@ -1,16 +1,18 @@ package org.cryptomator.presentation.ui.adapter import android.view.View -import kotlinx.android.synthetic.main.item_cloud.view.* import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudTypeModel import org.cryptomator.presentation.ui.adapter.CloudsAdapter.CloudViewHolder import javax.inject.Inject +import kotlinx.android.synthetic.main.item_cloud.view.cloud +import kotlinx.android.synthetic.main.item_cloud.view.cloudName class CloudsAdapter @Inject constructor() : RecyclerViewBaseAdapter() { interface OnItemClickListener { + fun onCloudClicked(cloudTypeModel: CloudTypeModel) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/RecyclerViewBaseAdapter.java b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/RecyclerViewBaseAdapter.java index 529b02a0..3d94339f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/RecyclerViewBaseAdapter.java +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/RecyclerViewBaseAdapter.java @@ -4,15 +4,15 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - public abstract class RecyclerViewBaseAdapter extends RecyclerView.Adapter { final List itemCollection; @@ -117,15 +117,6 @@ public abstract class RecyclerViewBaseAdapter getComparator() { return comparator; } + + public abstract class ItemViewHolder extends RecyclerView.ViewHolder { + + ItemViewHolder(View itemView) { + super(itemView); + } + + public abstract void bind(int position); + } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedFilesAdapter.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedFilesAdapter.kt index 8bd9125c..fd5133be 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedFilesAdapter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedFilesAdapter.kt @@ -3,20 +3,22 @@ package org.cryptomator.presentation.ui.adapter import android.text.Editable import android.text.TextWatcher import android.view.View -import kotlinx.android.synthetic.main.item_shared_files.view.* import org.cryptomator.presentation.R import org.cryptomator.presentation.model.SharedFileModel import org.cryptomator.presentation.ui.adapter.SharedFilesAdapter.FileViewHolder import org.cryptomator.presentation.util.FileIcon import org.cryptomator.presentation.util.FileUtil import org.cryptomator.util.Comparators -import java.util.* +import java.util.HashSet import javax.inject.Inject +import kotlinx.android.synthetic.main.item_shared_files.view.fileImage +import kotlinx.android.synthetic.main.item_shared_files.view.fileName class SharedFilesAdapter @Inject constructor(private val fileUtil: FileUtil) : RecyclerViewBaseAdapter(Comparators.naturalOrder()) { interface Callback { + fun onFileNameConflict(hasFileNameConflict: Boolean) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedLocationsAdapter.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedLocationsAdapter.kt index 6ec8b950..4b8403dc 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedLocationsAdapter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/SharedLocationsAdapter.kt @@ -1,11 +1,15 @@ package org.cryptomator.presentation.ui.adapter import android.view.View -import kotlinx.android.synthetic.main.item_shareable_location.view.* import org.cryptomator.presentation.R import org.cryptomator.presentation.model.VaultModel import org.cryptomator.presentation.ui.adapter.SharedLocationsAdapter.VaultViewHolder import javax.inject.Inject +import kotlinx.android.synthetic.main.item_shareable_location.view.chooseFolderLocation +import kotlinx.android.synthetic.main.item_shareable_location.view.chosenLocation +import kotlinx.android.synthetic.main.item_shareable_location.view.cloudImage +import kotlinx.android.synthetic.main.item_shareable_location.view.selectedVault +import kotlinx.android.synthetic.main.item_shareable_location.view.vaultName class SharedLocationsAdapter @Inject constructor() : RecyclerViewBaseAdapter() { @@ -14,6 +18,7 @@ constructor() : RecyclerViewBaseAdapter(VaultModelComparator()), VaultsMoveListener.Listener { + interface OnItemInteractionListener { + fun onVaultClicked(vaultModel: VaultModel) fun onVaultSettingsClicked(vaultModel: VaultModel) @@ -78,6 +84,7 @@ internal constructor() : RecyclerViewBaseAdapter { + override fun compare(o1: VaultModel, o2: VaultModel): Int { return o1.position - o2.position } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/VaultsMoveListener.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/VaultsMoveListener.kt index 6c0ee760..65fce429 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/VaultsMoveListener.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/adapter/VaultsMoveListener.kt @@ -51,6 +51,7 @@ class VaultsMoveListener(val adapter: VaultsAdapter) : ItemTouchHelper.Callback( } interface Listener { + fun onRowMoved(fromPosition: Int, toPosition: Int) fun onVaultMoved(fromPosition: Int, toPosition: Int) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/AddVaultBottomSheet.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/AddVaultBottomSheet.kt index 2e708f80..62c7ef0b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/AddVaultBottomSheet.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/AddVaultBottomSheet.kt @@ -1,13 +1,16 @@ package org.cryptomator.presentation.ui.bottomsheet -import kotlinx.android.synthetic.main.dialog_bottom_sheet_add_vault.* import org.cryptomator.generator.BottomSheet import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_bottom_sheet_add_vault.add_existing_vault +import kotlinx.android.synthetic.main.dialog_bottom_sheet_add_vault.create_new_vault +import kotlinx.android.synthetic.main.dialog_bottom_sheet_add_vault.title @BottomSheet(R.layout.dialog_bottom_sheet_add_vault) class AddVaultBottomSheet : BaseBottomSheet() { interface Callback { + fun onCreateVault() fun onAddExistingVault() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/CloudConnectionSettingsBottomSheet.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/CloudConnectionSettingsBottomSheet.kt index 8eb8a2b8..363948b8 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/CloudConnectionSettingsBottomSheet.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/bottomsheet/CloudConnectionSettingsBottomSheet.kt @@ -2,18 +2,23 @@ package org.cryptomator.presentation.ui.bottomsheet import android.os.Bundle import android.view.View -import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.* import org.cryptomator.generator.BottomSheet import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel import org.cryptomator.presentation.model.CloudTypeModel import org.cryptomator.presentation.model.LocalStorageModel import org.cryptomator.presentation.model.WebDavCloudModel +import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.change_cloud +import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.delete_cloud +import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.iv_cloud_image +import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.tv_cloud_name +import kotlinx.android.synthetic.main.dialog_bottom_sheet_cloud_settings.tv_cloud_subtext @BottomSheet(R.layout.dialog_bottom_sheet_cloud_settings) class CloudConnectionSettingsBottomSheet : BaseBottomSheet() { interface Callback { + fun onChangeCloudClicked(cloudModel: CloudModel) fun onDeleteCloudClicked(cloudModel: CloudModel) } @@ -55,6 +60,7 @@ class CloudConnectionSettingsBottomSheet : BaseBottomSheet() { interface Callback { + fun onExportFileClicked(cloudFile: CloudFileModel) fun onRenameFileClicked(cloudFile: CloudFileModel) fun onDeleteNodeClicked(cloudFile: CloudNodeModel<*>) @@ -61,6 +70,7 @@ class FileSettingsBottomSheet : BaseBottomSheet() { interface Callback { + fun onShareFolderClicked(cloudFolderModel: CloudFolderModel) fun onRenameFolderClicked(cloudFolderModel: CloudFolderModel) fun onDeleteNodeClicked(cloudFolderModel: CloudNodeModel<*>) @@ -53,6 +60,7 @@ class FolderSettingsBottomSheet : BaseBottomSheet() { interface Callback { + fun onDeleteVaultClick(vaultModel: VaultModel) fun onRenameVaultClick(vaultModel: VaultModel) fun onLockVaultClick(vaultModel: VaultModel) @@ -47,6 +54,7 @@ class SettingsVaultBottomSheet : BaseBottomSheet() { interface Callback { + fun onCreateNewFolderClicked() fun onUploadFilesClicked(folder: CloudFolderModel) fun onCreateNewTextFileClicked() @@ -44,6 +48,7 @@ class VaultContentActionBottomSheet : BaseBottomSheet() { @@ -28,6 +28,7 @@ class AppIsObscuredInfoDialog : BaseDialog() { } companion object { + fun newInstance(): DialogFragment { return AppIsObscuredInfoDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AskForLockScreenDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AskForLockScreenDialog.kt index 625e895c..6ff1fb0a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AskForLockScreenDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AskForLockScreenDialog.kt @@ -3,14 +3,15 @@ package org.cryptomator.presentation.ui.dialog import android.content.DialogInterface import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_no_screen_lock_set.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_no_screen_lock_set.cb_select_screen_lock @Dialog(R.layout.dialog_no_screen_lock_set) class AskForLockScreenDialog : BaseDialog() { interface Callback { + fun onAskForLockScreenFinished(setScreenLock: Boolean) } @@ -26,6 +27,7 @@ class AskForLockScreenDialog : BaseDialog() { } companion object { + fun newInstance(): DialogFragment { return AskForLockScreenDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AssignSslCertificateDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AssignSslCertificateDialog.kt index e781375c..f6699b00 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AssignSslCertificateDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/AssignSslCertificateDialog.kt @@ -4,7 +4,6 @@ import android.content.DialogInterface import android.os.Bundle import android.view.View import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_handle_ssl_certificate.* import org.cryptomator.data.util.X509CertificateHelper import org.cryptomator.domain.WebDavCloud import org.cryptomator.domain.exception.FatalBackendException @@ -12,6 +11,10 @@ import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import java.security.cert.CertificateException import java.security.cert.X509Certificate +import kotlinx.android.synthetic.main.dialog_handle_ssl_certificate.cb_accept_certificate +import kotlinx.android.synthetic.main.dialog_handle_ssl_certificate.certificate_details +import kotlinx.android.synthetic.main.dialog_handle_ssl_certificate.show_certificate +import kotlinx.android.synthetic.main.dialog_handle_ssl_certificate.tv_finger_print_text @Dialog(R.layout.dialog_handle_ssl_certificate) class AssignSslCertificateDialog : BaseDialog() { @@ -19,6 +22,7 @@ class AssignSslCertificateDialog : BaseDialog : BaseDialog(), ProgressAware, ErrorDisplay { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BetaConfirmationDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BetaConfirmationDialog.kt index 5de287c4..14d109f5 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BetaConfirmationDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BetaConfirmationDialog.kt @@ -10,6 +10,7 @@ import org.cryptomator.presentation.R class BetaConfirmationDialog : BaseDialog() { interface Callback { + fun onAskForBetaConfirmationFinished() } @@ -25,6 +26,7 @@ class BetaConfirmationDialog : BaseDialog() { } companion object { + fun newInstance(): DialogFragment { return BetaConfirmationDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt index 595a333e..0e397bd8 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt @@ -20,6 +20,7 @@ class BiometricAuthKeyInvalidatedDialog : BaseDialog() { @@ -19,6 +22,7 @@ class ChangePasswordDialog : BaseProgressErrorDialog() { @@ -21,6 +21,7 @@ class CloudNodeRenameDialog : BaseProgressErrorDialog, newCloudNodeName: String) } @@ -94,6 +95,7 @@ class CloudNodeRenameDialog : BaseProgressErrorDialog): CloudNodeRenameDialog { val dialog = CloudNodeRenameDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ConfirmDeleteCloudNodeDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ConfirmDeleteCloudNodeDialog.kt index 205568ff..78c80df5 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ConfirmDeleteCloudNodeDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ConfirmDeleteCloudNodeDialog.kt @@ -4,18 +4,19 @@ import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_confirm_delete_cloud_node.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.model.CloudFolderModel import org.cryptomator.presentation.model.CloudNodeModel import java.io.Serializable +import kotlinx.android.synthetic.main.dialog_confirm_delete_cloud_node.tv_message @Dialog(R.layout.dialog_confirm_delete_cloud_node) class ConfirmDeleteCloudNodeDialog : BaseDialog() { interface Callback { + fun onDeleteCloudNodeConfirmed(nodes: List>) } @@ -50,6 +51,7 @@ class ConfirmDeleteCloudNodeDialog : BaseDialog>): DialogFragment { val confirmDeleteCloudNodeDialog = ConfirmDeleteCloudNodeDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateFolderDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateFolderDialog.kt index 8b6c3cb6..9d3794d2 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateFolderDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateFolderDialog.kt @@ -6,11 +6,11 @@ import android.text.TextWatcher import android.view.View import android.widget.Button import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_create_folder.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import org.cryptomator.presentation.model.ProgressModel import org.cryptomator.presentation.model.ProgressStateModel +import kotlinx.android.synthetic.main.dialog_create_folder.et_folder_name @Dialog(R.layout.dialog_create_folder) class CreateFolderDialog : BaseProgressErrorDialog() { @@ -18,6 +18,7 @@ class CreateFolderDialog : BaseProgressErrorDialog( private var createFolderButton: Button? = null interface Callback { + fun onCreateFolderClick(folderName: String) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DebugModeDisclaimerDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DebugModeDisclaimerDialog.kt index c93697a9..e8ccacef 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DebugModeDisclaimerDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DebugModeDisclaimerDialog.kt @@ -10,6 +10,7 @@ import org.cryptomator.presentation.R class DebugModeDisclaimerDialog : BaseDialog() { interface Callback { + fun onDisclaimerAccepted() fun onDisclaimerRejected() } @@ -32,6 +33,7 @@ class DebugModeDisclaimerDialog : BaseDialog } companion object { + fun newInstance(): DialogFragment { return DebugModeDisclaimerDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DeleteCloudConnectionWithVaultsDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DeleteCloudConnectionWithVaultsDialog.kt index ed40b9d2..bd7db986 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DeleteCloudConnectionWithVaultsDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DeleteCloudConnectionWithVaultsDialog.kt @@ -7,12 +7,13 @@ import org.cryptomator.domain.Vault import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel -import java.util.* +import java.util.ArrayList @Dialog(R.layout.dialog_delete_cloud_connection_with_vaults) class DeleteCloudConnectionWithVaultsDialog : BaseDialog() { interface Callback { + fun onDeleteCloudConnectionAndVaults(cloudModel: CloudModel, vaultsOfCloud: ArrayList) } @@ -30,6 +31,7 @@ class DeleteCloudConnectionWithVaultsDialog : BaseDialog): DeleteCloudConnectionWithVaultsDialog { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DisableAppWhenObscuredDisclaimerDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DisableAppWhenObscuredDisclaimerDialog.kt index 7115e671..4be71ea9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DisableAppWhenObscuredDisclaimerDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/DisableAppWhenObscuredDisclaimerDialog.kt @@ -4,14 +4,15 @@ import android.content.DialogInterface import android.text.method.LinkMovementMethod import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_disable_app_obscured_disclaimer.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_disable_app_obscured_disclaimer.tv_disable_app_obscured_disclaimer @Dialog(R.layout.dialog_disable_app_obscured_disclaimer) class DisableAppWhenObscuredDisclaimerDialog : BaseDialog() { interface Callback { + fun onDisableAppObscuredDisclaimerAccepted() fun onDisableAppObscuredDisclaimerRejected() } @@ -34,6 +35,7 @@ class DisableAppWhenObscuredDisclaimerDialog : BaseDialog() { interface Callback { + fun onDisableSecureScreenDisclaimerAccepted() fun onDisableSecureScreenDisclaimerRejected() } @@ -34,6 +35,7 @@ class DisableSecureScreenDisclaimerDialog : BaseDialog() { interface Callback { + fun onSetupBiometricAuthInSystemClicked() fun onCancelSetupBiometricAuthInSystemClicked() } @@ -31,6 +32,7 @@ class EnrollSystemBiometricDialog : BaseDialog() { interface Callback { + fun onReplaceClick(uri: Uri) } @@ -29,6 +30,7 @@ class ExistingFileDialog : BaseDialog() { } companion object { + private const val FILE_URI_ARG = "fileUri" private const val FILE_NAME_ARG = "fileName" fun newInstance(uri: Uri, fileName: String): ExistingFileDialog { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ExportCloudFilesDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ExportCloudFilesDialog.kt index 40410c85..0042a865 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ExportCloudFilesDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ExportCloudFilesDialog.kt @@ -3,7 +3,6 @@ package org.cryptomator.presentation.ui.dialog import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.view_dialog_intermediate_progress.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFileModel @@ -11,12 +10,15 @@ import org.cryptomator.presentation.model.FileProgressStateModel import org.cryptomator.presentation.model.ProgressModel import org.cryptomator.presentation.model.ProgressStateModel import org.cryptomator.presentation.util.ResourceHelper -import java.util.* +import java.util.HashSet +import kotlinx.android.synthetic.main.view_dialog_intermediate_progress.iv_progress_icon +import kotlinx.android.synthetic.main.view_dialog_intermediate_progress.pb_dialog @Dialog(R.layout.dialog_upload_loading) class ExportCloudFilesDialog : BaseProgressErrorDialog() { interface Callback { + fun onExportCancelled() } @@ -68,6 +70,7 @@ class ExportCloudFilesDialog : BaseProgressErrorDialog() { @@ -17,6 +17,7 @@ class FileNameDialog : BaseProgressErrorDialog() { private var createFileButton: Button? = null interface Callback { + fun onCreateNewTextFileClicked(fileName: String) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/FileTypeNotSupportedDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/FileTypeNotSupportedDialog.kt index 360865b6..3bd9f70f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/FileTypeNotSupportedDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/FileTypeNotSupportedDialog.kt @@ -11,6 +11,7 @@ import org.cryptomator.presentation.model.CloudFileModel class FileTypeNotSupportedDialog : BaseDialog() { interface Callback { + fun onExportFileAfterAppChooserClicked(cloudFile: CloudFileModel) } @@ -25,6 +26,7 @@ class FileTypeNotSupportedDialog : BaseDialog(), ProgressAware { @@ -41,6 +42,7 @@ class GenericProgressDialog : BaseDialog(), ProgressAware { } companion object { + private const val INITIAL_PROGRESS = "initialProgress" fun create(progressModel: ProgressModel): GenericProgressDialog { val dialog = GenericProgressDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/LicenseConfirmationDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/LicenseConfirmationDialog.kt index e651e68a..61f83a88 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/LicenseConfirmationDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/LicenseConfirmationDialog.kt @@ -3,14 +3,15 @@ package org.cryptomator.presentation.ui.dialog import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_license_confirmation.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_license_confirmation.tv_message @Dialog(R.layout.dialog_license_confirmation) class LicenseConfirmationDialog : BaseDialog() { interface Callback { + fun licenseConfirmationClicked() } @@ -27,6 +28,7 @@ class LicenseConfirmationDialog : BaseDialog } companion object { + private const val ARG_MAIL = "argMail" fun newInstance(mail: String): LicenseConfirmationDialog { val confirmationDialog = LicenseConfirmationDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NoDirFileDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NoDirFileDialog.kt index 2a2d3f3c..013fd8a0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NoDirFileDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NoDirFileDialog.kt @@ -4,14 +4,15 @@ import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_no_dir_file.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_no_dir_file.tv_no_dir_file_info @Dialog(R.layout.dialog_no_dir_file) class NoDirFileDialog : BaseDialog() { interface CallBack { + fun navigateFolderBackBecauseNoDirFile() } @@ -36,6 +37,7 @@ class NoDirFileDialog : BaseDialog() { } companion object { + private const val ARG_CRYPTO_FOLDER_NAME = "argCryptoFolderName" private const val ARG_CLOUD_FOLDER_PATH = "argCloudFolderPath" fun newInstance(cryptoFolderName: String, cloudFolderPath: String): DialogFragment { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NotEnoughVaultsDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NotEnoughVaultsDialog.kt index 254985cd..8b093848 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NotEnoughVaultsDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/NotEnoughVaultsDialog.kt @@ -12,6 +12,7 @@ class NotEnoughVaultsDialog private constructor(private val context: Context) { private var title: String interface Callback { + fun onNotEnoughVaultsOkClicked() fun onNotEnoughVaultsCreateVaultClicked() } @@ -33,6 +34,7 @@ class NotEnoughVaultsDialog private constructor(private val context: Context) { } companion object { + fun withContext(context: Context): NotEnoughVaultsDialog { return NotEnoughVaultsDialog(context) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ReplaceDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ReplaceDialog.kt index e767efaa..3592e914 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ReplaceDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ReplaceDialog.kt @@ -11,6 +11,7 @@ class ReplaceDialog private constructor(private val context: Context) { private val callback: Callback interface Callback { + fun onReplacePositiveClicked() fun onReplaceNegativeClicked() fun onReplaceCanceled() @@ -67,6 +68,7 @@ class ReplaceDialog private constructor(private val context: Context) { } companion object { + fun withContext(context: Context): ReplaceDialog { return ReplaceDialog(context) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/SymLinkDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/SymLinkDialog.kt index 8bde8407..dd8efe14 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/SymLinkDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/SymLinkDialog.kt @@ -4,14 +4,15 @@ import android.content.DialogInterface import android.text.method.LinkMovementMethod import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_sym_link.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_sym_link.tv_sym_link_info @Dialog(R.layout.dialog_sym_link) class SymLinkDialog : BaseDialog() { interface CallBack { + fun navigateFolderBackBecauseSymlink() } @@ -30,6 +31,7 @@ class SymLinkDialog : BaseDialog() { } companion object { + fun newInstance(): DialogFragment { return SymLinkDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UnsavedChangesDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UnsavedChangesDialog.kt index 70c21a94..adf0259a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UnsavedChangesDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UnsavedChangesDialog.kt @@ -10,6 +10,7 @@ class UnsavedChangesDialog private constructor(private val context: Context) { private val callback: Callback interface Callback { + fun onSaveChangesClicked() fun onDiscardChangesClicked() } @@ -25,6 +26,7 @@ class UnsavedChangesDialog private constructor(private val context: Context) { } companion object { + fun withContext(context: Context): UnsavedChangesDialog { return UnsavedChangesDialog(context) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateAppAvailableDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateAppAvailableDialog.kt index 1ac94bb4..0f22a180 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateAppAvailableDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateAppAvailableDialog.kt @@ -6,14 +6,15 @@ import android.os.Bundle import android.text.Html import android.view.View import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_app_update.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_app_update.tv_message @Dialog(R.layout.dialog_app_update) class UpdateAppAvailableDialog : BaseProgressErrorDialog() { interface Callback { + fun installUpdate() fun cancelUpdateClicked() fun showUpdateWebsite() @@ -43,6 +44,7 @@ class UpdateAppAvailableDialog : BaseProgressErrorDialog() { interface Callback { + fun onUpdateAppDialogLoaded() } @@ -35,6 +36,7 @@ class UpdateAppDialog : BaseProgressErrorDialog() { } companion object { + fun newInstance(): UpdateAppDialog { return UpdateAppDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateLicenseDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateLicenseDialog.kt index 164738f8..52b5f5d5 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateLicenseDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/UpdateLicenseDialog.kt @@ -5,9 +5,9 @@ import android.os.Bundle import android.view.View import android.widget.Button import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.dialog_enter_license.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R +import kotlinx.android.synthetic.main.dialog_enter_license.et_license @Dialog(R.layout.dialog_enter_license) class UpdateLicenseDialog : BaseProgressErrorDialog() { @@ -16,6 +16,7 @@ class UpdateLicenseDialog : BaseProgressErrorDialog() { @@ -19,6 +20,7 @@ class UploadCloudFileDialog : BaseProgressErrorDialog() { interface Callback { + fun onDeleteConfirmedClick(vaultModel: VaultModel) } @@ -28,6 +29,7 @@ class VaultDeleteConfirmationDialog : BaseDialog() { @@ -20,6 +20,7 @@ class VaultRenameDialog : BaseProgressErrorDialog() private var renameConfirmButton: Button? = null interface Callback { + fun onRenameClick(vaultModel: VaultModel, newVaultName: String) } @@ -69,6 +70,7 @@ class VaultRenameDialog : BaseProgressErrorDialog() } companion object { + private const val VAULT_ARG = "vault" fun newInstance(vaultModel: VaultModel): VaultRenameDialog { val dialog = VaultRenameDialog() diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/WebDavAskForHttpDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/WebDavAskForHttpDialog.kt index 27a275a1..2d2379ff 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/WebDavAskForHttpDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/WebDavAskForHttpDialog.kt @@ -4,10 +4,10 @@ import android.content.DialogInterface import android.os.Bundle import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.dialog_ask_for_http.* import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import java.net.URI +import kotlinx.android.synthetic.main.dialog_ask_for_http.cb_select_http @Dialog(R.layout.dialog_ask_for_http) class WebDavAskForHttpDialog : BaseDialog() { @@ -20,6 +20,7 @@ class WebDavAskForHttpDialog : BaseDialog() { private var cloudId: Long? = null interface Callback { + fun onAksForHttpFinished(username: String, password: String, url: String, cloudId: Long?, certificate: String?) } @@ -63,6 +64,7 @@ class WebDavAskForHttpDialog : BaseDialog() { } companion object { + private const val URI_ARG = "uri" private const val USERNAME_ARG = "username" private const val PASSWORD_ARG = "password" diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/AutoUploadChooseVaultFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/AutoUploadChooseVaultFragment.kt index e7f12b66..c43bd47d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/AutoUploadChooseVaultFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/AutoUploadChooseVaultFragment.kt @@ -1,8 +1,6 @@ package org.cryptomator.presentation.ui.fragment import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_shared_files.* -import kotlinx.android.synthetic.main.view_receive_save_button.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFolderModel @@ -11,6 +9,8 @@ import org.cryptomator.presentation.presenter.AutoUploadChooseVaultPresenter import org.cryptomator.presentation.ui.adapter.SharedLocationsAdapter import org.cryptomator.util.SharedPreferencesHandler import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_shared_files.* +import kotlinx.android.synthetic.main.view_receive_save_button.* @Fragment(R.layout.fragment_auto_upload_choose_vault) class AutoUploadChooseVaultFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BaseFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BaseFragment.kt index 7e4f32f4..ed790bcd 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BaseFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BaseFragment.kt @@ -11,8 +11,8 @@ import org.cryptomator.presentation.di.component.ActivityComponent import org.cryptomator.presentation.exception.ExceptionHandlers import org.cryptomator.presentation.presenter.Presenter import org.cryptomator.presentation.util.KeyboardHelper -import timber.log.Timber import javax.inject.Inject +import timber.log.Timber abstract class BaseFragment : Fragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BiometricAuthSettingsFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BiometricAuthSettingsFragment.kt index f9595388..cefcefa9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BiometricAuthSettingsFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BiometricAuthSettingsFragment.kt @@ -2,8 +2,6 @@ package org.cryptomator.presentation.ui.fragment import android.util.TypedValue import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_settings_biometric_auth.* -import kotlinx.android.synthetic.main.recycler_view_layout.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.VaultModel @@ -12,6 +10,9 @@ import org.cryptomator.presentation.ui.adapter.BiometricAuthSettingsAdapter import org.cryptomator.presentation.ui.adapter.BiometricAuthSettingsAdapter.OnVaultBiometricAuthSettingsChanged import org.cryptomator.util.SharedPreferencesHandler import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_settings_biometric_auth.toggleBiometricAuth +import kotlinx.android.synthetic.main.fragment_settings_biometric_auth.toggleFaceUnlockConfirmation +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView @Fragment(R.layout.fragment_settings_biometric_auth) class BiometricAuthSettingsFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BrowseFilesFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BrowseFilesFragment.kt index e82265ab..7fcac79b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BrowseFilesFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/BrowseFilesFragment.kt @@ -10,11 +10,6 @@ import android.widget.RelativeLayout import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import kotlinx.android.synthetic.main.floating_action_button_layout.* -import kotlinx.android.synthetic.main.fragment_browse_files.* -import kotlinx.android.synthetic.main.recycler_view_layout.* -import kotlinx.android.synthetic.main.view_browses_files_extra_text_and_button.* -import kotlinx.android.synthetic.main.view_empty_folder.* import org.cryptomator.domain.CloudNode import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R @@ -32,8 +27,16 @@ import org.cryptomator.presentation.presenter.BrowseFilesPresenter import org.cryptomator.presentation.ui.adapter.BrowseFilesAdapter import org.cryptomator.presentation.util.ResourceHelper.Companion.getPixelOffset import org.cryptomator.util.Optional -import java.util.* +import java.util.Comparator import javax.inject.Inject +import kotlinx.android.synthetic.main.floating_action_button_layout.floatingActionButton +import kotlinx.android.synthetic.main.fragment_browse_files.slidingCoordinatorLayout +import kotlinx.android.synthetic.main.fragment_browse_files.swipeRefreshLayout +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView +import kotlinx.android.synthetic.main.view_browses_files_extra_text_and_button.chooseLocationButton +import kotlinx.android.synthetic.main.view_browses_files_extra_text_and_button.extraText +import kotlinx.android.synthetic.main.view_browses_files_extra_text_and_button.extraTextAndButtonLayout +import kotlinx.android.synthetic.main.view_empty_folder.emptyFolderHint @Fragment(R.layout.fragment_browse_files) class BrowseFilesFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ChooseCloudServiceFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ChooseCloudServiceFragment.kt index a9f15e49..3c63a3e2 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ChooseCloudServiceFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ChooseCloudServiceFragment.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.ui.fragment import androidx.recyclerview.widget.GridLayoutManager -import kotlinx.android.synthetic.main.recycler_view_layout.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudTypeModel @@ -9,6 +8,7 @@ import org.cryptomator.presentation.presenter.ChooseCloudServicePresenter import org.cryptomator.presentation.ui.adapter.CloudsAdapter import org.cryptomator.presentation.ui.adapter.CloudsAdapter.OnItemClickListener import javax.inject.Inject +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView @Fragment(R.layout.fragment_choose_cloud_service) class ChooseCloudServiceFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudConnectionListFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudConnectionListFragment.kt index e550df6b..bf974c6f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudConnectionListFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudConnectionListFragment.kt @@ -5,10 +5,6 @@ import android.util.TypedValue import android.view.View.GONE import android.view.View.VISIBLE import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_browse_cloud_connections.* -import kotlinx.android.synthetic.main.recycler_view_layout.* -import kotlinx.android.synthetic.main.view_cloud_connection_content.* -import kotlinx.android.synthetic.main.view_empty_cloud_connections.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel @@ -16,6 +12,12 @@ import org.cryptomator.presentation.model.CloudTypeModel import org.cryptomator.presentation.presenter.CloudConnectionListPresenter import org.cryptomator.presentation.ui.adapter.CloudConnectionListAdapter import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_browse_cloud_connections.floating_action_button +import kotlinx.android.synthetic.main.fragment_browse_cloud_connections.rv_local_default_cloud +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView +import kotlinx.android.synthetic.main.view_cloud_connection_content.cloudSubText +import kotlinx.android.synthetic.main.view_cloud_connection_content.cloudText +import kotlinx.android.synthetic.main.view_empty_cloud_connections.rl_creation_hint @Fragment(R.layout.fragment_browse_cloud_connections) class CloudConnectionListFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudSettingsFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudSettingsFragment.kt index 4f48f8ea..46460eaa 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudSettingsFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/CloudSettingsFragment.kt @@ -1,7 +1,6 @@ package org.cryptomator.presentation.ui.fragment import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.recycler_view_layout.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudModel @@ -9,6 +8,7 @@ import org.cryptomator.presentation.presenter.CloudSettingsPresenter import org.cryptomator.presentation.ui.adapter.CloudSettingsAdapter import org.cryptomator.presentation.ui.adapter.CloudSettingsAdapter.OnItemClickListener import javax.inject.Inject +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView @Fragment(R.layout.fragment_cloud_settings) class CloudSettingsFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/EmptyDirIdFileInfoFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/EmptyDirIdFileInfoFragment.kt index e467945d..7de9617f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/EmptyDirIdFileInfoFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/EmptyDirIdFileInfoFragment.kt @@ -1,10 +1,11 @@ package org.cryptomator.presentation.ui.fragment -import kotlinx.android.synthetic.main.fragment_empty_dir_file_info.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.presenter.EmptyDirIdFileInfoPresenter import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_empty_dir_file_info.infoText +import kotlinx.android.synthetic.main.fragment_empty_dir_file_info.moreDetailsButton @Fragment(R.layout.fragment_empty_dir_file_info) class EmptyDirIdFileInfoFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ImagePreviewFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ImagePreviewFragment.kt index c595f7d8..5d69d9f6 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ImagePreviewFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/ImagePreviewFragment.kt @@ -1,17 +1,22 @@ package org.cryptomator.presentation.ui.fragment import android.os.Bundle -import android.view.* +import android.view.GestureDetector +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView -import kotlinx.android.synthetic.main.fragment_image_preview.* import org.cryptomator.presentation.R import org.cryptomator.presentation.di.HasComponent import org.cryptomator.presentation.di.component.ActivityComponent import org.cryptomator.presentation.model.ImagePreviewFile import org.cryptomator.presentation.presenter.ImagePreviewPresenter import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_image_preview.imageView +import kotlinx.android.synthetic.main.fragment_image_preview.progressBar class ImagePreviewFragment : Fragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/LicensesFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/LicensesFragment.kt index 72250c0f..7df1e1eb 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/LicensesFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/LicensesFragment.kt @@ -5,6 +5,7 @@ import androidx.preference.PreferenceFragmentCompat import org.cryptomator.presentation.R class LicensesFragment : PreferenceFragmentCompat() { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.licenses) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SetPasswordFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SetPasswordFragment.kt index 627ff2e9..a2479259 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SetPasswordFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SetPasswordFragment.kt @@ -1,13 +1,16 @@ package org.cryptomator.presentation.ui.fragment import android.view.inputmethod.EditorInfo -import kotlinx.android.synthetic.main.fragment_set_password.* -import kotlinx.android.synthetic.main.view_password_strength_indicator.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.presenter.SetPasswordPresenter import org.cryptomator.presentation.util.PasswordStrengthUtil import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_set_password.createVaultButton +import kotlinx.android.synthetic.main.fragment_set_password.passwordEditText +import kotlinx.android.synthetic.main.fragment_set_password.passwordRetypedEditText +import kotlinx.android.synthetic.main.view_password_strength_indicator.progressBarPwStrengthIndicator +import kotlinx.android.synthetic.main.view_password_strength_indicator.textViewPwStrengthIndicator @Fragment(R.layout.fragment_set_password) class SetPasswordFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SettingsFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SettingsFragment.kt index 5c912189..a8cd7886 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SettingsFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SettingsFragment.kt @@ -22,12 +22,12 @@ import org.cryptomator.presentation.ui.dialog.DisableAppWhenObscuredDisclaimerDi import org.cryptomator.presentation.ui.dialog.DisableSecureScreenDisclaimerDialog import org.cryptomator.util.SharedPreferencesHandler import org.cryptomator.util.file.LruFileCacheUtil -import timber.log.Timber import java.lang.Boolean.FALSE import java.lang.Boolean.TRUE import java.lang.String.format import java.text.DecimalFormat import kotlin.math.log10 +import timber.log.Timber class SettingsFragment : PreferenceFragmentCompat() { @@ -269,6 +269,7 @@ class SettingsFragment : PreferenceFragmentCompat() { } companion object { + private const val APP_VERSION_ITEM_KEY = "appVersion" private const val SEND_ERROR_REPORT_ITEM_KEY = "sendErrorReport" private const val BIOMETRIC_AUTHENTICATION_ITEM_KEY = "biometricAuthentication" diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SharedFilesFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SharedFilesFragment.kt index 9d6f8e51..bafbcdfa 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SharedFilesFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/SharedFilesFragment.kt @@ -1,8 +1,6 @@ package org.cryptomator.presentation.ui.fragment import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_shared_files.* -import kotlinx.android.synthetic.main.view_receive_save_button.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.CloudFolderModel @@ -13,6 +11,9 @@ import org.cryptomator.presentation.ui.adapter.SharedFilesAdapter import org.cryptomator.presentation.ui.adapter.SharedFilesAdapter.Callback import org.cryptomator.presentation.ui.adapter.SharedLocationsAdapter import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_shared_files.filesRecyclerView +import kotlinx.android.synthetic.main.fragment_shared_files.locationsRecyclerView +import kotlinx.android.synthetic.main.view_receive_save_button.saveFiles @Fragment(R.layout.fragment_shared_files) class SharedFilesFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/TextEditorFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/TextEditorFragment.kt index 2b837884..d816bcce 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/TextEditorFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/TextEditorFragment.kt @@ -5,12 +5,13 @@ import android.text.style.BackgroundColorSpan import androidx.annotation.NonNull import androidx.core.content.ContextCompat import com.google.android.material.textfield.TextInputEditText -import kotlinx.android.synthetic.main.fragment_text_editor.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.presenter.TextEditorPresenter -import java.util.* +import java.util.Locale import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_text_editor.textEditor +import kotlinx.android.synthetic.main.fragment_text_editor.textViewWrapper @Fragment(R.layout.fragment_text_editor) class TextEditorFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/VaultListFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/VaultListFragment.kt index 6d46bdac..acecea51 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/VaultListFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/VaultListFragment.kt @@ -4,9 +4,6 @@ import android.util.TypedValue import android.view.View import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_vault_list.* -import kotlinx.android.synthetic.main.recycler_view_layout.* -import kotlinx.android.synthetic.main.view_vault_creation_hint.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.VaultModel @@ -14,6 +11,10 @@ import org.cryptomator.presentation.presenter.VaultListPresenter import org.cryptomator.presentation.ui.adapter.VaultsAdapter import org.cryptomator.presentation.ui.adapter.VaultsMoveListener import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_vault_list.coordinatorLayout +import kotlinx.android.synthetic.main.fragment_vault_list.floating_action_button +import kotlinx.android.synthetic.main.recycler_view_layout.recyclerView +import kotlinx.android.synthetic.main.view_vault_creation_hint.rl_creation_hint @Fragment(R.layout.fragment_vault_list) class VaultListFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WebDavAddOrChangeFragment.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WebDavAddOrChangeFragment.kt index 3285b987..5b07aa5d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WebDavAddOrChangeFragment.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/fragment/WebDavAddOrChangeFragment.kt @@ -2,14 +2,17 @@ package org.cryptomator.presentation.ui.fragment import android.os.Bundle import android.view.inputmethod.EditorInfo -import kotlinx.android.synthetic.main.fragment_setup_webdav.* import org.cryptomator.generator.Fragment import org.cryptomator.presentation.R import org.cryptomator.presentation.model.WebDavCloudModel import org.cryptomator.presentation.presenter.WebDavAddOrChangePresenter import org.cryptomator.util.crypto.CredentialCryptor -import timber.log.Timber import javax.inject.Inject +import kotlinx.android.synthetic.main.fragment_setup_webdav.createCloudButton +import kotlinx.android.synthetic.main.fragment_setup_webdav.passwordEditText +import kotlinx.android.synthetic.main.fragment_setup_webdav.urlPortEditText +import kotlinx.android.synthetic.main.fragment_setup_webdav.userNameEditText +import timber.log.Timber @Fragment(R.layout.fragment_setup_webdav) class WebDavAddOrChangeFragment : BaseFragment() { diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ArcAwareCoordinatorLayout.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ArcAwareCoordinatorLayout.kt index 265d67e4..7b9d0f4c 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ArcAwareCoordinatorLayout.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ArcAwareCoordinatorLayout.kt @@ -9,9 +9,9 @@ import android.util.DisplayMetrics import android.view.View import androidx.coordinatorlayout.widget.CoordinatorLayout import org.cryptomator.presentation.R -import timber.log.Timber import kotlin.math.cos import kotlin.math.sin +import timber.log.Timber class ArcAwareCoordinatorLayout : CoordinatorLayout { @@ -81,6 +81,7 @@ class ArcAwareCoordinatorLayout : CoordinatorLayout { } private class ArcBuilder(val x1: Float, val y1: Float, val layoutDirection: Int) { + var angle = 0f var x2 = 0f var y2 = 0f @@ -103,6 +104,7 @@ class ArcAwareCoordinatorLayout : CoordinatorLayout { } private class Arc(b: ArcBuilder) { + private val left: Float private val right: Float private val top: Float @@ -118,6 +120,7 @@ class ArcAwareCoordinatorLayout : CoordinatorLayout { } companion object { + private const val TWO_PI = 2f * Math.PI } @@ -165,6 +168,7 @@ class ArcAwareCoordinatorLayout : CoordinatorLayout { } companion object { + private fun arcFrom(x1: Float, y1: Float, layoutDirection: Int): ArcBuilder { return ArcBuilder(x1, y1, layoutDirection) } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ObscuredAwareCoordinatorLayout.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ObscuredAwareCoordinatorLayout.kt index 0fe0bc1c..d725e60d 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ObscuredAwareCoordinatorLayout.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/layout/ObscuredAwareCoordinatorLayout.kt @@ -27,6 +27,7 @@ class ObscuredAwareCoordinatorLayout : CoordinatorLayout { } interface Listener { + fun onFilteredTouchEventForSecurity() } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/snackbar/AppSettingsAction.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/snackbar/AppSettingsAction.kt index 1c1adcd0..d385a4f0 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/snackbar/AppSettingsAction.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/snackbar/AppSettingsAction.kt @@ -20,6 +20,7 @@ class AppSettingsAction(private val context: Context) : SnackbarAction { get() = R.string.snack_bar_action_title_settings companion object { + private const val PACKAGE = "package:" } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/BiometricAuthentication.kt b/presentation/src/main/java/org/cryptomator/presentation/util/BiometricAuthentication.kt index acef14e5..fad7d4e8 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/BiometricAuthentication.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/BiometricAuthentication.kt @@ -12,8 +12,8 @@ import org.cryptomator.presentation.R import org.cryptomator.presentation.model.VaultModel import org.cryptomator.util.crypto.BiometricAuthCryptor import org.cryptomator.util.crypto.UnrecoverableStorageKeyException -import timber.log.Timber import java.util.concurrent.Executor +import timber.log.Timber @RequiresApi(Build.VERSION_CODES.M) class BiometricAuthentication(val callback: Callback, val context: Context, val cryptoMode: CryptoMode, private val useConfirmationInFaceUnlockAuth: Boolean) { @@ -33,6 +33,7 @@ class BiometricAuthentication(val callback: Callback, val context: Context, val } companion object { + private lateinit var executor: Executor private lateinit var biometricPrompt: BiometricPrompt private lateinit var promptInfo: BiometricPrompt.PromptInfo diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/Blacklist.kt b/presentation/src/main/java/org/cryptomator/presentation/util/Blacklist.kt index b4b00d89..c243ffb3 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/Blacklist.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/Blacklist.kt @@ -7,6 +7,7 @@ internal interface Blacklist> { fun isBlacklisted(cloudNodeModel: T): Boolean interface Entry { + fun isBlacklisted(name: String): Boolean } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/ContentResolverUtil.kt b/presentation/src/main/java/org/cryptomator/presentation/util/ContentResolverUtil.kt index 9ab0d262..feef2b78 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/ContentResolverUtil.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/ContentResolverUtil.kt @@ -8,7 +8,7 @@ import java.io.File import java.io.FileNotFoundException import java.io.InputStream import java.io.OutputStream -import java.util.* +import java.util.ArrayList import javax.inject.Inject class ContentResolverUtil @Inject constructor(context: Context) { @@ -129,6 +129,7 @@ class ContentResolverUtil @Inject constructor(context: Context) { } companion object { + private const val CONTENT_SCHEME = "content" private const val FILE_SCHEME = "file" } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/DateHelper.kt b/presentation/src/main/java/org/cryptomator/presentation/util/DateHelper.kt index 91d02f4b..bdd1741b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/DateHelper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/DateHelper.kt @@ -2,7 +2,7 @@ package org.cryptomator.presentation.util import org.cryptomator.presentation.R import org.cryptomator.util.Optional -import java.util.* +import java.util.Date import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -51,10 +51,12 @@ class DateHelper @Inject constructor() { } private interface TimePeriod { + fun convert(timeInMilliseconds: Long): Long } companion object { + private fun currentDate(): Date { return Date() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/DownloadFileUtil.kt b/presentation/src/main/java/org/cryptomator/presentation/util/DownloadFileUtil.kt index 308a6b7b..dc657a2f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/DownloadFileUtil.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/DownloadFileUtil.kt @@ -5,7 +5,7 @@ import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.presenter.Presenter import java.io.FileNotFoundException import java.io.OutputStream -import java.util.* +import java.util.ArrayList import javax.inject.Inject class DownloadFileUtil @Inject constructor(private val fileUtil: FileUtil) { diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/EmailBuilder.kt b/presentation/src/main/java/org/cryptomator/presentation/util/EmailBuilder.kt index bc91c3be..a0490538 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/EmailBuilder.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/EmailBuilder.kt @@ -4,9 +4,10 @@ import android.content.Context import android.content.Intent import androidx.core.content.FileProvider import java.io.File -import java.util.* +import java.util.ArrayList class EmailBuilder private constructor() { + private var recipient: String? = null private var subject: String? = null private var body: String? = null @@ -51,6 +52,7 @@ class EmailBuilder private constructor() { } companion object { + fun anEmail(): EmailBuilder { return EmailBuilder() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/FileIcon.java b/presentation/src/main/java/org/cryptomator/presentation/util/FileIcon.java index 2d2b9ef3..a5718972 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/FileIcon.java +++ b/presentation/src/main/java/org/cryptomator/presentation/util/FileIcon.java @@ -32,9 +32,15 @@ public enum FileIcon { forMediaTypeOrExtensions("text", "md", "todo")), // VAULT(R.drawable.node_vault, // forExtensions("cryptomator")), // - UNKNOWN(R.drawable.node_file_unknown) + UNKNOWN(R.drawable.node_file_unknown); - ; + private final int iconResource; + private final Predicate[] predicates; + + FileIcon(int iconResource, Predicate... predicates) { + this.iconResource = iconResource; + this.predicates = predicates; + } public static Optional knownFileIconFor(String name, FileUtil fileUtil) { FileInfo fileInfo = fileUtil.fileInfo(name); @@ -50,27 +56,6 @@ public enum FileIcon { return knownFileIconFor(name, fileUtil).orElse(UNKNOWN); } - private final int iconResource; - private final Predicate[] predicates; - - FileIcon(int iconResource, Predicate... predicates) { - this.iconResource = iconResource; - this.predicates = predicates; - } - - private boolean matches(FileInfo fileInfo) { - for (Predicate predicate : predicates) { - if (predicate.test(fileInfo)) { - return true; - } - } - return false; - } - - public int getIconResource() { - return iconResource; - } - private static Predicate forExtensions(final String... extensions) { return fileInfo -> fileInfo.getExtension().map(fileExtension -> { for (String extension : extensions) { @@ -96,4 +81,17 @@ public enum FileIcon { return FALSE; }).orElse(FALSE); } + + private boolean matches(FileInfo fileInfo) { + for (Predicate predicate : predicates) { + if (predicate.test(fileInfo)) { + return true; + } + } + return false; + } + + public int getIconResource() { + return iconResource; + } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/FileNameValidator.kt b/presentation/src/main/java/org/cryptomator/presentation/util/FileNameValidator.kt index 9c818019..7d085840 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/FileNameValidator.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/FileNameValidator.kt @@ -3,6 +3,7 @@ package org.cryptomator.presentation.util class FileNameValidator { companion object { + private val INVALID_FILENAME_PATTERN = Regex("[\\\\/:*?\"<>|]|\\.\$| \$") fun isInvalidName(name: String): Boolean { diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/FileSizeHelper.kt b/presentation/src/main/java/org/cryptomator/presentation/util/FileSizeHelper.kt index 79e98dfd..96e0b17f 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/FileSizeHelper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/FileSizeHelper.kt @@ -10,6 +10,7 @@ import kotlin.math.min import kotlin.math.pow class FileSizeHelper @Inject constructor(private val context: Context) { + private val units: Array = arrayOf( // context.getString(R.string.file_size_unit_bytes), // context.getString(R.string.file_size_unit_kilo_bytes), // diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt b/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt index a0a24cfa..0f70cbd5 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/FileUtil.kt @@ -12,10 +12,20 @@ import org.cryptomator.util.Optional import org.cryptomator.util.file.LruFileCacheUtil import org.cryptomator.util.file.MimeType import org.cryptomator.util.file.MimeTypes -import timber.log.Timber -import java.io.* -import java.util.* +import java.io.File +import java.io.FileInputStream +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.io.IOException +import java.io.InvalidClassException +import java.io.ObjectInputStream +import java.io.ObjectOutputStream +import java.io.OutputStream +import java.util.ArrayList +import java.util.HashSet +import java.util.Locale import javax.inject.Inject +import timber.log.Timber class FileUtil @Inject constructor(private val context: Context, private val mimeTypes: MimeTypes) { @@ -239,6 +249,7 @@ class FileUtil @Inject constructor(private val context: Context, private val mim } class FileInfo(val name: String, mimeTypes: MimeTypes) { + var extension: Optional var mimeType: MimeType diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/KeyboardHelper.kt b/presentation/src/main/java/org/cryptomator/presentation/util/KeyboardHelper.kt index d358c28a..4d460e78 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/KeyboardHelper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/KeyboardHelper.kt @@ -7,6 +7,7 @@ import android.view.WindowManager import android.view.inputmethod.InputMethodManager object KeyboardHelper { + fun hideKeyboard(context: Context, view: View) { val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(view.windowToken, 0) diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/PasswordStrength.kt b/presentation/src/main/java/org/cryptomator/presentation/util/PasswordStrength.kt index f2451b3c..d1bb6227 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/PasswordStrength.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/PasswordStrength.kt @@ -13,6 +13,7 @@ enum class PasswordStrength(val score: Int, val description: Int, val color: Int GOOD(4, R.string.screen_set_password_strength_indicator_4, R.color.password_strength_4); companion object { + private val zxcvbn = Zxcvbn() fun forPassword(password: String, sanitizedInputs: List): PasswordStrength { diff --git a/presentation/src/main/java/org/cryptomator/presentation/util/ShareFileHelper.kt b/presentation/src/main/java/org/cryptomator/presentation/util/ShareFileHelper.kt index 5dfb00d1..c825ccb9 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/util/ShareFileHelper.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/util/ShareFileHelper.kt @@ -7,8 +7,8 @@ import org.cryptomator.presentation.model.CloudFileModel import org.cryptomator.presentation.presenter.ActivityHolder import org.cryptomator.util.file.MimeType import org.cryptomator.util.file.MimeTypes -import timber.log.Timber import javax.inject.Inject +import timber.log.Timber class ShareFileHelper @Inject constructor( // private val fileUtil: FileUtil, // diff --git a/presentation/src/main/java/org/cryptomator/presentation/workflow/AddExistingVaultWorkflow.java b/presentation/src/main/java/org/cryptomator/presentation/workflow/AddExistingVaultWorkflow.java index 6548e311..379dcf1a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/workflow/AddExistingVaultWorkflow.java +++ b/presentation/src/main/java/org/cryptomator/presentation/workflow/AddExistingVaultWorkflow.java @@ -79,18 +79,18 @@ public class AddExistingVaultWorkflow extends Workflow result) { state().name = result.getResult(); chain(browseFilesIntent() // - .withTitle(context.getString(cloudModelMapper.toModel(state().cloudRoot.getCloud()).name())) // - .withFolder(new CloudFolderModel(state().cloudRoot)) // - .withChooseCloudNodeSettings( // - chooseCloudNodeSettings() // - .withExtraTitle(presenter().context().getString(R.string.screen_file_browser_subtitle_create_new_vault)) // - .withExtraText(presenter().context().getString(R.string.screen_file_browser_create_new_vault_extra_text, state().name)) // - .withButtonText(presenter().context().getString(R.string.screen_file_browser_create_new_vault_button_text)) // - .selectingFoldersNotContaining(singletonList(state().name)) // - .build()), // + .withTitle(context.getString(cloudModelMapper.toModel(state().cloudRoot.getCloud()).name())) // + .withFolder(new CloudFolderModel(state().cloudRoot)) // + .withChooseCloudNodeSettings( // + chooseCloudNodeSettings() // + .withExtraTitle(presenter().context().getString(R.string.screen_file_browser_subtitle_create_new_vault)) // + .withExtraText(presenter().context().getString(R.string.screen_file_browser_create_new_vault_extra_text, state().name)) // + .withButtonText(presenter().context().getString(R.string.screen_file_browser_create_new_vault_button_text)) // + .selectingFoldersNotContaining(singletonList(state().name)) // + .build()), // SerializableResultCallbacks.locationChosen()); } diff --git a/presentation/src/main/res/animator/enter_from_left.xml b/presentation/src/main/res/animator/enter_from_left.xml index 6e3bb99a..aae8ea30 100644 --- a/presentation/src/main/res/animator/enter_from_left.xml +++ b/presentation/src/main/res/animator/enter_from_left.xml @@ -3,7 +3,7 @@ + android:valueTo="0" + android:valueType="floatType" /> diff --git a/presentation/src/main/res/animator/enter_from_right.xml b/presentation/src/main/res/animator/enter_from_right.xml index 5b183157..e856f47f 100644 --- a/presentation/src/main/res/animator/enter_from_right.xml +++ b/presentation/src/main/res/animator/enter_from_right.xml @@ -3,7 +3,7 @@ + android:valueTo="0" + android:valueType="floatType" /> diff --git a/presentation/src/main/res/animator/exit_to_left.xml b/presentation/src/main/res/animator/exit_to_left.xml index 5e8cc811..a95f3f2f 100644 --- a/presentation/src/main/res/animator/exit_to_left.xml +++ b/presentation/src/main/res/animator/exit_to_left.xml @@ -3,7 +3,7 @@ + android:valueTo="-1" + android:valueType="floatType" /> diff --git a/presentation/src/main/res/animator/exit_to_right.xml b/presentation/src/main/res/animator/exit_to_right.xml index 05a1173c..7993722d 100644 --- a/presentation/src/main/res/animator/exit_to_right.xml +++ b/presentation/src/main/res/animator/exit_to_right.xml @@ -3,7 +3,7 @@ + android:valueTo="1" + android:valueType="floatType" /> diff --git a/presentation/src/main/res/drawable-night/ic_add_gray.xml b/presentation/src/main/res/drawable-night/ic_add_gray.xml index 81e5ac8e..51dafc98 100644 --- a/presentation/src/main/res/drawable-night/ic_add_gray.xml +++ b/presentation/src/main/res/drawable-night/ic_add_gray.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_add_white.xml b/presentation/src/main/res/drawable-night/ic_add_white.xml index 81e5ac8e..51dafc98 100644 --- a/presentation/src/main/res/drawable-night/ic_add_white.xml +++ b/presentation/src/main/res/drawable-night/ic_add_white.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_clear.xml b/presentation/src/main/res/drawable-night/ic_clear.xml index f3d900f3..70dfd52f 100644 --- a/presentation/src/main/res/drawable-night/ic_clear.xml +++ b/presentation/src/main/res/drawable-night/ic_clear.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_cloud.xml b/presentation/src/main/res/drawable-night/ic_cloud.xml index 6953d5ba..8d7213a3 100644 --- a/presentation/src/main/res/drawable-night/ic_cloud.xml +++ b/presentation/src/main/res/drawable-night/ic_cloud.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_create_new_folder.xml b/presentation/src/main/res/drawable-night/ic_create_new_folder.xml index 491eb61f..0c4ca6dc 100644 --- a/presentation/src/main/res/drawable-night/ic_create_new_folder.xml +++ b/presentation/src/main/res/drawable-night/ic_create_new_folder.xml @@ -1,8 +1,8 @@ - + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_delete.xml b/presentation/src/main/res/drawable-night/ic_delete.xml index d120940c..0fbce5ad 100644 --- a/presentation/src/main/res/drawable-night/ic_delete.xml +++ b/presentation/src/main/res/drawable-night/ic_delete.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_edit.xml b/presentation/src/main/res/drawable-night/ic_edit.xml index e2ba1b89..5f9c5ece 100644 --- a/presentation/src/main/res/drawable-night/ic_edit.xml +++ b/presentation/src/main/res/drawable-night/ic_edit.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_expand_more.xml b/presentation/src/main/res/drawable-night/ic_expand_more.xml index aae5b3e2..d3854e81 100644 --- a/presentation/src/main/res/drawable-night/ic_expand_more.xml +++ b/presentation/src/main/res/drawable-night/ic_expand_more.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_export.xml b/presentation/src/main/res/drawable-night/ic_export.xml index 1a9d0725..4fc44d34 100644 --- a/presentation/src/main/res/drawable-night/ic_export.xml +++ b/presentation/src/main/res/drawable-night/ic_export.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_file_download.xml b/presentation/src/main/res/drawable-night/ic_file_download.xml index 79360c8f..0ab978b8 100644 --- a/presentation/src/main/res/drawable-night/ic_file_download.xml +++ b/presentation/src/main/res/drawable-night/ic_file_download.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_file_upload.xml b/presentation/src/main/res/drawable-night/ic_file_upload.xml index ae1ae3a7..929d7ea5 100644 --- a/presentation/src/main/res/drawable-night/ic_file_upload.xml +++ b/presentation/src/main/res/drawable-night/ic_file_upload.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> + android:fillColor="#FFFFFF" + android:pathData="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z" /> diff --git a/presentation/src/main/res/drawable-night/ic_file_upload_gray.xml b/presentation/src/main/res/drawable-night/ic_file_upload_gray.xml index c395e8fd..929d7ea5 100644 --- a/presentation/src/main/res/drawable-night/ic_file_upload_gray.xml +++ b/presentation/src/main/res/drawable-night/ic_file_upload_gray.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_folder.xml b/presentation/src/main/res/drawable-night/ic_folder.xml index a1503985..d6b82141 100644 --- a/presentation/src/main/res/drawable-night/ic_folder.xml +++ b/presentation/src/main/res/drawable-night/ic_folder.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_lock.xml b/presentation/src/main/res/drawable-night/ic_lock.xml index 5953255f..5e1148e5 100644 --- a/presentation/src/main/res/drawable-night/ic_lock.xml +++ b/presentation/src/main/res/drawable-night/ic_lock.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_lock_closed.xml b/presentation/src/main/res/drawable-night/ic_lock_closed.xml index 07cda57c..ca42c73b 100644 --- a/presentation/src/main/res/drawable-night/ic_lock_closed.xml +++ b/presentation/src/main/res/drawable-night/ic_lock_closed.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_lock_open.xml b/presentation/src/main/res/drawable-night/ic_lock_open.xml index 71e8e5fa..8ff7b376 100644 --- a/presentation/src/main/res/drawable-night/ic_lock_open.xml +++ b/presentation/src/main/res/drawable-night/ic_lock_open.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_search.xml b/presentation/src/main/res/drawable-night/ic_search.xml index 47deeaf5..dc0595a1 100644 --- a/presentation/src/main/res/drawable-night/ic_search.xml +++ b/presentation/src/main/res/drawable-night/ic_search.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_az.xml b/presentation/src/main/res/drawable-night/ic_sort_az.xml index 09824b38..e0cc0dd0 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_az.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_az.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_biggest.xml b/presentation/src/main/res/drawable-night/ic_sort_biggest.xml index 353d52c0..e140f27a 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_biggest.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_biggest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_newest.xml b/presentation/src/main/res/drawable-night/ic_sort_newest.xml index 321fd571..7b449339 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_newest.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_newest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_oldest.xml b/presentation/src/main/res/drawable-night/ic_sort_oldest.xml index ea35fe19..72bb9fac 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_oldest.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_oldest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_smallest.xml b/presentation/src/main/res/drawable-night/ic_sort_smallest.xml index 02104150..43758a5c 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_smallest.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_smallest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable-night/ic_sort_za.xml b/presentation/src/main/res/drawable-night/ic_sort_za.xml index 0378daa0..4ce651a7 100644 --- a/presentation/src/main/res/drawable-night/ic_sort_za.xml +++ b/presentation/src/main/res/drawable-night/ic_sort_za.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/background_image_preview_toolbar.xml b/presentation/src/main/res/drawable/background_image_preview_toolbar.xml index 35041c1e..9c30914b 100644 --- a/presentation/src/main/res/drawable/background_image_preview_toolbar.xml +++ b/presentation/src/main/res/drawable/background_image_preview_toolbar.xml @@ -2,6 +2,6 @@ + android:endColor="@android:color/transparent" + android:startColor="@color/colorBlackTransparent" /> diff --git a/presentation/src/main/res/drawable/ic_add_gray.xml b/presentation/src/main/res/drawable/ic_add_gray.xml index 267ae2cc..d02b8097 100644 --- a/presentation/src/main/res/drawable/ic_add_gray.xml +++ b/presentation/src/main/res/drawable/ic_add_gray.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_add_white.xml b/presentation/src/main/res/drawable/ic_add_white.xml index 81e5ac8e..51dafc98 100644 --- a/presentation/src/main/res/drawable/ic_add_white.xml +++ b/presentation/src/main/res/drawable/ic_add_white.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_clear.xml b/presentation/src/main/res/drawable/ic_clear.xml index f3d900f3..70dfd52f 100644 --- a/presentation/src/main/res/drawable/ic_clear.xml +++ b/presentation/src/main/res/drawable/ic_clear.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_cloud.xml b/presentation/src/main/res/drawable/ic_cloud.xml index 6953d5ba..8d7213a3 100644 --- a/presentation/src/main/res/drawable/ic_cloud.xml +++ b/presentation/src/main/res/drawable/ic_cloud.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_create_new_folder.xml b/presentation/src/main/res/drawable/ic_create_new_folder.xml index 491eb61f..0c4ca6dc 100644 --- a/presentation/src/main/res/drawable/ic_create_new_folder.xml +++ b/presentation/src/main/res/drawable/ic_create_new_folder.xml @@ -1,8 +1,8 @@ - + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_delete.xml b/presentation/src/main/res/drawable/ic_delete.xml index 42d21f69..6fa381b9 100644 --- a/presentation/src/main/res/drawable/ic_delete.xml +++ b/presentation/src/main/res/drawable/ic_delete.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_edit.xml b/presentation/src/main/res/drawable/ic_edit.xml index 4d073f68..88f7f596 100644 --- a/presentation/src/main/res/drawable/ic_edit.xml +++ b/presentation/src/main/res/drawable/ic_edit.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_expand_more.xml b/presentation/src/main/res/drawable/ic_expand_more.xml index 62708f28..15a3bbf1 100644 --- a/presentation/src/main/res/drawable/ic_expand_more.xml +++ b/presentation/src/main/res/drawable/ic_expand_more.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_export.xml b/presentation/src/main/res/drawable/ic_export.xml index e36b7738..bd98b07e 100644 --- a/presentation/src/main/res/drawable/ic_export.xml +++ b/presentation/src/main/res/drawable/ic_export.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_file_download.xml b/presentation/src/main/res/drawable/ic_file_download.xml index da003c5c..3bf7253a 100644 --- a/presentation/src/main/res/drawable/ic_file_download.xml +++ b/presentation/src/main/res/drawable/ic_file_download.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_file_upload.xml b/presentation/src/main/res/drawable/ic_file_upload.xml index adcc96c4..60dfa26c 100644 --- a/presentation/src/main/res/drawable/ic_file_upload.xml +++ b/presentation/src/main/res/drawable/ic_file_upload.xml @@ -4,6 +4,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> + android:fillColor="#000000" + android:pathData="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z" /> diff --git a/presentation/src/main/res/drawable/ic_file_upload_gray.xml b/presentation/src/main/res/drawable/ic_file_upload_gray.xml index fccfc3b8..5c41708a 100644 --- a/presentation/src/main/res/drawable/ic_file_upload_gray.xml +++ b/presentation/src/main/res/drawable/ic_file_upload_gray.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_folder.xml b/presentation/src/main/res/drawable/ic_folder.xml index c6ba950a..23b164c6 100644 --- a/presentation/src/main/res/drawable/ic_folder.xml +++ b/presentation/src/main/res/drawable/ic_folder.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_launcher_background.xml b/presentation/src/main/res/drawable/ic_launcher_background.xml index adffe5a8..d8544c4f 100644 --- a/presentation/src/main/res/drawable/ic_launcher_background.xml +++ b/presentation/src/main/res/drawable/ic_launcher_background.xml @@ -1,78 +1,176 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:width="108dp" + android:height="108dp" + android:viewportWidth="108" + android:viewportHeight="108"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/drawable/ic_lock.xml b/presentation/src/main/res/drawable/ic_lock.xml index 1cda5850..c47025e0 100644 --- a/presentation/src/main/res/drawable/ic_lock.xml +++ b/presentation/src/main/res/drawable/ic_lock.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_lock_closed.xml b/presentation/src/main/res/drawable/ic_lock_closed.xml index 07cda57c..ca42c73b 100644 --- a/presentation/src/main/res/drawable/ic_lock_closed.xml +++ b/presentation/src/main/res/drawable/ic_lock_closed.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_lock_open.xml b/presentation/src/main/res/drawable/ic_lock_open.xml index 71e8e5fa..8ff7b376 100644 --- a/presentation/src/main/res/drawable/ic_lock_open.xml +++ b/presentation/src/main/res/drawable/ic_lock_open.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_search.xml b/presentation/src/main/res/drawable/ic_search.xml index 8fbb7487..d218fe99 100644 --- a/presentation/src/main/res/drawable/ic_search.xml +++ b/presentation/src/main/res/drawable/ic_search.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_search_white.xml b/presentation/src/main/res/drawable/ic_search_white.xml index 47deeaf5..dc0595a1 100644 --- a/presentation/src/main/res/drawable/ic_search_white.xml +++ b/presentation/src/main/res/drawable/ic_search_white.xml @@ -1,8 +1,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/presentation/src/main/res/drawable/ic_sort_az.xml b/presentation/src/main/res/drawable/ic_sort_az.xml index e7c54f9d..140a1c37 100644 --- a/presentation/src/main/res/drawable/ic_sort_az.xml +++ b/presentation/src/main/res/drawable/ic_sort_az.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/ic_sort_biggest.xml b/presentation/src/main/res/drawable/ic_sort_biggest.xml index 836f35a6..1607fa3f 100644 --- a/presentation/src/main/res/drawable/ic_sort_biggest.xml +++ b/presentation/src/main/res/drawable/ic_sort_biggest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/ic_sort_newest.xml b/presentation/src/main/res/drawable/ic_sort_newest.xml index 72955b84..49ac2a2b 100644 --- a/presentation/src/main/res/drawable/ic_sort_newest.xml +++ b/presentation/src/main/res/drawable/ic_sort_newest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/ic_sort_oldest.xml b/presentation/src/main/res/drawable/ic_sort_oldest.xml index a9001fd9..8f4c31c4 100644 --- a/presentation/src/main/res/drawable/ic_sort_oldest.xml +++ b/presentation/src/main/res/drawable/ic_sort_oldest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/ic_sort_smallest.xml b/presentation/src/main/res/drawable/ic_sort_smallest.xml index f257dd27..b0faadfa 100644 --- a/presentation/src/main/res/drawable/ic_sort_smallest.xml +++ b/presentation/src/main/res/drawable/ic_sort_smallest.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/ic_sort_za.xml b/presentation/src/main/res/drawable/ic_sort_za.xml index e5961d80..17d54442 100644 --- a/presentation/src/main/res/drawable/ic_sort_za.xml +++ b/presentation/src/main/res/drawable/ic_sort_za.xml @@ -1,9 +1,9 @@ + android:viewportHeight="512"> diff --git a/presentation/src/main/res/drawable/item_browse_files_node_selector.xml b/presentation/src/main/res/drawable/item_browse_files_node_selector.xml index f17c78cf..1c5af921 100644 --- a/presentation/src/main/res/drawable/item_browse_files_node_selector.xml +++ b/presentation/src/main/res/drawable/item_browse_files_node_selector.xml @@ -1,5 +1,5 @@ - + diff --git a/presentation/src/main/res/layout/activity_image_preview.xml b/presentation/src/main/res/layout/activity_image_preview.xml index 41d1fd6b..a25fac71 100644 --- a/presentation/src/main/res/layout/activity_image_preview.xml +++ b/presentation/src/main/res/layout/activity_image_preview.xml @@ -24,13 +24,13 @@ android:id="@+id/controlView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fitsSystemWindows="true" - android:background="@drawable/background_image_preview_controls" - android:layout_gravity="end" - android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" - android:padding="12dp" - android:layout_marginBottom="16dp"> + android:layout_alignParentBottom="true" + android:layout_gravity="end" + android:layout_marginBottom="16dp" + android:background="@drawable/background_image_preview_controls" + android:fitsSystemWindows="true" + android:padding="12dp"> diff --git a/presentation/src/main/res/layout/content_create_vault.xml b/presentation/src/main/res/layout/content_create_vault.xml index a403b834..819d5a8f 100644 --- a/presentation/src/main/res/layout/content_create_vault.xml +++ b/presentation/src/main/res/layout/content_create_vault.xml @@ -4,14 +4,14 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingBottom="@dimen/activity_vertical_margin" + android:orientation="vertical" android:paddingStart="@dimen/activity_horizontal_margin" - android:paddingEnd="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" + android:paddingEnd="@dimen/activity_horizontal_margin" + android:paddingBottom="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".ui.activity.CreateVaultActivity" - tools:showIn="@layout/activity_create_vault" - android:orientation="vertical"> + tools:showIn="@layout/activity_create_vault"> + android:singleLine="true" /> diff --git a/presentation/src/main/res/layout/dialog_ask_for_http.xml b/presentation/src/main/res/layout/dialog_ask_for_http.xml index 45a05eb1..665e5d84 100644 --- a/presentation/src/main/res/layout/dialog_ask_for_http.xml +++ b/presentation/src/main/res/layout/dialog_ask_for_http.xml @@ -21,8 +21,8 @@ android:layout_height="wrap_content" android:layout_below="@id/tv_security_hint" android:checked="true" - android:paddingEnd="16dp" android:paddingStart="16dp" + android:paddingEnd="16dp" android:text="@string/dialog_http_security_checkbox" /> diff --git a/presentation/src/main/res/layout/dialog_biometric_auth_key_invalidated.xml b/presentation/src/main/res/layout/dialog_biometric_auth_key_invalidated.xml index 6b765109..1ba2dd52 100644 --- a/presentation/src/main/res/layout/dialog_biometric_auth_key_invalidated.xml +++ b/presentation/src/main/res/layout/dialog_biometric_auth_key_invalidated.xml @@ -3,10 +3,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingBottom="@dimen/activity_vertical_margin" android:paddingStart="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" android:paddingEnd="@dimen/activity_horizontal_margin" - android:paddingTop="@dimen/activity_vertical_margin"> + android:paddingBottom="@dimen/activity_vertical_margin"> + android:paddingBottom="8dp"> + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" /> @@ -66,8 +66,8 @@ android:id="@+id/change_cloud" style="@style/AppTheme.ListItem" android:text="@string/screen_cloud_settings_option_edit" - app:drawableStartCompat="@drawable/ic_edit" - android:visibility="gone" /> + android:visibility="gone" + app:drawableStartCompat="@drawable/ic_edit" /> + android:paddingBottom="8dp"> + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" /> @@ -71,8 +71,8 @@ android:id="@+id/open_with_text" style="@style/AppTheme.ListItem" android:text="@string/screen_file_browser_node_action_open_with_text" - app:drawableStartCompat="@drawable/ic_open_with" - android:visibility="gone" /> + android:visibility="gone" + app:drawableStartCompat="@drawable/ic_open_with" /> + android:paddingBottom="8dp"> diff --git a/presentation/src/main/res/layout/dialog_bottom_sheet_vault_action.xml b/presentation/src/main/res/layout/dialog_bottom_sheet_vault_action.xml index 89e44ff0..896aa82c 100644 --- a/presentation/src/main/res/layout/dialog_bottom_sheet_vault_action.xml +++ b/presentation/src/main/res/layout/dialog_bottom_sheet_vault_action.xml @@ -5,23 +5,23 @@ android:layout_height="match_parent"> + android:paddingBottom="8dp"> + android:textSize="16sp" /> + android:paddingBottom="8dp"> + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" /> + android:maxLines="1" /> @@ -37,9 +37,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/dialog_change_password_new_password_label" + android:imeOptions="flagNoPersonalizedLearning" android:inputType="textPassword" - android:maxLines="1" - android:imeOptions="flagNoPersonalizedLearning" /> + android:maxLines="1" /> @@ -55,9 +55,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/dialog_change_password_new_retype_password_label" + android:imeOptions="flagNoPersonalizedLearning" android:inputType="textPassword" - android:maxLines="1" - android:imeOptions="flagNoPersonalizedLearning" /> + android:maxLines="1" /> diff --git a/presentation/src/main/res/layout/dialog_confirm_delete_cloud_node.xml b/presentation/src/main/res/layout/dialog_confirm_delete_cloud_node.xml index 19768497..53825bb5 100644 --- a/presentation/src/main/res/layout/dialog_confirm_delete_cloud_node.xml +++ b/presentation/src/main/res/layout/dialog_confirm_delete_cloud_node.xml @@ -7,10 +7,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingBottom="@dimen/activity_vertical_margin" android:paddingStart="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" android:paddingEnd="@dimen/activity_horizontal_margin" - android:paddingTop="@dimen/activity_vertical_margin"> + android:paddingBottom="@dimen/activity_vertical_margin"> + android:paddingBottom="@dimen/activity_vertical_margin"> + android:layout_marginBottom="5dp" + android:text="@string/dialog_enter_license_content" /> + android:maxLines="1" /> diff --git a/presentation/src/main/res/layout/dialog_existing_file.xml b/presentation/src/main/res/layout/dialog_existing_file.xml index 19768497..53825bb5 100644 --- a/presentation/src/main/res/layout/dialog_existing_file.xml +++ b/presentation/src/main/res/layout/dialog_existing_file.xml @@ -7,10 +7,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingBottom="@dimen/activity_vertical_margin" android:paddingStart="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" android:paddingEnd="@dimen/activity_horizontal_margin" - android:paddingTop="@dimen/activity_vertical_margin"> + android:paddingBottom="@dimen/activity_vertical_margin"> + android:maxLines="1" /> diff --git a/presentation/src/main/res/layout/dialog_license_confirmation.xml b/presentation/src/main/res/layout/dialog_license_confirmation.xml index 28f580c4..6f3af309 100644 --- a/presentation/src/main/res/layout/dialog_license_confirmation.xml +++ b/presentation/src/main/res/layout/dialog_license_confirmation.xml @@ -12,8 +12,8 @@ android:id="@+id/tv_message" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/dialog_license_confirmation_message" - android:layout_marginBottom="5dp" /> + android:layout_marginBottom="5dp" + android:text="@string/dialog_license_confirmation_message" /> diff --git a/presentation/src/main/res/layout/dialog_no_screen_lock_set.xml b/presentation/src/main/res/layout/dialog_no_screen_lock_set.xml index 7ab9fee8..a6bf2897 100644 --- a/presentation/src/main/res/layout/dialog_no_screen_lock_set.xml +++ b/presentation/src/main/res/layout/dialog_no_screen_lock_set.xml @@ -21,8 +21,8 @@ android:layout_below="@id/tv_no_screenlock" android:layout_marginTop="27dp" android:checked="true" - android:paddingEnd="16dp" android:paddingStart="16dp" + android:paddingEnd="16dp" android:text="@string/dialog_no_screen_lock_checkbox" /> diff --git a/presentation/src/main/res/layout/dialog_rename.xml b/presentation/src/main/res/layout/dialog_rename.xml index 4f0d738c..54284d1c 100644 --- a/presentation/src/main/res/layout/dialog_rename.xml +++ b/presentation/src/main/res/layout/dialog_rename.xml @@ -12,10 +12,10 @@ android:id="@+id/et_rename" android:layout_width="match_parent" android:layout_height="wrap_content" + android:imeOptions="flagNoPersonalizedLearning" android:inputType="text" android:maxLines="1" - android:selectAllOnFocus="true" - android:imeOptions="flagNoPersonalizedLearning" /> + android:selectAllOnFocus="true" /> + android:paddingBottom="@dimen/activity_vertical_margin"> diff --git a/presentation/src/main/res/layout/fragment_browse_cloud_connections.xml b/presentation/src/main/res/layout/fragment_browse_cloud_connections.xml index 94300748..4da30d58 100644 --- a/presentation/src/main/res/layout/fragment_browse_cloud_connections.xml +++ b/presentation/src/main/res/layout/fragment_browse_cloud_connections.xml @@ -21,8 +21,8 @@ android:layout_width="match_parent" android:layout_height="72dp" android:clickable="true" - android:focusable="true" - android:clipToPadding="true" /> + android:clipToPadding="true" + android:focusable="true" /> + android:layout_height="wrap_content" + android:layout_centerInParent="true" /> diff --git a/presentation/src/main/res/layout/fragment_set_password.xml b/presentation/src/main/res/layout/fragment_set_password.xml index 74aef055..ff3b4ee3 100644 --- a/presentation/src/main/res/layout/fragment_set_password.xml +++ b/presentation/src/main/res/layout/fragment_set_password.xml @@ -3,8 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="@dimen/activity_vertical_margin" - android:orientation="vertical"> + android:orientation="vertical" + android:padding="@dimen/activity_vertical_margin"> + android:singleLine="true" /> @@ -33,10 +33,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/screen_set_password_retype_password_label" + android:imeOptions="flagNoPersonalizedLearning" android:inputType="textPassword" android:maxLines="1" - android:singleLine="true" - android:imeOptions="flagNoPersonalizedLearning" /> + android:singleLine="true" /> diff --git a/presentation/src/main/res/layout/fragment_settings_biometric_auth.xml b/presentation/src/main/res/layout/fragment_settings_biometric_auth.xml index c30a1ec1..0f307b23 100644 --- a/presentation/src/main/res/layout/fragment_settings_biometric_auth.xml +++ b/presentation/src/main/res/layout/fragment_settings_biometric_auth.xml @@ -2,8 +2,8 @@ + android:paddingStart="17dp" + android:paddingEnd="16dp"> @@ -46,8 +46,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" - android:layout_toStartOf="@+id/toggleFaceUnlockConfirmation" android:layout_marginEnd="46dp" + android:layout_toStartOf="@+id/toggleFaceUnlockConfirmation" android:text="@string/screen_settings_confirm_face_unlock" android:textSize="16sp" /> @@ -63,8 +63,8 @@ + android:layout_marginTop="@dimen/global_padding" + android:background="@color/list_divider" /> diff --git a/presentation/src/main/res/layout/fragment_setup_webdav.xml b/presentation/src/main/res/layout/fragment_setup_webdav.xml index 054d94ad..75e7d94d 100644 --- a/presentation/src/main/res/layout/fragment_setup_webdav.xml +++ b/presentation/src/main/res/layout/fragment_setup_webdav.xml @@ -2,8 +2,8 @@ + android:orientation="vertical" + android:padding="@dimen/activity_vertical_margin"> + android:text="https://" /> @@ -39,9 +39,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/screen_webdav_settings_username_label" + android:imeOptions="flagNoPersonalizedLearning" android:maxLines="1" - android:singleLine="true" - android:imeOptions="flagNoPersonalizedLearning" /> + android:singleLine="true" /> @@ -54,10 +54,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/screen_webdav_settings_password_label" + android:imeOptions="flagNoPersonalizedLearning" android:inputType="textPassword" android:maxLines="1" - android:singleLine="true" - android:imeOptions="flagNoPersonalizedLearning" /> + android:singleLine="true" /> diff --git a/presentation/src/main/res/layout/fragment_text_editor.xml b/presentation/src/main/res/layout/fragment_text_editor.xml index 9aadfa11..ec31afe2 100644 --- a/presentation/src/main/res/layout/fragment_text_editor.xml +++ b/presentation/src/main/res/layout/fragment_text_editor.xml @@ -14,8 +14,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="top" - android:inputType="textMultiLine" - android:imeOptions="flagNoPersonalizedLearning" /> + android:imeOptions="flagNoPersonalizedLearning" + android:inputType="textMultiLine" /> diff --git a/presentation/src/main/res/layout/item_biometric_auth_vault.xml b/presentation/src/main/res/layout/item_biometric_auth_vault.xml index 7449d68e..b5792baa 100644 --- a/presentation/src/main/res/layout/item_biometric_auth_vault.xml +++ b/presentation/src/main/res/layout/item_biometric_auth_vault.xml @@ -16,10 +16,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginEnd="5dp" android:layout_marginStart="5dp" - android:layout_toEndOf="@+id/cloud" + android:layout_marginEnd="5dp" android:layout_toStartOf="@id/toggleBiometricAuth" + android:layout_toEndOf="@+id/cloud" android:ellipsize="middle" android:singleLine="true" android:textSize="20sp" /> diff --git a/presentation/src/main/res/layout/item_browse_cloud_model_connections.xml b/presentation/src/main/res/layout/item_browse_cloud_model_connections.xml index 2bd09528..445a210e 100644 --- a/presentation/src/main/res/layout/item_browse_cloud_model_connections.xml +++ b/presentation/src/main/res/layout/item_browse_cloud_model_connections.xml @@ -17,11 +17,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginEnd="16dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" - android:layout_toEndOf="@id/cloudImage" - android:layout_toStartOf="@+id/settings" /> + android:layout_marginEnd="16dp" + android:layout_toStartOf="@+id/settings" + android:layout_toEndOf="@id/cloudImage" /> + android:layout_marginEnd="16dp" + android:layout_toStartOf="@+id/controls" + android:layout_toEndOf="@id/cloudNodeImage" /> + android:layout_marginEnd="16dp" + android:layout_toStartOf="@+id/controls" + android:layout_toEndOf="@id/cloudNodeImage" /> + android:layout_centerVertical="true"> diff --git a/presentation/src/main/res/layout/item_cloud_setting.xml b/presentation/src/main/res/layout/item_cloud_setting.xml index 6a26fddb..953870f4 100644 --- a/presentation/src/main/res/layout/item_cloud_setting.xml +++ b/presentation/src/main/res/layout/item_cloud_setting.xml @@ -15,8 +15,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginEnd="16dp" android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" android:layout_toEndOf="@+id/cloudImage" android:orientation="vertical"> diff --git a/presentation/src/main/res/layout/item_shareable_location.xml b/presentation/src/main/res/layout/item_shareable_location.xml index e3e5c0c6..099531e9 100644 --- a/presentation/src/main/res/layout/item_shareable_location.xml +++ b/presentation/src/main/res/layout/item_shareable_location.xml @@ -15,10 +15,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginEnd="8dp" android:layout_marginStart="16dp" - android:layout_toEndOf="@+id/cloudImage" + android:layout_marginEnd="8dp" android:layout_toStartOf="@+id/chooseFolderLocation" + android:layout_toEndOf="@+id/cloudImage" android:orientation="vertical"> + android:singleLine="true" /> + android:visibility="gone" + app:tint="@color/colorPrimary" /> + app:fastScrollTrackColor="@color/textColorWhite" /> diff --git a/presentation/src/main/res/layout/view_cloud_file_content.xml b/presentation/src/main/res/layout/view_cloud_file_content.xml index 99caec7d..e3decfc7 100644 --- a/presentation/src/main/res/layout/view_cloud_file_content.xml +++ b/presentation/src/main/res/layout/view_cloud_file_content.xml @@ -49,8 +49,8 @@ layout="@layout/view_cloud_file_progress" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginEnd="32dp" - android:layout_marginStart="8dp" /> + android:layout_marginStart="8dp" + android:layout_marginEnd="32dp" /> diff --git a/presentation/src/main/res/layout/view_default_local_cloud.xml b/presentation/src/main/res/layout/view_default_local_cloud.xml index 21250ce5..9a44b282 100644 --- a/presentation/src/main/res/layout/view_default_local_cloud.xml +++ b/presentation/src/main/res/layout/view_default_local_cloud.xml @@ -18,9 +18,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:layout_marginEnd="16dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" android:layout_toEndOf="@id/iv_cloud_model_image" /> diff --git a/presentation/src/main/res/menu/menu_file_browser.xml b/presentation/src/main/res/menu/menu_file_browser.xml index 9c34f4c6..527df9f4 100644 --- a/presentation/src/main/res/menu/menu_file_browser.xml +++ b/presentation/src/main/res/menu/menu_file_browser.xml @@ -9,34 +9,34 @@ app:showAsAction="ifRoom" />

+ android:icon="@drawable/ic_sort_az" + android:title="@string/snack_bar_action_title_sort_az" /> + android:icon="@drawable/ic_sort_za" + android:title="@string/snack_bar_action_title_sort_za" /> + android:icon="@drawable/ic_sort_newest" + android:title="@string/snack_bar_action_title_sort_newest" /> + android:icon="@drawable/ic_sort_oldest" + android:title="@string/snack_bar_action_title_sort_oldest" /> + android:icon="@drawable/ic_sort_biggest" + android:title="@string/snack_bar_action_title_sort_biggest" /> + android:icon="@drawable/ic_sort_smallest" + android:title="@string/snack_bar_action_title_sort_smallest" /> diff --git a/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 036d09bc..4a0eb132 100644 --- a/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09bc..4a0eb132 100644 --- a/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/presentation/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/presentation/src/main/res/values/ic_launcher_background.xml b/presentation/src/main/res/values/ic_launcher_background.xml index c5d5899f..f497ac4c 100644 --- a/presentation/src/main/res/values/ic_launcher_background.xml +++ b/presentation/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #FFFFFF - \ No newline at end of file + #FFFFFF + diff --git a/presentation/src/main/res/xml/preferences.xml b/presentation/src/main/res/xml/preferences.xml index 06bf28c2..8130ff88 100644 --- a/presentation/src/main/res/xml/preferences.xml +++ b/presentation/src/main/res/xml/preferences.xml @@ -32,7 +32,7 @@ + android:targetPackage="@string/app_id" /> @@ -117,7 +117,7 @@ + android:targetPackage="@string/app_id" /> @@ -204,7 +204,7 @@ + android:targetPackage="@string/app_id" /> @@ -216,8 +216,8 @@ + android:key="versionCategory" + android:title="@string/screen_settings_section_version"> > naturalOrder(): Comparator { return Comparator { o1: T, o2: T -> o1.compareTo(o2) } } diff --git a/util/src/main/java/org/cryptomator/util/NoOpActivityLifecycleCallbacks.java b/util/src/main/java/org/cryptomator/util/NoOpActivityLifecycleCallbacks.java index a74a79d5..0ad966a3 100644 --- a/util/src/main/java/org/cryptomator/util/NoOpActivityLifecycleCallbacks.java +++ b/util/src/main/java/org/cryptomator/util/NoOpActivityLifecycleCallbacks.java @@ -7,6 +7,7 @@ import android.os.Bundle; import org.jetbrains.annotations.NotNull; public class NoOpActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { + @Override public void onActivityCreated(@NotNull Activity activity, Bundle savedInstanceState) { diff --git a/util/src/main/java/org/cryptomator/util/Optional.java b/util/src/main/java/org/cryptomator/util/Optional.java index 438a0a93..31fb1a69 100644 --- a/util/src/main/java/org/cryptomator/util/Optional.java +++ b/util/src/main/java/org/cryptomator/util/Optional.java @@ -5,6 +5,11 @@ import java.io.Serializable; public class Optional implements Serializable { private static final Optional EMPTY = new Optional(null); + private final T value; + + private Optional(T value) { + this.value = value; + } public static Optional of(T value) { if (value == null) { @@ -25,12 +30,6 @@ public class Optional implements Serializable { return EMPTY; } - private final T value; - - private Optional(T value) { - this.value = value; - } - public boolean isPresent() { return value != null; } @@ -86,10 +85,12 @@ public class Optional implements Serializable { @Override public boolean equals(Object obj) { - if (obj == this) + if (obj == this) { return true; - if (obj == null || getClass() != obj.getClass()) + } + if (obj == null || getClass() != obj.getClass()) { return false; + } return internalEquals((Optional) obj); } diff --git a/util/src/main/java/org/cryptomator/util/SharedPreferencesHandler.kt b/util/src/main/java/org/cryptomator/util/SharedPreferencesHandler.kt index ce24df18..127f746f 100644 --- a/util/src/main/java/org/cryptomator/util/SharedPreferencesHandler.kt +++ b/util/src/main/java/org/cryptomator/util/SharedPreferencesHandler.kt @@ -2,11 +2,15 @@ package org.cryptomator.util import android.content.Context import android.content.SharedPreferences -import androidx.appcompat.app.AppCompatDelegate.* +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES import androidx.preference.PreferenceManager import org.cryptomator.util.LockTimeout.ONE_MINUTE import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale +import java.util.WeakHashMap import javax.inject.Inject import kotlin.math.abs @@ -220,6 +224,7 @@ constructor(context: Context) : SharedPreferences.OnSharedPreferenceChangeListen } companion object { + private const val SCREEN_LOCK_DIALOG_SHOWN = "askForScreenLockDialogShown" private const val SCREEN_BETA_DIALOG_SHOWN = "askForBetaConfirmationDialogShown" private const val USE_BIOMETRIC_AUTHENTICATION = "useFingerprint" diff --git a/util/src/main/java/org/cryptomator/util/concurrent/CompletableFuture.java b/util/src/main/java/org/cryptomator/util/concurrent/CompletableFuture.java index 308e4be1..c44c3cdb 100644 --- a/util/src/main/java/org/cryptomator/util/concurrent/CompletableFuture.java +++ b/util/src/main/java/org/cryptomator/util/concurrent/CompletableFuture.java @@ -1,5 +1,7 @@ package org.cryptomator.util.concurrent; +import androidx.annotation.NonNull; + import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -9,8 +11,6 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import androidx.annotation.NonNull; - public class CompletableFuture implements Future { private final Lock lock = new ReentrantLock(); diff --git a/util/src/main/java/org/cryptomator/util/crypto/BiometricAuthCryptor.java b/util/src/main/java/org/cryptomator/util/crypto/BiometricAuthCryptor.java index 8da30cdf..a6dfd69c 100644 --- a/util/src/main/java/org/cryptomator/util/crypto/BiometricAuthCryptor.java +++ b/util/src/main/java/org/cryptomator/util/crypto/BiometricAuthCryptor.java @@ -20,10 +20,6 @@ public class BiometricAuthCryptor { private final Cipher cipher; - public static BiometricAuthCryptor getInstance(Context context) throws UnrecoverableStorageKeyException { - return new BiometricAuthCryptor(context); - } - private BiometricAuthCryptor(Context context) throws UnrecoverableStorageKeyException { KeyStore keyStore = KeyStoreBuilder.defaultKeyStore() // .withKey(BIOMETRIC_AUTH_KEY_ALIAS, true, context) // @@ -31,6 +27,16 @@ public class BiometricAuthCryptor { this.cipher = CryptoOperationsFactory.cryptoOperations().cryptor(keyStore, BIOMETRIC_AUTH_KEY_ALIAS); } + public static BiometricAuthCryptor getInstance(Context context) throws UnrecoverableStorageKeyException { + return new BiometricAuthCryptor(context); + } + + public static void recreateKey(Context context) { + KeyStoreBuilder.defaultKeyStore() // + .withRecreatedKey(BIOMETRIC_AUTH_KEY_ALIAS, true, context) // + .build(); + } + public javax.crypto.Cipher getDecryptCipher(String decrypted) throws InvalidAlgorithmParameterException, InvalidKeyException { return cipher.getDecryptCipher(decrypted.getBytes(ISO_8859_1)); } @@ -49,10 +55,4 @@ public class BiometricAuthCryptor { byte[] ciphered = cipher.doFinal(CipherFromApi23.getBytes(password.getBytes(ISO_8859_1))); return new String(ciphered, UTF_8); } - - public static void recreateKey(Context context) { - KeyStoreBuilder.defaultKeyStore() // - .withRecreatedKey(BIOMETRIC_AUTH_KEY_ALIAS, true, context) // - .build(); - } } diff --git a/util/src/main/java/org/cryptomator/util/crypto/CipherFromApi23.java b/util/src/main/java/org/cryptomator/util/crypto/CipherFromApi23.java index 4775928b..1164ac07 100644 --- a/util/src/main/java/org/cryptomator/util/crypto/CipherFromApi23.java +++ b/util/src/main/java/org/cryptomator/util/crypto/CipherFromApi23.java @@ -20,6 +20,25 @@ class CipherFromApi23 implements Cipher { this.key = key; } + private static byte[] mergeIvAndEncryptedData(byte[] encrypted, byte[] iv) { + byte[] mergedIvAndEncrypted = new byte[encrypted.length + iv.length]; + arraycopy( // + iv, 0, // + mergedIvAndEncrypted, 0, IV_LENGTH); + arraycopy( // + encrypted, 0, // + mergedIvAndEncrypted, IV_LENGTH, encrypted.length); + return mergedIvAndEncrypted; + } + + static byte[] getBytes(byte[] encryptedBytesWithIv) { + byte[] bytes = new byte[encryptedBytesWithIv.length - IV_LENGTH]; + arraycopy( // + encryptedBytesWithIv, IV_LENGTH, // + bytes, 0, bytes.length); + return bytes; + } + @Override public byte[] encrypt(byte[] data) { try { @@ -58,17 +77,6 @@ class CipherFromApi23 implements Cipher { return cipher; } - private static byte[] mergeIvAndEncryptedData(byte[] encrypted, byte[] iv) { - byte[] mergedIvAndEncrypted = new byte[encrypted.length + iv.length]; - arraycopy( // - iv, 0, // - mergedIvAndEncrypted, 0, IV_LENGTH); - arraycopy( // - encrypted, 0, // - mergedIvAndEncrypted, IV_LENGTH, encrypted.length); - return mergedIvAndEncrypted; - } - private byte[] getIv(byte[] encryptedBytesWithIv) { byte[] iv = new byte[IV_LENGTH]; arraycopy( // @@ -77,12 +85,4 @@ class CipherFromApi23 implements Cipher { return iv; } - static byte[] getBytes(byte[] encryptedBytesWithIv) { - byte[] bytes = new byte[encryptedBytesWithIv.length - IV_LENGTH]; - arraycopy( // - encryptedBytesWithIv, IV_LENGTH, // - bytes, 0, bytes.length); - return bytes; - } - } diff --git a/util/src/main/java/org/cryptomator/util/crypto/CredentialCryptor.java b/util/src/main/java/org/cryptomator/util/crypto/CredentialCryptor.java index 4472f0c1..49ba4de5 100644 --- a/util/src/main/java/org/cryptomator/util/crypto/CredentialCryptor.java +++ b/util/src/main/java/org/cryptomator/util/crypto/CredentialCryptor.java @@ -13,10 +13,6 @@ public class CredentialCryptor { private final Cipher cipher; - public static CredentialCryptor getInstance(Context context) { - return new CredentialCryptor(context); - } - private CredentialCryptor(Context context) { KeyStore keyStore = KeyStoreBuilder.defaultKeyStore() // .withKey(DEFAULT_KEY_ALIAS, false, context) // @@ -26,6 +22,10 @@ public class CredentialCryptor { .cryptor(keyStore, DEFAULT_KEY_ALIAS); } + public static CredentialCryptor getInstance(Context context) { + return new CredentialCryptor(context); + } + public byte[] encrypt(byte[] decrypted) { return cipher.encrypt(decrypted); } diff --git a/util/src/main/java/org/cryptomator/util/crypto/CryptoOperationsFromApi23.java b/util/src/main/java/org/cryptomator/util/crypto/CryptoOperationsFromApi23.java index 2caedc8f..20973b50 100644 --- a/util/src/main/java/org/cryptomator/util/crypto/CryptoOperationsFromApi23.java +++ b/util/src/main/java/org/cryptomator/util/crypto/CryptoOperationsFromApi23.java @@ -38,8 +38,8 @@ class CryptoOperationsFromApi23 implements CryptoOperations { return requireUserAuthentication -> { KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec // .Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) // - .setBlockModes(KeyProperties.BLOCK_MODE_CBC) // - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7); + .setBlockModes(KeyProperties.BLOCK_MODE_CBC) // + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7); builder.setUserAuthenticationRequired(requireUserAuthentication); diff --git a/util/src/main/java/org/cryptomator/util/crypto/KeyStoreBuilder.java b/util/src/main/java/org/cryptomator/util/crypto/KeyStoreBuilder.java index 7a0f2700..85e3ae14 100644 --- a/util/src/main/java/org/cryptomator/util/crypto/KeyStoreBuilder.java +++ b/util/src/main/java/org/cryptomator/util/crypto/KeyStoreBuilder.java @@ -12,6 +12,9 @@ public class KeyStoreBuilder { static final String DEFAULT_KEYSTORE_NAME = "AndroidKeyStore"; + private KeyStoreBuilder() { + } + public static DefaultKeyStoreBuilder defaultKeyStore() { return new KeyStoreBuilderImpl(initializeDefaultKeyStore()); } @@ -33,9 +36,6 @@ public class KeyStoreBuilder { return initializeKeyStore(); } - private KeyStoreBuilder() { - } - public interface CustomKeyStoreBuilder { KeyStore build(); diff --git a/util/src/main/java/org/cryptomator/util/file/FileCacheUtils.kt b/util/src/main/java/org/cryptomator/util/file/FileCacheUtils.kt index 8c83354a..10775d29 100644 --- a/util/src/main/java/org/cryptomator/util/file/FileCacheUtils.kt +++ b/util/src/main/java/org/cryptomator/util/file/FileCacheUtils.kt @@ -3,8 +3,17 @@ package org.cryptomator.util.file import android.content.Context import android.net.Uri import org.cryptomator.util.Encodings -import java.io.* -import java.util.* +import java.io.BufferedReader +import java.io.File +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream +import java.io.InputStreamReader +import java.io.OutputStreamWriter +import java.io.PrintWriter +import java.io.StringWriter +import java.util.UUID import javax.inject.Inject class FileCacheUtils @Inject constructor(context: Context) { @@ -70,6 +79,7 @@ class FileCacheUtils @Inject constructor(context: Context) { } companion object { + private const val EOF = -1 } diff --git a/util/src/main/java/org/cryptomator/util/file/LruFileCacheUtil.kt b/util/src/main/java/org/cryptomator/util/file/LruFileCacheUtil.kt index bbcd0fe1..f2ea8bf7 100644 --- a/util/src/main/java/org/cryptomator/util/file/LruFileCacheUtil.kt +++ b/util/src/main/java/org/cryptomator/util/file/LruFileCacheUtil.kt @@ -3,13 +3,18 @@ package org.cryptomator.util.file import android.content.Context import android.os.Build import com.tomclaw.cache.DiskLruCache -import timber.log.Timber -import java.io.* +import java.io.BufferedInputStream +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStream import java.nio.file.Files import java.nio.file.NoSuchFileException import java.nio.file.Path import java.nio.file.StandardCopyOption -import java.util.* +import java.util.Comparator +import timber.log.Timber class LruFileCacheUtil(context: Context) { @@ -97,6 +102,7 @@ class LruFileCacheUtil(context: Context) { } companion object { + @JvmStatic @Throws(IOException::class) fun retrieveFromLruCache(cacheFile: File, data: OutputStream) { diff --git a/util/src/main/java/org/cryptomator/util/file/MimeType.kt b/util/src/main/java/org/cryptomator/util/file/MimeType.kt index 89acae9c..98b6b8e0 100644 --- a/util/src/main/java/org/cryptomator/util/file/MimeType.kt +++ b/util/src/main/java/org/cryptomator/util/file/MimeType.kt @@ -44,6 +44,7 @@ class MimeType internal constructor(val mediatype: String, val subtype: String) } companion object { + val TO_STRING = Function { obj: MimeType -> obj.toString() } const val WILDCARD_MEDIATYPE = "*" const val WILDCARD_SUBTYPE = "*" diff --git a/util/src/main/java/org/cryptomator/util/file/MimeTypes.kt b/util/src/main/java/org/cryptomator/util/file/MimeTypes.kt index caa6194f..92988c82 100644 --- a/util/src/main/java/org/cryptomator/util/file/MimeTypes.kt +++ b/util/src/main/java/org/cryptomator/util/file/MimeTypes.kt @@ -1,7 +1,7 @@ package org.cryptomator.util.file import org.cryptomator.util.Optional -import java.util.* +import java.util.Locale import javax.inject.Inject class MimeTypes @Inject constructor(private val mimeTypeMap: MimeTypeMap) { diff --git a/util/src/test/java/org/cryptomator/util/ByteArrayUtilsTest.java b/util/src/test/java/org/cryptomator/util/ByteArrayUtilsTest.java index c6f9ed50..fc7776d1 100644 --- a/util/src/test/java/org/cryptomator/util/ByteArrayUtilsTest.java +++ b/util/src/test/java/org/cryptomator/util/ByteArrayUtilsTest.java @@ -63,6 +63,12 @@ public class ByteArrayUtilsTest { return new ByteArrayBuilder(size); } + public interface ByteArrayBuilderAppendWithoutSize { + + ByteArrayBuilder times(int amount); + + } + private static class ByteArrayBuilder { private final byte[] array; @@ -103,10 +109,4 @@ public class ByteArrayUtilsTest { } - public interface ByteArrayBuilderAppendWithoutSize { - - ByteArrayBuilder times(int amount); - - } - }