diff --git a/Gemfile.lock b/Gemfile.lock index c8545b12..82c2529b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,20 +10,20 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.571.0) - aws-sdk-core (3.130.0) + aws-partitions (1.587.0) + aws-sdk-core (3.130.2) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.55.0) + aws-sdk-kms (1.56.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.113.0) + aws-sdk-s3 (1.114.0) aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) bcrypt_pbkdf (1.1.0) @@ -40,7 +40,7 @@ GEM dotenv (2.7.6) ed25519 (1.3.0) emoji_regex (3.2.3) - excon (0.92.1) + excon (0.92.3) faraday (1.10.0) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -70,7 +70,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.205.1) + fastlane (2.205.2) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -115,7 +115,7 @@ GEM mime-types (~> 3.3) fastlane-plugin-get_version_name (0.2.2) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.17.0) + google-apis-androidpublisher_v3 (0.20.0) google-apis-core (>= 0.4, < 2.a) google-apis-core (0.4.2) addressable (~> 2.5, >= 2.5.1) @@ -130,7 +130,7 @@ GEM google-apis-core (>= 0.4, < 2.a) google-apis-playcustomapp_v1 (0.7.0) google-apis-core (>= 0.4, < 2.a) - google-apis-storage_v1 (0.11.0) + google-apis-storage_v1 (0.13.0) google-apis-core (>= 0.4, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) @@ -138,7 +138,7 @@ GEM google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) google-cloud-errors (1.2.0) - google-cloud-storage (1.36.1) + google-cloud-storage (1.36.2) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) @@ -146,7 +146,7 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.1.2) + googleauth (1.1.3) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -176,7 +176,7 @@ GEM optparse (0.1.1) os (1.1.4) plist (3.6.0) - public_suffix (4.0.6) + public_suffix (4.0.7) rake (13.0.6) representable (3.1.1) declarative (< 0.1.0) diff --git a/build.gradle b/build.gradle index 643394d2..96c20f86 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,13 @@ apply from: 'buildsystem/dependencies.gradle' apply plugin: "com.vanniktech.android.junit.jacoco" buildscript { - ext.kotlin_version = '1.6.20' + ext.kotlin_version = '1.6.21' repositories { mavenCentral() google() } dependencies { - classpath 'com.android.tools.build:gradle:7.1.3' + classpath 'com.android.tools.build:gradle:7.2.0' classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0' classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.16.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" diff --git a/buildsystem/dependencies.gradle b/buildsystem/dependencies.gradle index 52112515..1fbeb1cc 100644 --- a/buildsystem/dependencies.gradle +++ b/buildsystem/dependencies.gradle @@ -21,8 +21,8 @@ allprojects { ext { androidBuildToolsVersion = "30.0.3" androidMinSdkVersion = 26 - androidTargetSdkVersion = 30 - androidCompileSdkVersion = 30 + androidTargetSdkVersion = 31 + androidCompileSdkVersion = 31 // android and java libs androidVersion = '4.1.1.4' @@ -42,18 +42,18 @@ ext { rxAndroidVersion = '2.1.1' rxBindingVersion = '2.2.0' - daggerVersion = '2.41' + daggerVersion = '2.42' gsonVersion = '2.9.0' okHttpVersion = '4.9.3' - okHttpDigestVersion = '2.6' + okHttpDigestVersion = '2.7' velocityVersion = '2.3' timberVersion = '5.0.1' - zxcvbnVersion = '1.6.0' + zxcvbnVersion = '1.7.0' scaleImageViewVersion = '3.10.0' @@ -67,19 +67,19 @@ ext { dropboxVersion = '5.2.0' - googleApiServicesVersion = 'v3-rev20220110-1.32.1' + googleApiServicesVersion = 'v3-rev20220508-1.32.1' googlePlayServicesVersion = '19.2.0' - googleClientVersion = '1.33.4' // keep in sync with https://github.com/SailReal/google-http-java-client + googleClientVersion = '1.34.1' // keep in sync with https://github.com/SailReal/google-http-java-client /* update using https://github.com/SailReal/google-http-java-client with `mvn clean install`, copying `google-http-client-*.jar` and `google-http-client-android-*.jar` into the lib folder of this project */ - trackingFreeGoogleCLientVersion = '1.41.5' + trackingFreeGoogleCLientVersion = '1.41.8' - msgraphVersion = '5.19.0' + msgraphVersion = '5.24.0' msgraphAuthVersion = '3.0.2' - minIoVersion = '8.3.8' + minIoVersion = '8.4.1' staxVersion = '1.2.0' // needed for minIO commonsCodecVersion = '1.15' @@ -90,7 +90,7 @@ ext { jUnitVersion = '5.8.2' assertJVersion = '1.7.1' - mockitoVersion = '4.4.0' + mockitoVersion = '4.5.1' mockitoKotlinVersion = '4.0.0' hamcrestVersion = '1.3' dexmakerVersion = '1.0' @@ -100,6 +100,7 @@ ext { rulesVersion = '1.4.0' contributionVersion = '3.4.0' uiautomatorVersion = '2.2.0' + androidxTestJunitKtlnVersion = '1.1.3' androidxCoreVersion = '1.6.0' androidxFragmentVersion = '1.3.6' @@ -111,7 +112,7 @@ ext { androidxBiometricVersion = '1.1.0' androidxTestCoreVersion = '1.4.0' - jsonWebTokenApiVersion = '0.11.2' + jsonWebTokenApiVersion = '0.11.5' dependencies = [ android : "com.google.android:android:${androidVersion}", @@ -126,6 +127,7 @@ ext { documentFile : "androidx.documentfile:documentfile:${androidxDocumentfileVersion}", recyclerView : "androidx.recyclerview:recyclerview:${androidxRecyclerViewVersion}", androidxTestCore : "androidx.test:core:${androidxTestCoreVersion}", + androidxTestJunitKtln : "androidx.test.ext:junit-ktx:${androidxTestJunitKtlnVersion}", commonsCodec : "commons-codec:commons-codec:${commonsCodecVersion}", cryptolib : "org.cryptomator:cryptolib:${cryptolibVersion}", dagger : "com.google.dagger:dagger:${daggerVersion}", diff --git a/data/build.gradle b/data/build.gradle index 5284ae6b..cd56b4ef 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -82,7 +82,7 @@ android { } greendao { - schemaVersion 11 + schemaVersion 12 } configurations.all { @@ -191,6 +191,7 @@ dependencies { testRuntimeOnly dependencies.junitEngine testImplementation dependencies.junitParams testRuntimeOnly dependencies.junit4Engine + implementation dependencies.androidxTestJunitKtln testImplementation dependencies.mockito testImplementation dependencies.mockitoKotlin diff --git a/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt b/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt index 66589972..d7d5a7ec 100644 --- a/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt +++ b/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt @@ -2,9 +2,10 @@ package org.cryptomator.data.db import android.content.Context import android.database.sqlite.SQLiteDatabase -import androidx.test.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.google.common.base.Optional import org.cryptomator.data.db.entities.CloudEntityDao import org.cryptomator.data.db.entities.UpdateCheckEntityDao import org.cryptomator.data.db.entities.VaultEntityDao @@ -25,7 +26,7 @@ import org.junit.runner.RunWith @SmallTest class UpgradeDatabaseTest { - private val context = InstrumentationRegistry.getTargetContext() + private val context = InstrumentationRegistry.getInstrumentation().context private val sharedPreferencesHandler = SharedPreferencesHandler(context) private lateinit var db: Database @@ -580,4 +581,66 @@ class UpgradeDatabaseTest { } } + @Test + fun upgrade11To12IfOldDefaultSet() { + Upgrade0To1().applyTo(db, 0) + Upgrade1To2().applyTo(db, 1) + Upgrade2To3(context).applyTo(db, 2) + Upgrade3To4().applyTo(db, 3) + Upgrade4To5().applyTo(db, 4) + Upgrade5To6().applyTo(db, 5) + Upgrade6To7().applyTo(db, 6) + Upgrade7To8().applyTo(db, 7) + Upgrade8To9(sharedPreferencesHandler).applyTo(db, 8) + Upgrade9To10(sharedPreferencesHandler).applyTo(db, 9) + Upgrade10To11().applyTo(db, 10) + + sharedPreferencesHandler.setUpdateIntervalInDays(Optional.of(7)) + + Upgrade11To12(sharedPreferencesHandler).applyTo(db, 11) + + Assert.assertThat(sharedPreferencesHandler.updateIntervalInDays(), CoreMatchers.`is`(Optional.of(1))) + } + + @Test + fun upgrade11To12MonthlySet() { + Upgrade0To1().applyTo(db, 0) + Upgrade1To2().applyTo(db, 1) + Upgrade2To3(context).applyTo(db, 2) + Upgrade3To4().applyTo(db, 3) + Upgrade4To5().applyTo(db, 4) + Upgrade5To6().applyTo(db, 5) + Upgrade6To7().applyTo(db, 6) + Upgrade7To8().applyTo(db, 7) + Upgrade8To9(sharedPreferencesHandler).applyTo(db, 8) + Upgrade9To10(sharedPreferencesHandler).applyTo(db, 9) + Upgrade10To11().applyTo(db, 10) + + sharedPreferencesHandler.setUpdateIntervalInDays(Optional.of(30)) + + Upgrade11To12(sharedPreferencesHandler).applyTo(db, 11) + + Assert.assertThat(sharedPreferencesHandler.updateIntervalInDays(), CoreMatchers.`is`(Optional.of(1))) + } + + @Test + fun upgrade11To12MonthlyNever() { + Upgrade0To1().applyTo(db, 0) + Upgrade1To2().applyTo(db, 1) + Upgrade2To3(context).applyTo(db, 2) + Upgrade3To4().applyTo(db, 3) + Upgrade4To5().applyTo(db, 4) + Upgrade5To6().applyTo(db, 5) + Upgrade6To7().applyTo(db, 6) + Upgrade7To8().applyTo(db, 7) + Upgrade8To9(sharedPreferencesHandler).applyTo(db, 8) + Upgrade9To10(sharedPreferencesHandler).applyTo(db, 9) + Upgrade10To11().applyTo(db, 10) + + sharedPreferencesHandler.setUpdateIntervalInDays(Optional.absent()) + + Upgrade11To12(sharedPreferencesHandler).applyTo(db, 11) + + Assert.assertThat(sharedPreferencesHandler.updateIntervalInDays(), CoreMatchers.`is`(Optional.absent())) + } } 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 77239abe..63566c5b 100644 --- a/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java +++ b/data/src/main/java/org/cryptomator/data/db/DatabaseUpgrades.java @@ -29,7 +29,8 @@ class DatabaseUpgrades { Upgrade7To8 upgrade7To8, // Upgrade8To9 upgrade8To9, // Upgrade9To10 upgrade9To10, // - Upgrade10To11 upgrade10To11 + Upgrade10To11 upgrade10To11, // + Upgrade11To12 upgrade11To12 ) { availableUpgrades = defineUpgrades( // @@ -43,7 +44,8 @@ class DatabaseUpgrades { upgrade7To8, // upgrade8To9, // upgrade9To10, // - upgrade10To11); + upgrade10To11, // + upgrade11To12); } private Map> defineUpgrades(DatabaseUpgrade... upgrades) { diff --git a/data/src/main/java/org/cryptomator/data/db/Upgrade11To12.kt b/data/src/main/java/org/cryptomator/data/db/Upgrade11To12.kt new file mode 100644 index 00000000..2ec84644 --- /dev/null +++ b/data/src/main/java/org/cryptomator/data/db/Upgrade11To12.kt @@ -0,0 +1,17 @@ +package org.cryptomator.data.db + +import com.google.common.base.Optional +import org.cryptomator.util.SharedPreferencesHandler +import org.greenrobot.greendao.database.Database +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +internal class Upgrade11To12 @Inject constructor(private val sharedPreferencesHandler: SharedPreferencesHandler) : DatabaseUpgrade(11, 12) { + + override fun internalApplyTo(db: Database, origin: Int) { + when (sharedPreferencesHandler.updateIntervalInDays()) { + Optional.of(7), Optional.of(30) -> sharedPreferencesHandler.setUpdateIntervalInDays(Optional.of(1)) + } + } +} diff --git a/fastlane/izzyscript/result_apkstore.json b/fastlane/izzyscript/result_apkstore.json index 8092c119..aa1e5e29 100644 --- a/fastlane/izzyscript/result_apkstore.json +++ b/fastlane/izzyscript/result_apkstore.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
Androidx Fragment/androidx/fragment/appDevelopment AidApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeDep
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment/app","name":"Androidx Fragment","typ":"Development Aid","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeDep","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2869 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 48597 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 78 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeDep
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeDep","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2918 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 48677 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 90 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/izzyscript/result_fdroid.json b/fastlane/izzyscript/result_fdroid.json index 352cb380..590d888c 100644 --- a/fastlane/izzyscript/result_fdroid.json +++ b/fastlane/izzyscript/result_fdroid.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n4 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
Androidx Fragment/androidx/fragment/appDevelopment AidApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment/app","name":"Androidx Fragment","typ":"Development Aid","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2845 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 43607 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 73 libraries, 4 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n4 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2918 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 43741 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 85 libraries, 4 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/izzyscript/result_playstore.json b/fastlane/izzyscript/result_playstore.json index 8092c119..aa1e5e29 100644 --- a/fastlane/izzyscript/result_playstore.json +++ b/fastlane/izzyscript/result_playstore.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
Androidx Fragment/androidx/fragment/appDevelopment AidApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeDep
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment/app","name":"Androidx Fragment","typ":"Development Aid","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeDep","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2869 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 48597 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 78 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeDep
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
Java JWT/io/jsonwebtokenUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
Netty Project/io/nettyDevelopment FrameworkApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Kotlin/kotlinUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSON in Java/org/jsonUtilityMIT
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeDep","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/jsonwebtoken","name":"Java JWT","typ":"Utility","anti":"","url":"https://github.com/jwtk/jjwt","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/netty","name":"Netty Project","typ":"Development Framework","anti":"","url":"https://github.com/netty/netty","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/json","name":"JSON in Java","typ":"Utility","anti":"","url":"https://github.com/stleary/JSON-java","license":"MIT"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 2918 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 48677 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 90 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/metadata/android/de-DE/changelogs/default.txt b/fastlane/metadata/android/de-DE/changelogs/default.txt index c54251b8..69477f19 100644 --- a/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1,3 @@ -- Fehler beim Zugriff auf Dateien wenn eine Verbindung neu hinzugefügt wurde behoben \ No newline at end of file +- Update auf die neueste Android-Zielplatform-Version +- Löschen von Ordnern ohne Verzeichnisdatei im lokalen Cloud-Speicher behoben +- Dateiexport wenn keine App den ausgewählten Dateityp verarbeiten kann behoben \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/default.txt b/fastlane/metadata/android/en-US/changelogs/default.txt index 0704573a..dd0e4e3b 100644 --- a/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1 +1,3 @@ -- Fixed wrong access to files when a connection has been re-added \ No newline at end of file +- Updated to the latest Android target version +- Fixed deletion of folders without a dir-file in local storage cloud +- Fixed file export when no app can process the selected file type \ No newline at end of file diff --git a/fastlane/release-notes.html b/fastlane/release-notes.html index ae897a0f..2fb6da68 100644 --- a/fastlane/release-notes.html +++ b/fastlane/release-notes.html @@ -1,3 +1,5 @@ \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a25..2e6e5897 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/lib/google-http-client-1.41.8-sources.jar b/lib/google-http-client-1.41.8-sources.jar new file mode 100644 index 00000000..5e16fb0f Binary files /dev/null and b/lib/google-http-client-1.41.8-sources.jar differ diff --git a/lib/google-http-client-1.41.5.jar b/lib/google-http-client-1.41.8.jar similarity index 84% rename from lib/google-http-client-1.41.5.jar rename to lib/google-http-client-1.41.8.jar index ba559042..60408480 100644 Binary files a/lib/google-http-client-1.41.5.jar and b/lib/google-http-client-1.41.8.jar differ diff --git a/lib/google-http-client-android-1.41.8-sources.jar b/lib/google-http-client-android-1.41.8-sources.jar new file mode 100644 index 00000000..c80980c4 Binary files /dev/null and b/lib/google-http-client-android-1.41.8-sources.jar differ diff --git a/lib/google-http-client-android-1.41.5.jar b/lib/google-http-client-android-1.41.8.jar similarity index 77% rename from lib/google-http-client-android-1.41.5.jar rename to lib/google-http-client-android-1.41.8.jar index 8155cb61..605afc84 100644 Binary files a/lib/google-http-client-android-1.41.5.jar and b/lib/google-http-client-android-1.41.8.jar differ diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java deleted file mode 100644 index e2400dc6..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudContentRepositoryBlackboxTest.java +++ /dev/null @@ -1,422 +0,0 @@ -package org.cryptomator.presentation; - -import androidx.test.rule.ActivityTestRule; - -import org.cryptomator.data.cloud.local.file.RootLocalFolder; -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.CloudFile; -import org.cryptomator.domain.CloudFolder; -import org.cryptomator.domain.CloudNode; -import org.cryptomator.domain.CloudType; -import org.cryptomator.domain.LocalStorageCloud; -import org.cryptomator.domain.exception.BackendException; -import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException; -import org.cryptomator.domain.repository.CloudContentRepository; -import org.cryptomator.domain.usecases.ProgressAware; -import org.cryptomator.domain.usecases.cloud.ByteArrayDataSource; -import org.cryptomator.presentation.di.component.ApplicationComponent; -import org.cryptomator.presentation.testCloud.CryptoTestCloud; -import org.cryptomator.presentation.testCloud.DropboxTestCloud; -import org.cryptomator.presentation.testCloud.GoogledriveTestCloud; -import org.cryptomator.presentation.testCloud.LocalStorageTestCloud; -import org.cryptomator.presentation.testCloud.LocalTestCloud; -import org.cryptomator.presentation.testCloud.OnedriveTestCloud; -import org.cryptomator.presentation.testCloud.TestCloud; -import org.cryptomator.presentation.testCloud.WebdavTestCloud; -import org.cryptomator.presentation.ui.activity.SplashActivity; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.ByteArrayOutputStream; -import java.util.Date; -import java.util.List; -import java.util.UUID; - -import static androidx.test.InstrumentationRegistry.getTargetContext; -import static org.cryptomator.presentation.CloudNodeMatchers.aFile; -import static org.cryptomator.presentation.CloudNodeMatchers.folder; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.collection.IsEmptyCollection.emptyCollectionOf; - -@RunWith(Parameterized.class) -public class CloudContentRepositoryBlackboxTest { - - private static final byte[] DIGITS_ONE_TO_TEN_AS_BYTES = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - private static final byte[] DIGITS_SEVEN_TO_ONE_AS_BYTES = new byte[] {7, 6, 5, 4, 3, 2, 1}; - - 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; - - public CloudContentRepositoryBlackboxTest(TestCloud testCloud) { - if (inTestCloud != null && inTestCloud != testCloud) { - setupCloudCompleted = false; - } - - inTestCloud = testCloud; - } - - @Parameterized.Parameters(name = "{0}") - public static TestCloud[] data() { - return new TestCloud[] { // - new LocalStorageTestCloud(), // - new LocalTestCloud(), // - new WebdavTestCloud(getTargetContext()), // - new DropboxTestCloud(getTargetContext()), // - new GoogledriveTestCloud(), // - new OnedriveTestCloud(getTargetContext()), // - new CryptoTestCloud()}; - } - - @Before - public void setup() throws BackendException { - - ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule // - .getActivity() // - .getApplication()) // - .getComponent(); - - if (!setupCloudCompleted) { - if (inTestCloud instanceof CryptoTestCloud) { - // FIXME 343 @julian just for testcase local cloud - Cloud testCloud = appComponent.cloudRepository().clouds(CloudType.LOCAL).get(0); - CloudFolder rootFolder = new RootLocalFolder((LocalStorageCloud) testCloud); - cloud = ((CryptoTestCloud) inTestCloud).getInstance(appComponent, testCloud, rootFolder); - } else { - cloud = inTestCloud.getInstance(appComponent); - } - - setupCloudCompleted = true; - } - - inTest = appComponent.cloudContentRepository(); - root = inTest.create(inTest.resolve(cloud, UUID.randomUUID().toString())); - } - - @Test - public void testListEmptyDirectory() throws BackendException { - assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class))); - } - - @Test - public void testListDirectory() throws BackendException { - createParentsAndWrite("a", DIGITS_SEVEN_TO_ONE_AS_BYTES); - createParentsAndWrite("b.dat", DIGITS_ONE_TO_TEN_AS_BYTES); - createParentsAndWrite("empty.txt", new byte[0]); - inTest.create(inTest.folder(root, "b")); - inTest.create(inTest.folder(root, "c")); - - assertThat(listingOf(root), containsInAnyOrder( // - aFile().withName("a").withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length), // - aFile().withName("b.dat").withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length), // - aFile().withName("empty.txt").withSize(0L), // - folder("b"), // - folder("c"))); - } - - @Test - public void testCreateDirectory() throws BackendException { - CloudFolder created = inTest.folder(root, "created"); - created = inTest.create(created); - - assertThat(listingOf(created), is(emptyCollectionOf(CloudNode.class))); - assertThat(listingOf(root), containsInAnyOrder(folder("created"))); - } - - @Test - public void testDeleteDirectory() throws BackendException { - inTest.create(inTest.folder(root, "created")); - inTest.delete(inTest.folder(root, "created")); - - assertThat(inTest.exists(inTest.folder(root, "created")), is(false)); - assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class))); - } - - @Test - @SuppressWarnings("deprecation") - public void testUploadFile() throws BackendException { - Date start = new Date(); - CloudFile file = createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - - assertThat(file, is(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length) // - .withModifiedIn(start, new Date()))); - assertThat(listingOf(root), // - containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - } - - @Test - @SuppressWarnings("deprecation") - public void testReplaceFile() throws BackendException { - createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - Date start = new Date(); - CloudFile file = createParentsAndWriteOrReplace("file", DIGITS_SEVEN_TO_ONE_AS_BYTES); - - assertThat(file, is(aFile() // - .withName("file") // - .withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length) // - .withModifiedIn(start, new Date()))); - assertThat(listingOf(root), // - containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length))); - } - - @Test - public void testUploadExistingFileWithoutReplaceFlag() throws BackendException { - createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("CloudNode already exists and replace is false"); - - createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - } - - @Test - public void testDownloadFile() throws BackendException { - createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - - assertThat(read(inTest.file(root, "file")), is(DIGITS_ONE_TO_TEN_AS_BYTES)); - } - - @Test - public void testDeleteFile() throws BackendException { - createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES); - inTest.delete(inTest.file(root, "file")); - - assertThat(inTest.exists(inTest.file(root, "file")), is(false)); - assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class))); - } - - @Test - @SuppressWarnings("deprecation") - public void testRenameDirectory() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder target = inTest.folder(root, "newName"); - - target = inTest.move(directory, target); - - assertThat(listingOf(target), containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - } - - @Test - public void testRenameDirectoryToExistingDirectory() throws BackendException { - CloudFolder directory = inTest.folder(root, "directory"); - directory = inTest.create(directory); - CloudFolder target = inTest.folder(root, "newName"); - target = inTest.create(target); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("newName"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testRenameDirectoryToExistingFile() throws BackendException { - CloudFolder directory = inTest.folder(root, "directory"); - directory = inTest.create(directory); - CloudFolder target = inTest.folder(root, "newName"); - createParentsAndWrite("newName", new byte[0]); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("newName"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveDirectory() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "directory"); - - target = inTest.move(directory, target); - - assertThat(listingOf(target), containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveDirectoryToExistingDirectory() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "directory"); - target = inTest.create(target); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("directory"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveDirectoryToExistingFile() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "directory"); - createParentsAndWrite("newParent/directory", new byte[0]); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("directory"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveAndRenameDirectory() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "newName"); - - target = inTest.move(directory, target); - - assertThat(listingOf(target), containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveAndRenameDirectoryToExistingDirectory() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "newName"); - target = inTest.create(target); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("newName"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveAndRenameDirectoryToExistingFile() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder directory = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFolder target = inTest.folder(newParent, "newName"); - createParentsAndWrite("newParent/newName", new byte[0]); - - thrown.expect(CloudNodeAlreadyExistsException.class); - thrown.expectMessage("newName"); - - inTest.move(directory, target); - } - - @Test - @SuppressWarnings("deprecation") - public void testRenameFile() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFile target = inTest.file(file.getParent(), "newName"); - - target = inTest.move(file, target); - - assertThat(listingOf(file.getParent()), containsInAnyOrder(aFile() // - .withName("newName") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES)); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveFile() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder oldParent = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFile target = inTest.file(newParent, "file"); - - target = inTest.move(file, target); - - assertThat(listingOf(oldParent), is(emptyCollectionOf(CloudNode.class))); - assertThat(listingOf(newParent), containsInAnyOrder(aFile() // - .withName("file") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES)); - } - - @Test - @SuppressWarnings("deprecation") - public void testMoveAndRenameFile() throws BackendException { - CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES); - CloudFolder oldParent = file.getParent(); - CloudFolder newParent = inTest.create(inTest.folder(root, "newParent")); - CloudFile target = inTest.file(newParent, "newName"); - - target = inTest.move(file, target); - - assertThat(listingOf(oldParent), is(emptyCollectionOf(CloudNode.class))); - assertThat(listingOf(newParent), containsInAnyOrder(aFile() // - .withName("newName") // - .withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length))); - assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES)); - } - - @After - public void teardown() throws BackendException { - if (inTest != null && root != null) { - inTest.delete(root); - } - } - - private List listingOf(CloudFolder testRoot) throws BackendException { - return inTest.list(testRoot); - } - - private byte[] read(CloudFile file) throws BackendException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - inTest.read(file, null, out, ProgressAware.NO_OP_PROGRESS_AWARE_DOWNLOAD); - return out.toByteArray(); - } - - private CloudFile createParentsAndWrite(String path, byte[] data) throws BackendException { - return createParentsAndWriteOrReplaceImpl(path, data, false); - } - - private CloudFile createParentsAndWriteOrReplace(String path, byte[] data) throws BackendException { - return createParentsAndWriteOrReplaceImpl(path, data, true); - } - - private CloudFile createParentsAndWriteOrReplaceImpl(String path, byte[] data, boolean repalce) throws BackendException { - path = root.getName() + "/" + path; - String pathToParent = path.substring(0, path.lastIndexOf('/') + 1); - String name = path.substring(path.lastIndexOf('/') + 1); - CloudFolder parent = inTest.resolve(cloud, pathToParent); - if (!inTest.exists(parent)) { - parent = inTest.create(parent); - } - CloudFile file = inTest.file(parent, name, new Long(data.length)); - return inTest.write(file, ByteArrayDataSource.from(data), ProgressAware.NO_OP_PROGRESS_AWARE_UPLOAD, repalce, data.length); - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java b/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java deleted file mode 100644 index 9557d5f0..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/CloudNodeMatchers.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.cryptomator.presentation; - -import org.cryptomator.domain.CloudFile; -import org.cryptomator.domain.CloudFolder; -import org.cryptomator.domain.CloudNode; -import com.google.common.base.Optional; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeDiagnosingMatcher; - -import java.util.Date; - -class CloudNodeMatchers { - - public static Matcher aFile(final String name) { - return (Matcher) new TypeSafeDiagnosingMatcher() { - @Override - protected boolean matchesSafely(CloudFile file, Description description) { - if (name.equals(file.getName())) { - return true; - } else { - description.appendText("aFile with name '").appendText(file.getName()).appendText("'"); - return false; - } - } - - @Override - public void describeTo(Description description) { - description.appendText("aFile with name '").appendText(name).appendText("'"); - } - }; - } - - public static FileMatcher aFile() { - 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; - private Optional sizeToCheck; - - private Date minModifiedToCheck; - private Date maxModifiedToCheck; - - private FileMatcher() { - super(CloudFile.class); - } - - public FileMatcher withName(String name) { - this.nameToCheck = name; - return this; - } - - public FileMatcher withSize(int size) { - return withSize(Long.valueOf(size)); - } - - public FileMatcher withSize(Long size) { - this.sizeToCheck = Optional.ofNullable(size); - return this; - } - - public FileMatcher withModifiedIn(Date minModified, Date maxModified) { - this.minModifiedToCheck = minModified; - this.maxModifiedToCheck = maxModified; - return this; - } - - @Override - public void describeTo(Description description) { - description.appendText("a file"); - if (nameToCheck != null) { - description.appendText(" with name ").appendText(nameToCheck); - } - if (sizeToCheck != null) { - description.appendText(" with size ").appendValue(sizeToCheck); - } - if (minModifiedToCheck != null) { - description.appendText(" with modified in [").appendValue(minModifiedToCheck).appendText(",").appendValue(maxModifiedToCheck).appendText("]"); - } - } - - @Override - protected boolean matchesSafely(CloudNode cloudNode, Description description) { - CloudFile cloudFile = (CloudFile) cloudNode; - boolean match = true; - description.appendText("a file"); - if (nameToCheck != null && !nameToCheck.equals(cloudFile.getName())) { - description.appendText(" with name ").appendText(cloudFile.getName()); - match = false; - } - if (sizeToCheck != null && !sizeToCheck.equals(cloudFile.getSize())) { - description.appendText(" with size ").appendValue(cloudFile.getSize()); - match = false; - } - if (minModifiedToCheck != null && dateInRange(minModifiedToCheck, maxModifiedToCheck, cloudFile.getModified())) { - description.appendText(" with modified ").appendValue(cloudFile.getModified()); - } - return match; - } - - private boolean dateInRange(Date min, Date max, Optional modified) { - return modified.isPresent() && !modified.get().before(min) && !modified.get().after(max); - } - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/CryptoTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/CryptoTestCloud.java deleted file mode 100644 index 7848c3c5..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/CryptoTestCloud.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.CloudFolder; -import org.cryptomator.domain.Vault; -import org.cryptomator.domain.exception.BackendException; -import org.cryptomator.domain.exception.FatalBackendException; -import org.cryptomator.presentation.di.component.ApplicationComponent; - -import static org.cryptomator.domain.Vault.aVault; - -public class CryptoTestCloud extends TestCloud { - - private final static String VAULT_PASSWORD = "password"; - private final static String VAULT_NAME = "testVault"; - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - throw new IllegalStateException(); - } - - public Cloud getInstance(ApplicationComponent appComponent, Cloud testCloud, CloudFolder rootFolder) { - try { - CloudFolder vaultFolder = appComponent // - .cloudContentRepository() // - .folder(rootFolder, VAULT_NAME); - - Vault vault = aVault() // - .thatIsNew() // - .withCloud(testCloud) // - .withNamePathAndCloudFrom(vaultFolder) // - .build(); - - cleanup(appComponent, vault, vaultFolder); - - vaultFolder = appComponent.cloudContentRepository().create(vaultFolder); - appComponent.cloudRepository().create(vaultFolder, VAULT_PASSWORD); - vault = appComponent.vaultRepository().store(vault); - - return appComponent.cloudRepository().unlock(vault, VAULT_PASSWORD, () -> false); - } catch (BackendException e) { - throw new AssertionError(e); - } - } - - private void cleanup(ApplicationComponent appComponent, Vault vault, CloudFolder vaultFolder) { - try { - appComponent.cloudContentRepository().delete(vaultFolder); - } catch (BackendException | FatalBackendException e) { - } - - try { - appComponent.vaultRepository().vaults().forEach(vaultInRepo -> { - if (vaultInRepo.getName().equals(vault.getName()) // - && vaultInRepo.getPath().equals(vault.getPath())) { - try { - appComponent.vaultRepository().delete(vaultInRepo); - } catch (BackendException e) { - throw new AssertionError(e); - } - } - }); - } catch (FatalBackendException | BackendException e) { - } - } - - @Override - public String toString() { - return "CryptoTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java deleted file mode 100644 index 663e5bb7..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/DropboxTestCloud.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import android.content.Context; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.WebDavCloud; -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) { - this.context = context; - } - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - return WebDavCloud.aWebDavCloudCloud() // - .withUrl("https://webdav.mc.gmx.net") // - .withUsername("jraufelder@gmx.de") // - .withPassword(CredentialCryptor.getInstance(context).encrypt("mG7!3B3Mx")) // - .build(); - } - - @Override - public String toString() { - return "DropboxTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java deleted file mode 100644 index 1aaa37b6..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/GoogledriveTestCloud.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import androidx.test.InstrumentationRegistry; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; - -import junit.framework.AssertionFailedError; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.GoogleDriveCloud; -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.di.component.ApplicationComponent; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; -import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.checkLoginResult; -import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.openCloudServices; - -public class GoogledriveTestCloud extends TestCloud { - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - login(); - return GoogleDriveCloud.aGoogleDriveCloud() // - .withUsername("geselthyn@googlemail.com") // - .withAccessToken("geselthyn@googlemail.com") // - .build(); - } - - public void login() { - UiDevice device = UiDevice.getInstance(getInstrumentation()); - - openCloudServices(device); - - if (alreadyLoggedIn()) { - return; - } - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(GOOGLE_DRIVE, click())); - - try { - device // - .findObject(new UiSelector().resourceId("android:id/text1")) // - .click(); - - device // - .findObject(new UiSelector().resourceId("android:id/button1")) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("GoogleDrive login failed"); - } - - device.waitForIdle(); - - checkLoginResult("Google Drive", GOOGLE_DRIVE); - } - - private boolean alreadyLoggedIn() { - 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"))); - } catch (AssertionFailedError e) { - return false; - } - - return true; - - } - - @Override - public String toString() { - return "GoogledriveTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java deleted file mode 100644 index 8e7ae7b4..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalStorageTestCloud.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import androidx.test.uiautomator.UiDevice; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.CloudType; -import org.cryptomator.domain.LocalStorageCloud; -import org.cryptomator.domain.exception.BackendException; -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.di.component.ApplicationComponent; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.LOCAL; -import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard; -import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.openCloudServices; -import static org.cryptomator.presentation.ui.activity.LoginLocalClouds.chooseFolder; - -public class LocalStorageTestCloud extends TestCloud { - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - login(); - try { - return appComponent.cloudRepository() // - .clouds(CloudType.LOCAL).stream() // - .map(LocalStorageCloud.class::cast) // - .filter(cloud -> cloud.rootUri() != null) // - .findFirst() // - .get(); - } catch (BackendException e) { - throw new RuntimeException(e); - } - } - - private void login() { - UiDevice device = UiDevice.getInstance(getInstrumentation()); - - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(LOCAL, click())); - awaitCompleted(); - - onView(withId(R.id.floating_action_button)) // - .perform(click()); - awaitCompleted(); - - chooseSdCard(device); - awaitCompleted(); - - chooseFolder(device); - } - - @Override - public String toString() { - return "LocalStorageTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java deleted file mode 100644 index 4d57b3a3..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/LocalTestCloud.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.LocalStorageCloud; -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() // - .getUiAutomation() // - .executeShellCommand("pm grant " + "org.cryptomator" + " android.permission.READ_EXTERNAL_STORAGE"); - - getInstrumentation() // - .getUiAutomation() // - .executeShellCommand("pm grant " + "org.cryptomator" + " android.permission.WRITE_EXTERNAL_STORAGE"); - - return LocalStorageCloud.aLocalStorage().build(); - } - - @Override - public String toString() { - return "LocalTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java deleted file mode 100644 index bf80def9..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/OnedriveTestCloud.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import android.content.Context; -import android.content.SharedPreferences; - -import org.cryptomator.domain.Cloud; -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) { - this.context = context; - } - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - SharedPreferences sharedPreferences = context.getSharedPreferences("com.microsoft.live", 0); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString("refresh_token", "OAQABAAAAAABHh4kmS_aKT5XrjzxRAtHzMkxzFfIzutF8Q04IwuU77Vmp5-ErO6muS0-watCiLjvPG" + // - "-QICK6PwzSsJZApKZPIyTgDxJuElkhM9j9Caa-NGXKx3JPZx4Tk5X3zhmSWebZdQu2TM1N" + // - "RrKWLl2k2m3Zj7xr1zEsjcr4tUjjrZl_W6EIglAIoi-DPOwznIEDWAzWCJeUY76CIpywax" + // - "RTsbcZXD3u2321kIGaL-bnGLa_z5IzUbal0PcYfPNYPXXTuv8eMyl4L9Tls1tSEseTHgCu" + // - "X3OZU2owiGQk6ycDAeyrbRaPoUOA78GYuaJGUXRmhAeH1WBccUzABdrZmAY1dAt4yu2eV7" + // - "70RzrDQhbLCPV3u3x-7xEtvsM8w0W7096VBuu2-MXvaWuDccnCHo_PK8ketpow19_llBI9" + // - "fx7yBnIU-HCkKuvOCKcvVq3Bv9r312bwAoWHdOrxsKrNK8aLoR317O9Cxjpr7q-YI3NSJJ" + // - "veTK_vn2uE0e6gppGOYSmpJIvoW82ZVngpptW0jsp6rOsnkSg2yfKKpIPN-n0U1njVlYf8" + // - "cwsS99tx8NDdCPS6MTkVmcdKRJ4dhMuuWdEm4E_hZRnnj2Pya3APxjL2eqyAR1-54TDLF-" + // - "-L-jIJUS4bVpC_RBQn4fxcrX4s-ddo6I0ejfdC07mU_Np9p66VJ_3_Yokt64fFw-zzaGpn" + // - "QEzRMxtJp5G40MAelYwxLhDIc-syw91JEoSSqfGJYHETKExPlnQOw-rqLGPFbIF6OKFNqO" + // - "XtVLWKZFxIEf-EFQbhq5igZz8DZ2n-cRxC3HWi_x18tVSAA"); - editor.commit(); - - return OnedriveCloud.aOnedriveCloud() // - .withUsername("info@cryptomator.org") // - .withAccessToken("authenticated") // - .build(); - } - - @Override - public String toString() { - return "OnedriveTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java b/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java deleted file mode 100644 index 76f6fc55..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/TestCloud.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -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 deleted file mode 100644 index 6abb564e..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/testCloud/WebdavTestCloud.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.cryptomator.presentation.testCloud; - -import android.content.Context; - -import org.cryptomator.domain.Cloud; -import org.cryptomator.domain.WebDavCloud; -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) { - this.context = context; - } - - @Override - public Cloud getInstance(ApplicationComponent appComponent) { - return WebDavCloud.aWebDavCloudCloud() // - .withUrl("https://webdav.mc.gmx.net") // - .withUsername("jraufelder@gmx.de") // - .withPassword(CredentialCryptor.getInstance(context).encrypt("mG7!3B3Mx")) // - .build(); - } - - @Override - public String toString() { - return "WebdavTestCloud"; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java deleted file mode 100644 index a9369781..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/RecyclerViewMatcher.java +++ /dev/null @@ -1,65 +0,0 @@ -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; - -/** - * Created by dannyroa on 5/10/15. - */ -public class RecyclerViewMatcher { - - private final int recyclerViewId; - - public RecyclerViewMatcher(int recyclerViewId) { - this.recyclerViewId = recyclerViewId; - } - - public Matcher atPositionOnView(final int position, final int targetViewId) { - - return new TypeSafeMatcher() { - Resources resources = null; - View childView; - - public void describeTo(Description description) { - String idDescription = Integer.toString(recyclerViewId); - if (this.resources != null) { - try { - idDescription = this.resources.getResourceName(recyclerViewId); - } catch (Resources.NotFoundException var4) { - idDescription = String.format("%s (resource name not found)", recyclerViewId); - } - } - - description.appendText("with id: " + idDescription); - } - - public boolean matchesSafely(View view) { - - this.resources = view.getResources(); - - if (childView == null) { - RecyclerView recyclerView = view.getRootView().findViewById(recyclerViewId); - if (recyclerView != null && recyclerView.getId() == recyclerViewId) { - childView = recyclerView.findViewHolderForAdapterPosition(position).itemView; - } else { - return false; - } - } - - if (targetViewId == -1) { - return view == childView; - } else { - View targetView = childView.findViewById(targetViewId); - return view == targetView; - } - - } - }; - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java deleted file mode 100644 index 964e60c7..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/TestUtil.java +++ /dev/null @@ -1,179 +0,0 @@ -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; -import org.cryptomator.domain.CloudType; -import org.cryptomator.domain.Vault; -import org.cryptomator.domain.exception.BackendException; -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.di.component.ApplicationComponent; -import org.hamcrest.Matchers; - -import java.util.List; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.RootMatchers.withDecorView; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withParent; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.not; -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; - public static final int WEBDAV = 3; - public static final int LOCAL = 4; - - private static final String SD_CARD_REGEX = "(?i)SD[- ]*(CARD|KARTE)"; - - public static void isToastDisplayed(String message, ActivityTestRule activityTestRule) { - onView(withText(message)) // - .inRoot(withDecorView(not(is(activityTestRule.getActivity().getWindow().getDecorView())))) // - .check(matches(isDisplayed())); - } - - public static void openMenu(UiDevice device) { - try { - final UiSelector toolbar = new UiSelector() // - .resourceId("com.android.documentsui:id/toolbar"); - - device // - .findObject(toolbar.childSelector(new UiSelector().index(0))) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Menu not found"); - } - } - - public static void chooseSdCard(UiDevice device) { - try { - if (!sdCardAlreadySelected()) { - openMenu(device); - - device // - .findObject(new UiSelector().textMatches(SD_CARD_REGEX)) // - .click(); - } - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Menu not found"); - } - } - - private static boolean sdCardAlreadySelected() { - ViewInteraction textView = onView(allOf(withText("SDCARD"), withParent(withId(R.id.toolbar)), isDisplayed())); - return textView.check(matches(withText("SDCARD"))) != null; - } - - public static void openSettings(UiDevice device) { - awaitCompleted(); - - waitForIdle(device); - - openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); - - waitForIdle(device); - - onView(allOf( // - withId(R.id.title), // - withText(R.string.snack_bar_action_title_settings))) // - .perform(click()); - - awaitCompleted(); - - } - - public static void waitForIdle(UiDevice uiDevice) { - uiDevice.waitForIdle(); - } - - public static void addFolderInCloud(ApplicationComponent appComponent, String path, CloudType cloudType) { - try { - CloudFolder vaultFolder = (CloudFolder) getNode(appComponent, getEncryptedCloud(appComponent, cloudType), path); - - if (!appComponent.cloudContentRepository().exists(vaultFolder)) { - assertThat(appComponent.cloudContentRepository().create(vaultFolder), Matchers.is(notNullValue())); - } - } catch (BackendException e) { - throw new AssertionError("Error while adding testVault"); - } - } - - public static void removeFolderInCloud(ApplicationComponent appComponent, String path, CloudType cloudType) { - try { - CloudFolder vaultFolder = (CloudFolder) getNode(appComponent, getEncryptedCloud(appComponent, cloudType), path); - - if (appComponent.cloudContentRepository().exists(vaultFolder)) { - appComponent.cloudContentRepository().delete(vaultFolder); - } - } catch (BackendException e) { - throw new AssertionError("Error while removing testVault"); - } - } - - private static Cloud getEncryptedCloud(ApplicationComponent appComponent, CloudType cloudType) throws BackendException { - Cloud cloud; - if (cloudType.equals(CloudType.LOCAL)) { - cloud = appComponent.cloudRepository().clouds(cloudType).get(1); - } else { - cloud = appComponent.cloudRepository().clouds(cloudType).get(0); - } - - return cloud; - } - - private static CloudNode getNode(ApplicationComponent appComponent, Cloud cloud, String path) throws BackendException { - return appComponent.cloudContentRepository().resolve(cloud, path); - } - - public static void removeFolderInVault(ApplicationComponent appComponent, String name, CloudType cloudType) { - try { - Cloud decryptedCloud = getDecryptedCloud(appComponent, cloudType); - CloudFolder root = appComponent.cloudContentRepository().root(decryptedCloud); - CloudFolder folder = appComponent.cloudContentRepository().folder(root, name); - appComponent.cloudContentRepository().delete(folder); - } catch (BackendException e) { - throw new AssertionError(e); - } - } - - public static void addFolderInVaultsRoot(ApplicationComponent appComponent, String name, CloudType cloudType) { - try { - Cloud decryptedCloud = getDecryptedCloud(appComponent, cloudType); - CloudFolder root = appComponent.cloudContentRepository().root(decryptedCloud); - CloudFolder folder = appComponent.cloudContentRepository().folder(root, name); - assertThat(appComponent.cloudContentRepository().create(folder), is(notNullValue())); - } catch (BackendException e) { - throw new AssertionError(e); - } - } - - private static Cloud getDecryptedCloud(ApplicationComponent appComponent, CloudType cloudType) throws BackendException { - List vaults = appComponent.vaultRepository().vaults(); - for (Vault vault : vaults) { - if (vault.getCloudType().equals(cloudType)) { - return appComponent.cloudRepository().decryptedViewOf(vault); - } - } - - throw new AssertionError("Cloud for vault not found"); - } -} 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 deleted file mode 100644 index d4a8f792..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/BasicNodeOperationsUtil.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import androidx.test.InstrumentationRegistry; -import androidx.test.uiautomator.UiDevice; - -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.ui.RecyclerViewMatcher; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static java.lang.String.format; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.hamcrest.Matchers.allOf; - -public class BasicNodeOperationsUtil { - - static void openSettings(UiDevice device, int nodePosition) { - awaitCompleted(); - - waitForIdle(device); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.settings)) // - .perform(click()); - - awaitCompleted(); - } - - static void waitForIdle(UiDevice uiDevice) { - uiDevice.waitForIdle(); - } - - static void checkEmptyFolderHint() { - awaitCompleted(); - - 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))); - } - - static void checkFileOrFolderAlreadyExistsErrorMessage(String nodeName) { - onView(withId(R.id.tv_error)) // - .check(matches(withText(format( // - InstrumentationRegistry // - .getTargetContext() // - .getString(R.string.error_file_or_folder_exists), // - nodeName)))); - } - - public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) { - return new RecyclerViewMatcher(recyclerViewId); - } -} 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 deleted file mode 100644 index dc0ad8d5..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/CloudsOperationsTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; - -import androidx.test.InstrumentationRegistry; -import androidx.test.espresso.ViewInteraction; -import androidx.test.espresso.contrib.RecyclerViewActions; -import androidx.test.rule.ActivityTestRule; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiScrollable; -import androidx.test.uiautomator.UiSelector; - -import org.cryptomator.presentation.R; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeMatcher; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static androidx.test.espresso.matcher.ViewMatchers.withChild; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static java.lang.Thread.sleep; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.DROPBOX; -import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE; -import static org.cryptomator.presentation.ui.TestUtil.LOCAL; -import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE; -import static org.cryptomator.presentation.ui.TestUtil.WEBDAV; -import static org.cryptomator.presentation.ui.TestUtil.openSettings; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; -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); - - 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() { - openSettings(device); - - try { - new UiScrollable(new UiSelector().scrollable(true)).scrollToEnd(10); - - awaitCompleted(); - - onView(withChild(withText(R.string.screen_settings_debug_mode_label))) // - .perform(click()); - - awaitCompleted(); - - onView(withId(android.R.id.button1)) // - .perform(click()); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Scrolling down failed"); - } - } - - @Test - public void test02LoginDropboxCloudLeadsToLoggedInDropboxCloud() { - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(DROPBOX, click())); - - try { - device // - .findObject(new UiSelector().resourceId("android:id/button_once")) // - .click(); - - device.waitForIdle(); - - device // - .findObject(new UiSelector().text("Email")) // - .setText(""); - - device // - .findObject(new UiSelector().text("Password")) // - .setText(""); - - device // - .findObject(new UiSelector().description("Sign in")) // - .click(); - - device.waitForIdle(); - - device // - .findObject(new UiSelector().description("Allow")) // - .click(); - - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Dropbox login failed"); - } - - device.waitForIdle(); - - checkLoginResult("Dropbox", DROPBOX); - } - - @Test - public void test03LoginGoogleDriveCloudLeadsToLoggedInGoogleDriveCloud() { - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(GOOGLE_DRIVE, click())); - - try { - device // - .findObject(new UiSelector().resourceId("android:id/text1")) // - .click(); - - device // - .findObject(new UiSelector().resourceId("android:id/button1")) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("GoogleDrive login failed"); - } - - device.waitForIdle(); - - checkLoginResult("Google Drive", GOOGLE_DRIVE); - } - - @Test - public void test04LoginOneDriveLeadsToLoggedInOneDriveCloud() { - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(ONEDRIVE, click())); - - try { - try { - sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - device // - .findObject(new UiSelector().resourceId("i0116")) // - .setText(""); - - device // - .findObject(new UiSelector().resourceId("idSIButton9")) // - .click(); - - device.waitForWindowUpdate(null, 500); - - device // - .findObject(new UiSelector().resourceId("i0118")) // - .setText(""); - - device.waitForWindowUpdate(null, 500); - - device // - .findObject(new UiSelector().resourceId("idSIButton9")) // - .click(); - - try { - device // - .findObject(new UiSelector().resourceId("idSIButton9")) // - .click(); - } catch (UiObjectNotFoundException e) { - // Do nothing because second click is normaly not necessary - } - } catch (UiObjectNotFoundException e) { - throw new AssertionError("OneDrive login failed"); - } - - awaitCompleted(); - - checkLoginResult("OneDrive", ONEDRIVE); - } - - @Test - public void test05LoginWebdavCloudLeadsToLoggedInWebdavCloud() { - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(WEBDAV, click())); - - LoginWebdavClouds.loginWebdavClouds(activityTestRule.getActivity()); - } - - @Test - public void test06LoginLocalCloudLeadsToLoggedInLocalCloud() { - openCloudServices(device); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(LOCAL, click())); - - LoginLocalClouds.loginLocalClouds(device); - } -} 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 deleted file mode 100644 index 75d688fa..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FileOperationsTest.java +++ /dev/null @@ -1,668 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.rule.ActivityTestRule; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; - -import org.cryptomator.domain.CloudType; -import org.cryptomator.presentation.CryptomatorApp; -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.di.component.ApplicationComponent; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -import java.util.Arrays; - -import static android.R.id.button1; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.pressBack; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.action.ViewActions.swipeDown; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static java.lang.String.format; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.DROPBOX; -import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE; -import static org.cryptomator.presentation.ui.TestUtil.LOCAL; -import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE; -import static org.cryptomator.presentation.ui.TestUtil.WEBDAV; -import static org.cryptomator.presentation.ui.TestUtil.addFolderInVaultsRoot; -import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard; -import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed; -import static org.cryptomator.presentation.ui.TestUtil.removeFolderInVault; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.openSettings; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; -import static org.cryptomator.presentation.ui.activity.FolderOperationsTest.openFolder; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assume.assumeThat; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@RunWith(Parameterized.class) -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; - - 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"}}); - } - - 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 - public void test00UploadFileWithCancelPressedWhileUploadingLeadsToNoNewFileInVault() { - assumeThat(cloudId, is(not(LOCAL))); - - packageName = activityTestRule.getActivity().getPackageName(); - - String nodeName = "foo.pdf"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - uploadFile(nodeName); - - onView(withId(android.R.id.button3)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(swipeDown()); - - awaitCompleted(); - - try { - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(1, R.id.cloudFileText)) // - .check(matches(withText(nodeName))); - - throw new AssertionError("Canceling the upload should not lead to new cloud node"); - } catch (NullPointerException e) { - // do nothing - } - - pressBack(); - } - - @Test - public void test01UploadFileLeadsToNewFileInVault() { - packageName = activityTestRule.getActivity().getPackageName(); - String nodeName = "lala.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - uploadFile(nodeName); - - device.waitForWindowUpdate(packageName, 15000); - - checkFileDisplayText(nodeName, 1); - - pressBack(); - } - - @Test - public void test02UploadAlreadyExistingFileAndCancelLeadsToNoNewFileInVault() { - String nodeName = "lala.png"; - String subString; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - // subString = subtextFromFile(); - - uploadFile(nodeName); - - device.waitForWindowUpdate(packageName, 500); - - onView(withText(R.string.dialog_button_cancel)) // - .perform(click()); - - awaitCompleted(); - - // assertThat(subtextFromFile(), equalTo(subString)); - - pressBack(); - } - - @Test - public void test03UploadAlreadyExistingFileAndReplaceLeadsToUpdatedFileInVault() { - String nodeName = "lala.png"; - String subString; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - awaitCompleted(); - - subString = subtextFromFile(); - - uploadFile(nodeName); - - device.waitForWindowUpdate(packageName, 500); - - onView(withText(R.string.dialog_existing_file_positive_button)) // - .perform(click()); - - awaitCompleted(); - - // assertThat(subtextFromFile(), not(equalTo(subString))); - - pressBack(); - } - - @Test - public void test04OpenFileLeadsToOpenFile() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFile(1); - - device.waitForWindowUpdate(null, 25000); - - device.pressBack(); - - awaitCompleted(); - - pressBack(); - } - - @Test - public void test05RenameFileLeadsToFileWithNewName() { - String fileName = "foo.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - renameFileTo(fileName, 1); - - checkFileDisplayText(fileName, 1); - - pressBack(); - } - - @Test - public void test06RenameFileToExistingFolderLeadsToNothingChanged() { - String fileName = "testFolder"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - renameFileTo(fileName, 1); - - checkFileOrFolderAlreadyExistsErrorMessage(fileName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - - checkFileDisplayText("foo.png", 1); - - pressBack(); - } - - @Test - public void test07MoveFileLeadsToFileWithNewLocation() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openSettings(device, 1); - - openMoveFile(); - - openFolder(0); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - openFolder(0); - - checkFileDisplayText("foo.png", 0); - - pressBack(); - pressBack(); - } - - @Test - public void test08MoveWithExistingFileLeadsToNoNewFile() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - openSettings(device, 0); - - openMoveFile(); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - isToastDisplayed( // - format( // - InstrumentationRegistry // - .getTargetContext() // - .getString(R.string.error_file_or_folder_exists), // - "foo.png"), // - activityTestRule); - - pressBack(); - pressBack(); - pressBack(); - pressBack(); - } - - @Test - public void test09MoveWithExistingFolderLeadsToNoNewFile() { - ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule.getActivity().getApplication()).getComponent(); - - String moveFileNameAndTmpFolder = "foo.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - addFolderInVaultsRoot(appComponent, moveFileNameAndTmpFolder, CloudType.values()[cloudId]); - - awaitCompleted(); - - refreshCloudNodes(); - - openFolder(1); - - openSettings(device, 0); - - openMoveFile(); - - pressBack(); - - awaitCompleted(); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - isToastDisplayed( // - InstrumentationRegistry // - .getTargetContext() // - .getString(R.string.error_file_or_folder_exists), // - activityTestRule); - - removeFolderInVault(appComponent, moveFileNameAndTmpFolder, CloudType.values()[cloudId]); - - pressBack(); - pressBack(); - pressBack(); - } - - @Test - public void test10ShareFileWithCryptomatorLeadsToNewFileInVault() { - String newFileName = "fooBar.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - shareFile(newFileName, cloudId, 0); - - isToastDisplayed(context.getString(R.string.screen_share_files_msg_success), activityTestRule); - - refreshCloudNodes(); - - checkFileDisplayText(newFileName, 1); - - pressBack(); - pressBack(); - } - - @Test - public void test11ShareExistingFileAndReplaceWithCryptomatorLeadsToUpdatedFileInVault() { - String newFileName = "fooBar.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - shareFile(newFileName, cloudId, 0); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - - isToastDisplayed(context.getString(R.string.screen_share_files_msg_success), activityTestRule); - - refreshCloudNodes(); - - checkFileDisplayText(newFileName, 1); // check before and compare with after upload - - pressBack(); - pressBack(); - } - - @Test - public void test12ShareExistingFileWithoutReplaceWithCryptomatorLeadsToNotUpdatedFileInVault() { - String newFileName = "fooBar.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - shareFile(newFileName, cloudId, 0); - - onView(withId(android.R.id.button3)) // - .perform(click()); - - pressBack(); - pressBack(); - pressBack(); - } - - @Test - public void test13RenameFileToExistingFileLeadsToNothingChanged() { - String fileName = "fooBar.png"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - renameFileTo(fileName, 0); - - checkFileOrFolderAlreadyExistsErrorMessage(fileName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - - awaitCompleted(); - - checkFileDisplayText("foo.png", 0); - - pressBack(); - pressBack(); - } - - @Test - public void test14DeleteFileLeadsToRemovedFile() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - awaitCompleted(); - - openFolder(0); - - deleteNodeOnPosition(0); - awaitCompleted(); - deleteNodeOnPosition(0); - - checkEmptyFolderHint(); - - pressBack(); - - deleteTestFolder(); - - pressBack(); - } - - private void deleteNodeOnPosition(int position) { - openSettings(device, position); - - onView(withId(R.id.delete_file)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(android.R.id.button1)) // - .perform(click()); - } - - private void refreshCloudNodes() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(swipeDown()); - - awaitCompleted(); - } - - private void shareFile(String newFilename, int vaultPosition, int filePosition) { - awaitCompleted(); - - openSettings(device, filePosition); - - openEncryptWithCryptomator(); - - chooseShareLocation(vaultPosition); - - checkPathInSharingScreen("/testFolder", vaultPosition); - - onView(withId(R.id.fileName)) // - .perform(replaceText(newFilename), closeSoftKeyboard()); - - onView(withId(R.id.saveFiles)) // - .perform(click()); - - awaitCompleted(); - } - - private void chooseShareLocation(int nodePosition) { - onView(withRecyclerView(R.id.locationsRecyclerView) // - .atPositionOnView(nodePosition, R.id.vaultName)) // - .perform(click()); - - device.waitForWindowUpdate(packageName, 300); - - onView(withRecyclerView(R.id.locationsRecyclerView) // - .atPositionOnView(nodePosition, R.id.chooseFolderLocation)) // - .perform(click()); - - openFolder(0); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - awaitCompleted(); - } - - private void checkPathInSharingScreen(String path, int nodePosition) { - onView(withRecyclerView(R.id.locationsRecyclerView) // - .atPositionOnView(nodePosition, R.id.chosenLocation)) // - .check(matches(withText(path))); - } - - private void deleteTestFolder() { - awaitCompleted(); - - openSettings(device, 0); - - onView(withId(R.id.delete_folder)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - - checkEmptyFolderHint(); - } - - private void uploadFile(String nodeName) { - awaitCompleted(); - - onView(withId(R.id.floatingActionButton)) // - .perform(click()); - - onView(withId(R.id.upload_files)) // - .perform(click()); - - chooseSdCard(device); - - try { - device // - .findObject(new UiSelector().text(nodeName)) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Image " + nodeName + " not available"); - } - } - - private void renameFileTo(String name, int nodePosition) { - awaitCompleted(); - - openSettings(device, nodePosition); - - onView(withId(R.id.rename_file)) // - .perform(click()); - - onView(withId(R.id.et_rename)) // - .perform(replaceText(name), closeSoftKeyboard()); - - onView(allOf( // - withId(button1), // - withText(R.string.dialog_rename_node_positive_button))) // - .perform(click()); - - awaitCompleted(); - } - - private void checkFileDisplayText(String assertNodeText, int nodePosition) { - awaitCompleted(); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.cloudFileText)) // - .check(matches(withText(assertNodeText))); - } - - private void openMoveFile() { - awaitCompleted(); - - onView(withId(R.id.move_file)) // - .perform(click()); - - awaitCompleted(); - } - - private void openEncryptWithCryptomator() { - openShareFile(); - try { - device // - .findObject(new UiSelector().text(context.getString(R.string.share_with_label))) // - .waitForExists(30000L); - device // - .findObject(new UiSelector().text(context.getString(R.string.share_with_label))) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Share with Cryptomator not available"); - } - - awaitCompleted(); - } - - private void openShareFile() { - awaitCompleted(); - - onView(withId(R.id.share_file)) // - .perform(click()); - - awaitCompleted(); - } - - private String subtextFromFile() { - try { - final UiSelector docList = new UiSelector() // - .resourceId("org.cryptomator:id/cloudFileContent"); - - return device // - .findObject(docList.childSelector(new UiSelector(). // - resourceId("org.cryptomator:id/cloudFileSubText") // - .index(0))) // - .getText(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Folder 0 not found"); - } - } -} 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 deleted file mode 100644 index 73590067..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/FolderOperationsTest.java +++ /dev/null @@ -1,313 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.rule.ActivityTestRule; -import androidx.test.uiautomator.UiDevice; - -import org.cryptomator.presentation.R; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -import java.util.Arrays; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.pressBack; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.DROPBOX; -import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE; -import static org.cryptomator.presentation.ui.TestUtil.LOCAL; -import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE; -import static org.cryptomator.presentation.ui.TestUtil.WEBDAV; -import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.openSettings; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; -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); - - 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"}}); - } - - static void openFolder(int nodePosition) { - awaitCompleted(); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.cloudFolderText)) // - .perform(click()); - - awaitCompleted(); - } - - @Test - public void test00CreateFolderLeadsToFolderInVault() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - String folderName = "testFolder"; - createFolder(folderName); - - checkFolderCreationResult(folderName, "/0/testVault", 0); - pressBack(); - - folderName = "testFolder1"; - createFolder(folderName); - - checkFolderCreationResult(folderName, "/0/testVault", 1); - - pressBack(); - pressBack(); - } - - @Test - public void test01CreateExistingFolderLeadsToNoNewFolderInVault() { - String folderName = "testFolder"; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - awaitCompleted(); - - createFolder(folderName); - - checkFileOrFolderAlreadyExistsErrorMessage(folderName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - - awaitCompleted(); - - pressBack(); - } - - @Test - public void test02OpenFolderLeadsToOpenFolder() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - checkEmptyFolderHint(); - - pressBack(); - pressBack(); - } - - @Test - public void test03RenameFolderLeadsToFolderWithNewName() { - String newFolderName = "testFolder2"; - int nodePosition = 1; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - renameFolderTo(newFolderName, nodePosition); - - checkFolderDisplayText(newFolderName, nodePosition); - - pressBack(); - } - - @Test - public void test04RenameFolderToAlreadyExistFolderLeadsToSameFolderName() { - String newFolderName = "testFolder"; - int nodePosition = 1; - - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - renameFolderTo(newFolderName, nodePosition); - - checkFileOrFolderAlreadyExistsErrorMessage(newFolderName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - - awaitCompleted(); - - pressBack(); - } - - @Test - public void test05MoveFolderLeadsToFolderWithNewLocation() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openSettings(device, 1); - - openMoveFolder(); - - openFolder(0); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - openFolder(0); - - checkFolderDisplayText("testFolder2", 0); - - openFolder(0); - - checkEmptyFolderHint(); - - pressBack(); - pressBack(); - pressBack(); - } - - @Test - public void test06MoveFolderToAlreadyExistingFolderLeadsToErrorMessage() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openSettings(device, 0); - - openMoveFolder(); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - awaitCompleted(); - - isToastDisplayed( // - context.getString(R.string.error_file_or_folder_exists), // - activityTestRule); - - pressBack(); - pressBack(); - } - - @Test - public void test07DeleteFolderLeadsToRemovedFolder() { - awaitCompleted(); - - onView(withId(R.id.recyclerView)) // - .perform(actionOnItemAtPosition(cloudId, click())); - - openFolder(0); - - openSettings(device, 0); - - onView(withId(R.id.delete_folder)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - - checkEmptyFolderHint(); - - pressBack(); - pressBack(); - } - - private void openMoveFolder() { - onView(withId(R.id.move_folder)) // - .perform(click()); - } - - private void createFolder(String name) { - awaitCompleted(); - - onView(withId(R.id.floatingActionButton)) // - .perform(click()); - - onView(withId(R.id.create_new_folder)) // - .perform(click()); - - onView(withId(R.id.et_folder_name)) // - .perform(replaceText(name), closeSoftKeyboard()); - - onView(allOf( // - withId(android.R.id.button1), // - withText(R.string.screen_enter_vault_name_button_text))) // - .perform(click()); - - awaitCompleted(); - } - - private void checkFolderCreationResult(String folderName, String path, int position) { - checkFolderDisplayText(folderName, position); - - openSettings(device, position); - - onView(allOf( // - withId(R.id.tv_folder_path), // - withText(path))) // - .check(matches(withText(path))); - - awaitCompleted(); - } - - private void renameFolderTo(String name, int nodePosition) { - awaitCompleted(); - - openSettings(device, nodePosition); - - onView(withId(R.id.change_cloud)) // - .perform(click()); - - onView(withId(R.id.et_rename)) // - .perform(replaceText(name), closeSoftKeyboard()); - - onView(allOf( // - withId(android.R.id.button1), // - withText(R.string.dialog_rename_node_positive_button))) // - .perform(click()); - - awaitCompleted(); - } - - private void checkFolderDisplayText(String assertNodeText, int nodePosition) { - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(nodePosition, R.id.cloudFolderText)) // - .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 deleted file mode 100644 index 7493cba7..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginLocalClouds.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObjectNotFoundException; -import androidx.test.uiautomator.UiSelector; - -import org.cryptomator.presentation.R; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; - -public class LoginLocalClouds { - - private static UiDevice device; - - public static void loginLocalClouds(UiDevice uiDevice) { - device = uiDevice; - String folderName = "0"; - createNewStorageAccessCloudCloud(folderName); - awaitCompleted(); - checkResult(folderName); - } - - private static void createNewStorageAccessCloudCloud(String folderName) { - onView(withId(R.id.floating_action_button)) // - .perform(click()); - - awaitCompleted(); - - chooseSdCard(device); - - awaitCompleted(); - - openFolder0(); - - awaitCompleted(); - - chooseFolder(device); - } - - private static void openFolder0() { - try { - final UiSelector docList = new UiSelector() // - .resourceId("com.android.documentsui:id/container_directory") // - .childSelector( // - new UiSelector() // - .resourceId("com.android.documentsui:id/dir_list")); - - device // - .findObject(docList.childSelector(new UiSelector().text("0"))) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Folder 0 not found"); - } - } - - public static void chooseFolder(UiDevice device) { - try { - - final UiSelector docList = new UiSelector() // - .resourceId("com.android.documentsui:id/container_save"); - - device // - .findObject(docList.childSelector(new UiSelector().resourceId("android:id/button1"))) // - .click(); - } catch (UiObjectNotFoundException e) { - throw new AssertionError("Folder 0 not found"); - } - } - - private static void checkResult(String folderName) { - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(0, R.id.cloudText)) // - .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 deleted file mode 100644 index fe2e0284..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/LoginWebdavClouds.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import org.cryptomator.presentation.R; - -import java.util.Collections; -import java.util.List; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.pressBack; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.activity.LoginWebdavClouds.WebdavCloudCredentials.notSpecialWebdavClouds; -import static org.hamcrest.Matchers.allOf; - -class LoginWebdavClouds { - - private static final String localUrl = "192.168.0.108"; - - static void loginWebdavClouds(SplashActivity activity) { - loginStandardWebdavClouds(); - - /* - * loginAuthenticationFailWebdavCloud(activity); - * - * loginSelfSignedWebdavCloud(); - * - * loginRedirectToHttpsWebdavCloud(); - * - * loginRedirectToUrlWebdavCloud(); - */ - } - - private static void loginStandardWebdavClouds() { - for (WebdavCloudCredentials webdavCloudCredential : notSpecialWebdavClouds()) { - createNewCloud(); - - enterCredentials(webdavCloudCredential); - - startLoginProcess(); - - awaitCompleted(); - - checkResult(webdavCloudCredential); - } - - pressBack(); - } - - private static void createNewCloud() { - onView(withId(R.id.floating_action_button)) // - .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); - * startLoginProcess(); - * clickOk(); - * startLoginProcess(); - * checkResult(SELF_SIGNED_HTTPS); - * } - * - * private static void loginRedirectToHttpsWebdavCloud() { - * createNewCloud(); - * enterCredentials(REDIRECT_TO_HTTPS); - * startLoginProcess(); - * clickOk(); - * clickOk(); - * startLoginProcess(); - * checkResult(REDIRECT_TO_HTTPS); - * } - * - * private static void loginRedirectToUrlWebdavCloud() { - * createNewCloud(); - * enterCredentials(REDIRECT_TO_URL); - * startLoginProcess(); - * clickOk(); - * startLoginProcess(); - * } - */ - - private static void enterCredentials(WebdavCloudCredentials webdavCloudCredential) { - onView(withId(R.id.urlPortEditText)) // - .perform(replaceText(webdavCloudCredential.url)); - - onView(withId(R.id.userNameEditText)) // - .perform(replaceText(webdavCloudCredential.username)); - - onView(withId(R.id.passwordEditText)) // - .perform( // - replaceText(webdavCloudCredential.password), // - closeSoftKeyboard()); - } - - private static void checkResult(WebdavCloudCredentials webdavCloudCredential) { - onView(allOf( // - withId(R.id.cloudText), // - withText(webdavCloudCredential.displayUrl))); - - onView(allOf( // - 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 deleted file mode 100644 index 2c2b6cec..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/VaultsOperationsTest.java +++ /dev/null @@ -1,412 +0,0 @@ -package org.cryptomator.presentation.ui.activity; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.rule.ActivityTestRule; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiSelector; - -import org.cryptomator.domain.CloudType; -import org.cryptomator.presentation.CryptomatorApp; -import org.cryptomator.presentation.R; -import org.cryptomator.presentation.di.component.ApplicationComponent; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.junit.runners.Parameterized; - -import java.util.Arrays; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.pressBack; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.replaceText; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted; -import static org.cryptomator.presentation.ui.TestUtil.DROPBOX; -import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE; -import static org.cryptomator.presentation.ui.TestUtil.LOCAL; -import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE; -import static org.cryptomator.presentation.ui.TestUtil.WEBDAV; -import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed; -import static org.cryptomator.presentation.ui.TestUtil.removeFolderInCloud; -import static org.cryptomator.presentation.ui.TestUtil.waitForIdle; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage; -import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView; -import static org.cryptomator.presentation.ui.activity.FileOperationsTest.grantPermission; -import static org.cryptomator.presentation.ui.activity.FileOperationsTest.isPermissionShown; -import static org.cryptomator.presentation.ui.activity.FileOperationsTest.openFile; -import static org.cryptomator.presentation.ui.activity.FolderOperationsTest.openFolder; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@RunWith(Parameterized.class) -public class VaultsOperationsTest { - - @Rule - public final ActivityTestRule activityTestRule = new ActivityTestRule<>(SplashActivity.class); - - private final UiDevice device = UiDevice.getInstance(getInstrumentation()); - private final Context context = InstrumentationRegistry.getTargetContext(); - - 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"}}); - } - - @Test - public void test00CreateNewVaultsLeadsToNewVaults() { - ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule.getActivity().getApplication()).getComponent(); - String path = "0/tempVault/"; - - awaitCompleted(); - - // Permission problem - if (cloudId != LOCAL) { - removeFolderInCloud(appComponent, path, CloudType.values()[cloudId]); - removeFolderInCloud(appComponent, "0/testVault/", CloudType.values()[cloudId]); - removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.values()[cloudId]); - } - - onView(withId(R.id.floating_action_button)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(R.id.create_new_vault)) // - .perform(click()); - - createVault(cloudId, appComponent, path); - - awaitCompleted(); - - unlockVault("tempVault", cloudId); - - awaitCompleted(); - - checkEmptyFolderHint(); - - pressBack(); - - } - - @Test - public void test01RenameLoggedInVaultToAlreadyExistingNameLeadsToNothingChanged() { - String vaultName = "tempVault"; - - renameVault(cloudId, vaultName); - - checkFileOrFolderAlreadyExistsErrorMessage(vaultName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - - checkVault(cloudId, vaultName); - } - - @Test - public void test02ChangeLoggedInVaultPasswordLeadsToNewPassword() { - String oldPassword = "tempVault"; - String newPassword = "foo"; - - changePassword(cloudId, oldPassword, newPassword); - - isToastDisplayed(context.getString(R.string.screen_vault_list_change_password_successful), activityTestRule); - - } - - @Test - public void test03RenameLoggedInVaultToNewNameLeadsToNewName() { - String vaultName = "testLoggedInVault"; - - renameVault(cloudId, vaultName); - - checkVault(cloudId, vaultName); - - } - - @Test - public void test04RenameLoggedOutVaultToAlreadyExistingNameLeadsToNothingChanged() { - String vaultName = "testLoggedInVault"; - - renameVault(cloudId, vaultName); - - checkFileOrFolderAlreadyExistsErrorMessage(vaultName); - - onView(withId(android.R.id.button2)) // - .perform(click()); - } - - @Test - public void test05RenameLoggedOutVaultToNewNameLeadsToNewName() { - String vaultName = "testVault"; - - renameVault(cloudId, vaultName); - - checkVault(cloudId, vaultName); - } - - @Test - public void test06ChangeLoggedOutVaultPasswordLeadsToNewPassword() { - String oldPassword = "foo"; - String newPassword = "testVault"; - - changePassword(cloudId, oldPassword, newPassword); - - isToastDisplayed(context.getString(R.string.screen_vault_list_change_password_successful), activityTestRule); - } - - @Test - public void test07DeleteVaultsLeadsToDeletedVaults() { - waitForIdle(device); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(cloudId, R.id.settings)) // - .perform(click()); - - waitForIdle(device); - - onView(withId(R.id.delete_vault)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - onView(withId(R.id.tv_creation_hint)); - } - - @Test - public void test08addExistingVaultsLeadsToAddedVaults() { - waitForIdle(device); - - onView(withId(R.id.floating_action_button)) // - .perform(click()); - - waitForIdle(device); - - onView(withId(R.id.add_existing_vault)) // - .perform(click()); - - openVault(cloudId); - - awaitCompleted(); - - unlockVault("testVault", cloudId); - - awaitCompleted(); - - checkEmptyFolderHint(); - - pressBack(); - } - - private void renameVault(int position, String vaultName) { - awaitCompleted(); - - waitForIdle(device); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(position, R.id.settings)) // - .perform(click()); - - waitForIdle(device); - - onView(withId(R.id.et_rename)) // - .perform(click()); - - awaitCompleted(); - - waitForIdle(device); - - onView(withId(R.id.et_rename)) // - .perform(replaceText("tempVault"), closeSoftKeyboard()); - - onView(withId(R.id.et_rename)) // - .perform(replaceText(vaultName), closeSoftKeyboard()); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - } - - private void createVault(int vaultPosition, ApplicationComponent appComponent, String path) { - awaitCompleted(); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(vaultPosition, R.id.cloud)) // - .perform(click()); - - String vaultnameAndPassword = "tempVault"; - - awaitCompleted(); - - switch (vaultPosition) { - 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()); - - awaitCompleted(); - - isPermissionShown(device); - grantPermission(device); - - removeFolderInCloud(appComponent, path, CloudType.LOCAL); - removeFolderInCloud(appComponent, "0/testVault/", CloudType.LOCAL); - removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.LOCAL); - - break; - } - - awaitCompleted(); - - onView(withId(R.id.vaultNameEditText)) // - .perform(replaceText(vaultnameAndPassword), closeSoftKeyboard()); - - awaitCompleted(); - - onView(withId(R.id.createVaultButton)) // - .perform(click()); - - awaitCompleted(); - - openFolder(0); - - onView(withId(R.id.chooseLocationButton)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(R.id.passwordEditText)) // - .perform(replaceText(vaultnameAndPassword)); - - onView(withId(R.id.passwordRetypedEditText)) // - .perform(replaceText(vaultnameAndPassword), closeSoftKeyboard()); - - awaitCompleted(); - - onView(withId(R.id.createVaultButton)) // - .perform(click()); - } - - private void openVault(int vaultPosition) { - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(vaultPosition, R.id.cloud)) // - .perform(click()); - - awaitCompleted(); - - switch (vaultPosition) { - 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; - } - - awaitCompleted(); - - openFolder(0); - awaitCompleted(); - - openFolder(0); - awaitCompleted(); - - openFile(1); - } - - private void unlockVault(String vaultPassword, int vaultPosition) { - waitForIdle(device); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(vaultPosition, R.id.vaultName)) // - .perform(click()); - - device // - .findObject(new UiSelector().text("Password")) // - .waitForExists(30000L); - - onView(withId(R.id.et_password)) // - .perform(replaceText(vaultPassword), closeSoftKeyboard()); - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - } - - private void changePassword(int position, String oldPassword, String newPassword) { - awaitCompleted(); - - waitForIdle(device); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(position, R.id.settings)) // - .perform(click()); - - waitForIdle(device); - - onView(withId(R.id.change_password)) // - .perform(click()); - - awaitCompleted(); - - onView(withId(R.id.et_old_password)) // - .perform(replaceText(oldPassword)); - - onView(withId(R.id.et_new_password)) // - .perform(replaceText(newPassword)); - - onView(withId(R.id.et_new_retype_password)) // - .perform(replaceText(newPassword), closeSoftKeyboard()); - - onView(withId(android.R.id.button1)) // - .perform(click()); - - awaitCompleted(); - } - - private void checkVault(int position, String name) { - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(position, R.id.vaultName)) // - .check(matches(withText(name))); - - onView(withRecyclerView(R.id.recyclerView) // - .atPositionOnView(position, R.id.vaultPath)) // - .check(matches(withText("/0/" + name))); - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/FailureListener.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/FailureListener.java deleted file mode 100644 index 3e37f342..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/FailureListener.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.cryptomator.presentation.ui.activity.suite; - -import org.junit.runner.notification.Failure; -import org.junit.runner.notification.RunListener; -import org.junit.runner.notification.RunNotifier; - -class FailureListener extends RunListener { - - private final RunNotifier runNotifier; - - FailureListener(RunNotifier runNotifier) { - super(); - this.runNotifier = runNotifier; - } - - @Override - public void testFailure(Failure failure) throws Exception { - super.testFailure(failure); - this.runNotifier.pleaseStop(); - } -} diff --git a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/StopOnFailureSuite.java b/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/StopOnFailureSuite.java deleted file mode 100644 index 75e236f2..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/StopOnFailureSuite.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.cryptomator.presentation.ui.activity.suite; - -import org.junit.runner.notification.RunNotifier; -import org.junit.runners.Suite; -import org.junit.runners.model.InitializationError; - -public class StopOnFailureSuite extends Suite { - - public StopOnFailureSuite(Class klass, Class[] suiteClasses) throws InitializationError { - super(klass, suiteClasses); - } - - public StopOnFailureSuite(Class klass) throws InitializationError { - super(klass, klass.getAnnotation(Suite.SuiteClasses.class).value()); - } - - @Override - public void run(RunNotifier runNotifier) { - runNotifier.addListener(new FailureListener(runNotifier)); - super.run(runNotifier); - } -} 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 deleted file mode 100644 index e711df54..00000000 --- a/presentation/src/androidTest/java/org/cryptomator/presentation/ui/activity/suite/UiTestSuite.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.cryptomator.presentation.ui.activity.suite; - -import org.cryptomator.presentation.ui.activity.CloudsOperationsTest; -import org.cryptomator.presentation.ui.activity.FileOperationsTest; -import org.cryptomator.presentation.ui.activity.FolderOperationsTest; -import org.cryptomator.presentation.ui.activity.VaultsOperationsTest; -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@Ignore -@RunWith(StopOnFailureSuite.class) -@Suite.SuiteClasses({ // - CloudsOperationsTest.class, // - VaultsOperationsTest.class, // - FolderOperationsTest.class, // - FileOperationsTest.class // -}) -public class UiTestSuite { - -} diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 9c449d8b..359fb2ec 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -37,6 +37,7 @@ @@ -47,25 +48,31 @@ @@ -80,12 +87,14 @@ @@ -98,22 +107,40 @@ - - - - - - - - + + + + + + + + @@ -131,10 +158,12 @@ @@ -159,11 +188,15 @@ - + + + @@ -209,7 +243,9 @@ - + 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 7e7df22b..caf2400a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/BrowseFilesPresenter.kt @@ -284,16 +284,18 @@ class BrowseFilesPresenter @Inject constructor( // private fun copyFile(downloadFiles: List) { downloadFiles.forEach { downloadFile -> try { - FileInputStream(fileUtil.fileFor(cloudFileModelMapper.toModel(downloadFile.downloadFile))).use { - copyDataUseCase // - .withSource(it) // - .andTarget(downloadFile.dataSink) // - .run(object : DefaultResultHandler() { - override fun onFinished() { - view?.showMessage(R.string.screen_file_browser_msg_file_exported) - } - }) - } + val source = FileInputStream(fileUtil.fileFor(cloudFileModelMapper.toModel(downloadFile.downloadFile))) + copyDataUseCase // + .withSource(source) // + .andTarget(downloadFile.dataSink) // + .run(object : DefaultResultHandler() { + override fun onSuccess(t: Void?) { + view?.showMessage(R.string.screen_file_browser_msg_file_exported) + } + override fun onFinished() { + source.close() + } + }) } catch (e: FileNotFoundException) { showError(e) } 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 d2f38f46..cfd8f00a 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/service/AutoUploadNotification.kt @@ -48,7 +48,7 @@ class AutoUploadNotification(private val context: Context, private val amountOfP private fun cancelNowAction(): NotificationCompat.Action { val intentAction = cancelAutoUploadIntent(context) - val cancelIntent = PendingIntent.getService(context, 0, intentAction, FLAG_CANCEL_CURRENT) + val cancelIntent = PendingIntent.getService(context, 0, intentAction, FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE) return NotificationCompat.Action.Builder( // R.drawable.ic_lock, // getString(R.string.notification_cancel_auto_upload), // @@ -60,7 +60,7 @@ class AutoUploadNotification(private val context: Context, private val amountOfP val startTheActivity = Intent(context, VaultListActivity::class.java) startTheActivity.action = ACTION_MAIN startTheActivity.flags = FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK - return PendingIntent.getActivity(context, 0, startTheActivity, FLAG_CANCEL_CURRENT) + return PendingIntent.getActivity(context, 0, startTheActivity, FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE) } fun update(progress: Int) { 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 023945fa..f36d6098 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/service/OpenWritableFileNotification.kt @@ -4,7 +4,6 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.app.NotificationManager.IMPORTANCE_LOW import android.app.PendingIntent -import android.app.PendingIntent.FLAG_CANCEL_CURRENT import android.content.Context import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION import android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION @@ -54,7 +53,7 @@ class OpenWritableFileNotification(private val context: Context, private val uri private fun cancelNowIntent(): PendingIntent { context.revokeUriPermission(uriToOpenendFile, FLAG_GRANT_WRITE_URI_PERMISSION or FLAG_GRANT_READ_URI_PERMISSION) val startTheActivity = vaultListIntent().withStopEditFileNotification(true).build(context as ContextHolder) - return PendingIntent.getActivity(context, 0, startTheActivity, FLAG_CANCEL_CURRENT) + return PendingIntent.getActivity(context, 0, startTheActivity, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE) } fun show() { 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 52c53c92..1b90f1d1 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java +++ b/presentation/src/main/java/org/cryptomator/presentation/service/UnlockedNotification.java @@ -16,7 +16,6 @@ import org.cryptomator.presentation.util.ResourceHelper; import timber.log.Timber; import static android.app.NotificationManager.IMPORTANCE_LOW; -import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -73,15 +72,15 @@ class UnlockedNotification { return PendingIntent.getService( // service.getApplicationContext(), // 0, // - CryptorsService.lockAllIntent(service.getApplicationContext()), // - FLAG_CANCEL_CURRENT); + CryptorsService.lockAllIntent(service.getApplicationContext()), + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); } private PendingIntent startTheActivity() { Intent startTheActivity = new Intent(service, VaultListActivity.class); startTheActivity.setAction(ACTION_MAIN); startTheActivity.setFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK); - return PendingIntent.getActivity(service, 0, startTheActivity, 0); + return PendingIntent.getActivity(service, 0, startTheActivity, PendingIntent.FLAG_IMMUTABLE); } public void setUnlockedCount(int unlocked) { diff --git a/presentation/src/main/res/values-bn-rBD/strings.xml b/presentation/src/main/res/values-bn-rBD/strings.xml index 04a25bc0..49c754c1 100644 --- a/presentation/src/main/res/values-bn-rBD/strings.xml +++ b/presentation/src/main/res/values-bn-rBD/strings.xml @@ -14,6 +14,7 @@ ভোল্টটি ইতিমধ্যে রয়েছে। ফাইলটি নেই। ভোল্টটি লক করা হয়েছে। + ক্লাউড ইতিমধ্যে বিদ্যমান. ফাইলটি খুলতে পারে এমন একটি আ্যপ ডাউনলোড করুন। সার্ভার খুজে পাওয়া যায়নি। অনুগ্রহ করে ডিভাইস সেটিংস খুলে নিজে স্ক্রিন লক লাগিয়ে নিন। @@ -39,6 +40,7 @@ ক্রিপ্টোমেটরের ফাইল এক্সপোর্ট করতে স্টোরেজ অনুমতি প্রয়োজন ক্রিপ্টোমেটরের ফাইল আপলোড করতে স্টোরেজ অনুমতি প্রয়োজন + ক্রিপ্টোমেটরের ফাইল শেয়ার করতে স্টোরেজ এক্সেস প্রয়োজন সেটিংস খুঁজুন পিছনে @@ -213,7 +215,28 @@ প্রতিস্থাপন করুন %1$s নামে একটি ফাইল ইতিমধ্যে রয়েছে। আপনি কি এটা প্রতিস্থাপন করতে চান? সব ফাইলগুলি ইতিমধ্যে রয়েছে। আপনি কি তাদের প্রতিস্থাপন করতে চান? + ফাইলগুলো শেয়ার করা যায় নি + আপনি কোনো ভোল্ট যুক্ত করেননি. অনুগ্রহ করে ক্রিপ্টোমেটর আ্যপ দিয়ে একটি নতুন ভোল্ট তৈরি করুন. আচ্ছা + ভোল্ট তৈরি করুন + %1$s খোলা যাচ্ছে না + অনুগ্রহ করে এমন একটি অ্যাপ ডাউনলোড করুন যেটি ফাইলটি খুলতে পারবে অথবা আপনি কি আপনার ডিভাইসে সংরক্ষণ করতে চান? + ভোল্ট নামকরণ করুন + ফোল্ডার পুনঃনামকরন + ফাইল পুনঃনামকরন + আপনার পরিবর্তনগুলো সংরক্ষণ করা হয়নি + আপনি সংরক্ষণ না করেই বের হয়ে যাবেন? + অগ্রাহ্য + text.txt + আপনি কি নিশ্চিতভাবে এই ভোল্ট অপসারণ করতে চান? + এই প্রক্রিয়ায় ভোল্টটি শুধুমাত্র এই তালিকা থেকে বাতিল হবে এবং মূল জায়গা থেকে মুছবে না. + আপলোড হচ্ছে… + ফাইল %1$d এর %2$d টি + এক্সপোর্ট হচ্ছে (%1$d/%2$d) + অনুগ্রহ করে অপেক্ষা করুন… + ফোল্ডার তৈরি হচ্ছে… + টেক্সট ফাইল তৈরি হচ্ছে… + আপলোড হচ্ছে… লক করুন বন্ধ করুন পিছনে diff --git a/presentation/src/main/res/values-de-rDE/strings.xml b/presentation/src/main/res/values-de-rDE/strings.xml index 3fccdf1b..f6519ef1 100644 --- a/presentation/src/main/res/values-de-rDE/strings.xml +++ b/presentation/src/main/res/values-de-rDE/strings.xml @@ -373,14 +373,14 @@ Fehler beim automatischen Photo-Hochladen Generaller Fehler während dem Hochladen. Ausgewählter Ordner für das Photo-Hochladen existiert nicht mehr. In der Einstellungen neuen auswählen - Tresor gesperrt während dem hochladen, zum weiteren Hochladen entsperren + Tresor wurde während dem Hochladen gesperrt, bitte Tresor erneut öffnen, um fortzufahren Der Tresor für den automatischen Upload existiert nicht mehr. Datei mit Schreibrechten geöffnet Tresor bleibt entsperrt, bis die Bearbeitung abgeschlossen wurde Neueste Version installiert Melde an… Zwischenspeicher - Speichere kürzlich geöffnete Dateien lokal und verschlüsselt auf dem Gerät für eine spätere Wiederverwendung beim erneuten öffnen + Kürzlich geöffnete Dateien für eine spätere Wiederverwendung beim erneuten Öffnen lokal und verschlüsselt auf dem Gerät zwischenspeichern Zwischenspeichergröße gesamt Zwischenspeicher leeren Änderungen werden nach einem Neustart der App aktiv diff --git a/presentation/src/main/res/values-hr-rHR/strings.xml b/presentation/src/main/res/values-hr-rHR/strings.xml index 79586830..5fcc2ee7 100644 --- a/presentation/src/main/res/values-hr-rHR/strings.xml +++ b/presentation/src/main/res/values-hr-rHR/strings.xml @@ -9,13 +9,13 @@ Nema mrežne veze Pogrešna lozinka Datoteka ili mapa već postoje. - Verzija trezora %1$s nije podržana. Ovaj trezor je stvoren sa starijom ili novijom verzijom Cryptomator-a. + Verzija trezora %1$s nije podržana. Ovaj trezor je izrađen sa starijom ili novijom verzijom Cryptomator-a. %1$s datoteka nedostaje u mapi Vašeg trezora. Budite sigurni da ova datoteka postoji u mapi Vašeg trezora u oblaku. Trezor već postoji. Datoteka ne postoji. Trezor je zaključan. Oblak već postoji. - Molimo preuzmite aplikaciju koja može otvoriti ovu datoteku. + Molimo preuzmite program koji može otvoriti ovu datoteku. Poslužitelj nije pronađen. Molimo otvorite postavke svog uređaja i ručno postavite zaključavanje zaslona Izvoz neuspješan. Uklonite posebne znakove iz imena datoteka i izvezite ponovno. @@ -33,7 +33,7 @@ Opća greška kod učitavanja postavki trezora Lokalna datoteka više ne postoji nakon povratka u Cryptomator. Moguće promjene ne mogu se propagirati nazad u oblak. Nepostojeća kanta - Prilagođeno mjesto glavnog ključa još nije podržano + Prilagođena lokacija glavnog ključa još nije podržano Lokalna pohrana @@ -57,16 +57,21 @@ Dodaj u Cryptomator - Napravi novi trezor + Izradi novi trezor Dodaj postojeći trezor Ukloni - Pritisnite ovdje za stvaranje novog trezora + Pritisnite ovdje za izradu novog trezora Lozinka je uspješno promijenjena Trezor Odaberi datoteku glavnog ključa Postavi ovdje Ime trezora: %1$s + + Premjesti %1$s u + Premjesti %2$d stavke u + Premjesti %2$d stavki u + Premjesti Prazna mapa izmijenjeno prije %1$s @@ -138,14 +143,14 @@ Ime trezora ne može biti prazno. Ime trezora - Stvori + Izradi Postavi lozinku Lozinka ne odgovara ponovno upisanoj lozinci. Gotovo VAŽNO: Ako zaboravite svoju lozinku, nema načina za povrat Vaših podataka. Ponovno upišite lozinku - Preslaba za kreiranje trezora + Preslaba za izradu trezora Slaba Prosječna Jaka @@ -156,10 +161,10 @@ Biometrijska autentikacija Aktiviraj biometrijsku autentikaciju Potvrdi otključavanje licem (ako je dostupno) - Blokiraj program kada je zaklonjen + Blokiraj aplikaciju kada je zaklonjena Blokiraj presretanje unosa i prikaz lažnog korisničkog sučelja Blokiraj snimke zaslona - Blokiraj snimke zaslona u listi nedavnih i unutar programa + Blokiraj snimke zaslona u listi nedavnih i unutar aplikacije Traži Pretraživanje uživo Ažuriraj rezultate pretraživanja pri unosu upita @@ -192,44 +197,221 @@ Verzija Napredne postavke Ubrzaj otključavanje + Preuzmite postavke trezora u pozadini dok se od vas traži da unesete lozinku ili biometrijska autentikacija + Drži otključano + Neka trezori budu otključani dok se datoteke uređuju + OneDrive veze + WebDAV veze + pCloud veze + S3 veze + Lokacije lokalne pohrane + Prijavi se na + Odjavi se iz + %1$s se ne može autenticirati. + Ažuriraj pCloud vjerodajnice Odustani Otključaj + Stara lozinka + Nova lozinka + Promijeni lozinku + Stara lozinka ne može biti prazna. + Nova lozinka ne može biti prazna. Nova lozinka ne odgovara ponovno upisanoj lozinci. + Trezor %1$s nije pronađen + Trezor je preimenovan, pomaknut ili obrisan. Uklonite trezor s liste i dodajte ga ponovno za nastavak. Ukloniti sada? Ukloni + Datoteka već postoji Zamijeni Datoteka s imenom \'%1$s\' već postoji. Preskoči postojeće Zamijeni sve Zamijeni postojeće Zamijeni + Datoteka naziva \'%1$s\' već postoji. Želite li ju zamijeniti? + Sve datoteke već postoje. Želite li ih zamijeniti? + %1$d datoteka već postoji. Želite li ih zamijeniti? + Zamijeniti datoteku? + Zamjeniti datoteke? + Nije moguće dijeliti datoteke + Niste postavili niti jedan trezor. Izradite novi trezor s Cryptomator-om. + U redu + Izradi trezor + Ne mogu otvoriti %1$s + Preuzmite aplikaciju koja može otvoriti ovu datoteku ili ju želite pohraniti na Vaš uređaj? + Preimenuj trezor + Preimenuj mapu + Preimenuj datoteku + Imate nepohranjene promjene + Želite li izaći bez spremanja? + Odbaci tekst.txt + Sigurno želite ukloniti ovaj trezor? + Ova radnja će samo ukloniti trezor s liste, ali ne i fizički ga obrisati. Prenosi se… + Datoteka %1$d od %2$d + Izvoz (%1$d/%2$d) + Molimo pričekajte… + Izrada mape… + Izrada tekstualne datoteke… + Autentikacija… + Preimenovanje… + Brisanje… + Otključavanje trezora… + Promijeni lozinku… + Izrada trezora… Prenosi se… Preuzima se… Šifrira se… + Dešifriranje… + Premještanje… Zaključaj + Nevažeći SSL certifikat + SSL certificate je nevažeći. Želite li mu ipak vjerovati? Detalji + Ovo bi mogao biti sigurnosni rizik. Znam što činim. + Onemogući optimizacije baterije + Za dohvat novih slika i videa bez rada u pozadini, moramo onemogućiti optimizacije baterije. Ali ne brinite, %1$s ne troši puno energije.\n\nDa biste ga primijenili, promijenite \"Nije optimizirano\" u \"Sve aplikacije\", odaberite %1$s i odaberite \"Nemoj optimizirati\" nakon što pritisnete \'%2$s\' u ovom dijaloškom okviru. + Ne pitati ponovno? + Korištenje HTTP-a je nesigurno. Preporučamo korištenje HTTPS-a umjesto toga. Ako znate rizike, možemo nastaviti s HTTP-om. + Promijeni u HTTPS + Koristiti HTTPS? + Zaključavanje zaslona nije postavljeno. Da biste svoje vjerodajnice pohranili na siguran način, postavite s OK uzorak ili lozinku. + Postaviti zaključavanje zaslona? + Postaviti zaključavanje zaslona + U sustavu nije postavljena osnovna provjera autentikacije + Prijavite barem jedan prst/lice za korištenje ove usluge. U ovom načinu, osjetljivi podaci mogu biti zapisani u log datoteku na Vašem uređaju (npr. datoteke i putanje). Lozinke, kolačići itd. su izričito isključeni.\n\nZapamtite da isključite način za otklanjanje pogrešaka čim prije je to moguće. Pažnja Omogući + Ova je postavka sigurnosna značajka i spriječava druge aplikacije da prevare korisnike da rade stvari koje ne žele raditi.\n\nOnemogućavanjem potvrđujete da ste svjesni rizika. Pažnja + Onemogući + Aplikacija je zaklonjena + Druga aplikacija prikazuje nešto na vrhu Cryptomator-a (e.g., a blue light filter or night mode app). Iz sigurnosnih razloga, Cryptomator je onemogućen.\n\nKako omogućiti Cryptomator Zatvori + Ponovno dodajte trezore za %1s oblak + Tijekom migracije na ovu verziju aplikacije moramo ukloniti sljedeće trezore iz njega:\n%2s \n\nTi trezori se ne uklanjaju iz oblaka, već samo iz ove aplikacije. Ispričavamo se zbog neugodnosti i molimo da ponovno dodate ove trezore kako biste nastavili raditi s njima. + Trezor je korijenska mapa veze u oblaku + Izradite novu vezu prema oblaku pri čemu odaberite barem nadređenu mapu ovog trezora kao korijensku mapu za njegovo dodavanje. + Ova je postavka sigurnosna značajka i sprječava druge aplikacije da prevare korisnike da rade stvari koje ne žele raditi.\n\nOnemogućavanjem potvrđujete da ste svjesni rizika. + Sigurni ste da želite ukloniti ovu vezu prema oblaku? + Ova radnje će ukloniti vezu prema oblaku i sve trezore u njemu. + Izbrisati %1$d stavke? + Sigurno želite obrisati ove stavke? + Sigurno želite obrisati ove datoteke? + Ovo će obrisati sav sadržaj mape. Sigurni ste da želite obrisati ovu mapu? + Biometrijska autentikacija deaktivirana + Budući da je ključ poništen, biometrijska autentikacija je deaktivirana. Da biste ju ponovno omogućili, otvorite postavke Cryptomator-a. + Pružite važeću licencu + Otkrili smo da ste instalirali Cryptomator bez upotrebe trgovine Google Play. Navedite važeću licencu koja se može kupiti na https://cryptomator.org/android/ + Navedena licenca nije važeća. Provjerite jeste li ju ispravno unijeli. + Navedeni ključ je certifikat tzv. stolnog podržavatelja. Molimo unesite važeću licencu. + Licenca nije pružena. Molimo unesite važeću licencu. + Izlaz + Potvrda licence + Hvala %1$s za pružanje valjane licence. + Ažuriranje dostupno + Ažurirajte Cryptomator na najnoviju verziju. Pritiskom na OK aplikaciju ćemo preuzeti u pozadini i zatražiti od Vas da ju instalirate. + Ažuriraj sada + Idi na stranicu za preuzimanja + Kasnije + Preuzimanje u tijeku + Preuzimanje zadnje verzije Cryptomator-a + Mapa je simbolička veza + Ne možete pratiti ovu simboličku vezu Nazad + Nije moguće učitati sadržaj mape + Mapa u oblaku \'%1$s\' nema valjanu datoteku mape. Može biti da je mapa izrađena na drugom uređaju i nije još u potpunosti sinkronizirana s oblakom. Molimo provjerite u oblaku da slijedeća datoteka postoji i da nije prazna:\n%2$s + Nema više slika za prikaz… + Vjerodajnice od \'%1$s\' ažurirane + Ako ste namjeravali dodati novi pCloud račun, pritisnite url www.pcloud.com, odjavite se iz postojećeg računa i pritisnite na \'+\' u ovoj aplikaciji za izradu nove veze prema oblaku. + Cryptomator treba pristup pohrani da koristi lokalne trezore + Cryptomator treba pristup pohrani da koristi automatski prijenos slika + Nula kB + bajtova + kB + MB + GB + TB + sekunda + sekunde + minuta minute + sat + sati + dan + dani + tjedan + tjedni + mjesec + mjeseci + godina + godine + Biometrijska prijava + Prijavite se koristeći svoje biometrijske vjerodajnice + Koristi lozinku trezora + Nije moguć automatski prijenos datoteka + Otključanih trezora: %1$d + Automatsko zaključavanje za %1$s + Zaključaj sve + Odustani od prijenosa + Aumatski prijenos slika u tijeku + Prenosim %1d/%2d + Automatski prijenos slika završen + %1$d slika preneseno u trezor + Automatski prijenos slika neuspješan + Došlo je do greške tijekom prijenosa. + Odabrana mapa za prijenos više nije dostupna. Idite na postavke i odaberite novu + Trezor je zaključan tijekom prijenosa, ponovno ga otvorite za nastavak + Trezor određen za automatski prijenos više ne postoji. + Datoteka otvorena za pisanje + Trezor ostaje otvoren dok se ne završi izmjena + Najnovija verzija je instalirana + Autentikacija… + Predmemorija + Predmemorija je nedavno pristupila datotekama šifriranima lokalno na uređaju za kasniju ponovnu upotrebu + Ukupna veličina predmemorije + Očisti predmemoriju + Promjene će se primijeniti kod slijedećeg pokretanja aplikacije + Registrirano za + %1$s + Razmak ažuriranja + Potraži ažuriranja + Posljednji put pokrenuto %1$s + Veličina predmemorije po oblaku + Odmah + 1 minuta + 2 minute + 5 minuta + 10 minuta + Nikad + 50 MB + 100 MB + 250 MB + 500 MB + 1 GB + 5 GB + Stil + Automatski (slijedi sustav) + Svijetlo + Tamno + Jednom dnevno + Jednom tjedno + Jednom mjesečno diff --git a/presentation/src/main/res/values-hu-rHU/strings.xml b/presentation/src/main/res/values-hu-rHU/strings.xml index 87d90e53..34fff9c8 100644 --- a/presentation/src/main/res/values-hu-rHU/strings.xml +++ b/presentation/src/main/res/values-hu-rHU/strings.xml @@ -197,6 +197,7 @@ Feloldvatartás Fájlok szerkesztése közben tartsa feloldva a trezorokat + OneDrive kapcsolat WebDAV fiókok pCloud fiókok S3 fiókok @@ -270,6 +271,21 @@ Az SSL tanúsítvány érvénytelen. El szeretné fogadni ennek ellenére? Részletek Ez biztonsági kockázatot jelent. Tudom, mit csinálok. + Akkumulátor-optimalizálás kikapcsolása + Ne kérdezze újra + A HTTP használata nem biztonságos, helyette a HTTPS használata ajánlott. Ha ismeri a kockázatot, folytathatja HTTP-vel is. + Váltson HTTPS-re + HTTPS használata + Nincs beállítva kijelzőzár. A hitelesítő adatok biztonságos tárolásához az OK-ra kattintva állítson be mintát vagy jelszót. + Képernyőzár beállítása? + Képernyőzár beállítása + Nincs beállítva hitelesítés a rendszerben + A funkció használatához tároljon legalább egy biometrikus adatot. + Ebben a módban érzékeny adatok kerülhetnek az eszközön lévő naplófájlba (pl. fájlnevek és -útvonalak). Ez jelszavakra és sütikre nem vonatkozik.\n\n Ne felejtse el minél hamarabb kikapcsolni a fejlesztői módot. + Figyelem + Engedélyezés + Figyelem + Letiltás Bezár Biztosan törölni akarja ezeket az elemeket? Biztosan törli ezt a fájlt? @@ -328,6 +344,7 @@ Írható fájl megnyitása A trezor a szerkesztés idejéig feloldva marad A legfrissebb verzió van telepítve + Hitelesítés… Gyorsítótár Helyileg titkosított fájlok gyorsítótárazása az eszközön, később újrafelhasználásra Gyorsítótár mérete @@ -336,10 +353,28 @@ Regisztrált: %1$s Frissítések keresésése + Frissítések keresése + Azonnal + 1 perc + 2 perc + 5 perc + 10 perc + Soha + 50 MB + 100 MB + 250 MB + 500 MB + 1 GB + 5 GB + Stílus + Automatikus (A rendszeren alapuló) Világos Sötét + Naponta egyszer + Hetente egyszer + Havonta egyszer diff --git a/presentation/src/main/res/values-in-rID/strings.xml b/presentation/src/main/res/values-in-rID/strings.xml index e32ffe71..4cc9c121 100644 --- a/presentation/src/main/res/values-in-rID/strings.xml +++ b/presentation/src/main/res/values-in-rID/strings.xml @@ -9,6 +9,8 @@ Tidak ada koneksi jaringan Kata sandi salah Berkas atau folder sudah ada. + Vault versi %1$s tidak didukung. Vault ini dibuat menggunakan Cryptomator versi lama ataupun lebih baru. + File %1$s tidak ditemukan di folder vault Anda. Pastikan file tersebut ada di folder cloud Anda. Vault sudah ada. Berkas tidak ada. Vault telah dikunci. @@ -271,6 +273,9 @@ Sertifikat SSL tidak valid. Apakah Anda ingin mempercayainya? Rincian Ini bisa menjadi risiko keamanan. Saya tahu apa yang saya lakukan. + Nonaktifkan optimalisasi baterai + Untuk mengambil gambar dan video baru tanpa berjalan di latar belakang, kami perlu keluar dari pengoptimalan baterai. Tidak perlu khawatir, %1$s tidak mengonsumsi banyak daya.\n\nUntuk menerapkannya, ubah \'Tidak dioptimalkan\' menjadi \'Semua aplikasi\', pilih %1$s dan pilih \'Jangan optimalkan\' setelah mengeklik \'%2$s\' dalam dialog ini. + Jangan tanya lagi? Penggunaan HTTP tidak aman. Kami menyarankan untuk menggunakan HTTPS sebagai gantinya. Jika Anda mengetahui risikonya, Anda dapat melanjutkan dengan HTTP. Ubah ke HTTPS Gunakan HTTPS? diff --git a/presentation/src/main/res/values-ja-rJP/strings.xml b/presentation/src/main/res/values-ja-rJP/strings.xml index c3597e4e..88f35bd9 100644 --- a/presentation/src/main/res/values-ja-rJP/strings.xml +++ b/presentation/src/main/res/values-ja-rJP/strings.xml @@ -9,6 +9,8 @@ ネットワーク接続がありません パスワードが正しくありません ファイルかフォルダーが既に存在します。 + 金庫のバージョン %1$s はサポートされていません。この金庫は、現在のものより古いか新しいバージョンの Cryptomator で作成されています。 + %1$s ファイルが金庫のフォルダーに見つかりませんでした。クラウドの金庫フォルダーにこのファイルが存在することをご確認ください。 金庫が既に存在します。 ファイルが存在しません。 金庫が施錠されました。 @@ -272,6 +274,7 @@ 詳細 これはセキュリティリスクになる可能性があります。リスクについて理解していますか バッテリーの最適化を無効にする + バックグラウンド中に新しい画像やビデオを取得するには、バッテリーの最適化オプションからオプトアウトする必要があります。%1$s が多くのエネルギーを消費することはありません。\n\n 「最適化されていない状態」から「すべてのアプリ」に変更するには、このダイアログで \'%2$s\' をクリックした後に、%1$s を選び「最適化しない」を指定してください。 今後確認しない HTTP は安全ではありません。代わりに HTTPS を使用することを推奨します。リスクを承知の上であれば HTTP をご使用ください。 HTTPS を使用 diff --git a/presentation/src/main/res/values-nb-rNO/strings.xml b/presentation/src/main/res/values-nb-rNO/strings.xml index 8a85bf35..e15f0695 100644 --- a/presentation/src/main/res/values-nb-rNO/strings.xml +++ b/presentation/src/main/res/values-nb-rNO/strings.xml @@ -9,6 +9,8 @@ Ingen nettverkstilkobling Feil passord En fil eller mappe finnes allerede. + Versjon %1$s av hvelvet støttes ikke. Dette hvelvet har blitt opprettet med en eldre eller nyere versjon av Cryptomator. + %1$s filen mangler i mappen til hvelvet ditt. Sørg for at filen eksisterer i hvelvet ditt i skyen. Hvelvet finnes allerede. Filen finnes ikke. Hvelvet har blitt låst. @@ -22,8 +24,16 @@ Navn på hvelvet kan ikke inneholde spesialtegn. Oppdateringskontrollen mislyktes. Det oppstod en generell feil. Oppdateringskontrollen mislyktes. Den beregnede hash-koden stemmer ikke med den opplastede filen + Oppdateringssjekken mislyktes. Ingen internettforbindelse. + Klarte ikke å dekryptere WebDAV-passord, vennligst legg inn nytt i innstillingene + Google Play Services er ikke installert Biometrisk autentisering avbrutt - Egendefinert posisjon for Masterkey er foreløpig ikke støttet + Versjon spesifisert i %1$s er forskjellig fra %2$s + %1$s samsvarer ikke med denne %2$s + Generell feil under lasting av hvelvkonfigurasjon + Lokal fil finnes ikke lenger etter å ha byttet tilbake til Cryptomator. Mulige endringer kan ikke sendes tilbake til skyen. + Ingen slik bøtte + Egendefinert lokasjon for Hovednøkkel er foreløpig ikke støttet Lokal lagring @@ -37,7 +47,7 @@ Søk Forrige Neste - Sorter + Sortere A - Å Å - A Nyeste først @@ -51,17 +61,26 @@ Legg til et eksisterende hvelv Fjern Klikk her for å lage et nytt hvelv + Passordet er endret Hvelv + Velg hovednøkkelfil Plasser her - Hvelvnavn: %1$s + Navn på hvelvet: %1$s + + Flytt %1$s til + Flytt %2$d elementer til + Flytt Tom mappe endret for %1$s siden Del med + Velg en lokasjon Velg + Ingenting å dele + Legg til %1$s Opprett mappe - Lag en tekstfil + Opprett tekstfil Last opp filer Filer Fil eksportert @@ -95,19 +114,31 @@ Skylagringstjeneste + Velg en plassering + Klikk her for å legge til lokasjoner Serveren ser ikke ut til å være WebDAV-kompatibel + Ingen filbehandler funnet som støtter å åpne mapper URL Brukernavn Passord + Koble til URL-adressen kan ikke være tomt. + URL-en er ugyldig. Brukernavnet kan ikke være tomt. Passordet kan ikke være tomt. Visningsnavn + Tilgangsnøkkel + Hemmelig nøkkel + Eksisterende bøtte + Endepunkt + Region Visningsnavn kan ikke være tomt Tilgangsnøkkel kan ikke være tom Hemmelig nøkkel kan ikke være tom + Bøtte kan ikke være tom + Endepunkt eller region kan ikke være tomt Navnet på hvelvet kan ikke være tomt. Hvelvnavn @@ -116,7 +147,9 @@ Angi passord Passordene stemmer ikke overens. Ferdig + VIKTIG: Hvis du glemmer passordet ditt, er det ikke mulig å gjenopprette dataene dine. Gjenta passordet + For svakt for å lage et hvelv Svakt Ok Sterkt @@ -127,30 +160,57 @@ Biometrisk autentisering Aktiver biometrisk autentisering Bekreft ansiktsopplåsing (hvis tilgjengelig) + Blokker app når tilslørt + Blokker å fange opp inndata samt visning av falsk brukergrensesnitt + Blokker skjermbilder + Blokker skjermbilder i sist brukte-listen og i programmet Søk + Live søk + Oppdater søkeresultater mens du angir spørringen + Søk med glob mønster + Bruk glob mønster tilsvarende som alice.*.jpg + Automatisk låsing Lås etter + Når skjermen er deaktivert + Automatisk bildeopplasting + Velg hvelv for opplasting Aktiver + Fang bilder i bakgrunnen og når det valgte hvelvet er ulåst, start opplasting + Last opp øyeblikkelig + Last opp direkte hvis hvelvet er låst opp + Last opp kun ved hjelp av WIFI Last opp videoer + Lagre de automatisk opplastede filene til … Cryptomators nettside Følg oss på Twitter Lik oss på Facebook Juridisk Lisenser + Lisensvilkår Brukerstøtte Be om hjelp Feilsøkingsmodus Send loggfil Sending feilet + Sikkerhetstips Versjon Avanserte innstillinger + Akselerer opplåsing + Last ned hvelvkonfigurasjonen i bakgrunnen mens du blir bedt om å skrive inn passord eller biometrisk autentisering + Behold ulåst + Beholdt hvelvet opplåst mens du redigerer filer + OneDrive tilkoblinger WebDAV-tilkoblinger pCloud-tilkoblinger + S3 tilkoblinger + Lokal lagringsplass Logg inn i Logg ut fra %1$s kunne ikke autentiseres. + Oppdater pCloud legitimasjoner Avbryt @@ -160,19 +220,29 @@ Bytt passord Feltet for gjeldende passord kan ikke være tomt. Feltet for nytt passordet kan ikke være tomt. + Det nye passordet stemmer ikke overens med det har skrevet på nytt. Hvelvet %1$s ble ikke funnet + Hvelvet har fått nytt navn, blitt endret eller slettet. Fjern hvelvet fra listen og legg det til igjen for å fortsette. Fjern nå? Fjern Filen finnes allerede Erstatt + En fil med navnet \'%1$s\' finnes allerede. + Hopp over eksisterende Erstatt alle + Erstatt eksisterende Erstatt + En fil med navnet \'%1$s\' finnes allerede. Vil du erstatte den? + Alle filene finnes allerede. Vil du erstatte dem? + %1$d filer finnes allerede. Vil du erstatte dem? Erstatt fil? Erstatt filene? Kunne ikke dele filene + Du har ikke konfigurert noen hvelv. Vennligst lag et nytt hvelv med Cryptomator appen først. Ok Opprett hvelv Kan ikke åpne %1$s + Last ned en app som kan åpne denne filen, eller vil du lagre filen på enheten? Endre navn på hvelvet Endre mappenavn Endre filnavn @@ -188,27 +258,145 @@ Vent litt… Oppretter mappe… Oppretter tekstfil… + Autentisering… + Gir nytt navn… Sletter… + Låser opp hvelv… + Endrer passord… + Oppretter hvelv… Laster opp… + Laster ned… + Krypterer… + Dekrypterer… + Flytter… Lås + Ugyldig SSL sertifikat + SSL-sertifikatet er ugyldig. Vil du stole på det likevel? + Detaljer + Dette kan være en sikkerhetsrisiko. Jeg vet hva jeg gjør. + Deaktiver batterioptimaliseringer + For å hente nye bilder og videoer uten å kjøre i bakgrunnen, må vi velge bort batterioptimaliseringer. Men ikke bekymre deg, %1$s konsumerer ikke mye energi.\n\nFor å bruke den, endre \'Ikke optimalisert\' til \'Alle apper\', velg %1$s og velg \'Ikke optimaliser\' etter å ha klikket \'%2$s\' i denne dialogboksen. + Ikke spør igjen? + Bruk av HTTP er usikker. Vi anbefaler å bruke HTTPS i stedet. Hvis du er klar over risikoen, kan du fortsette med HTTP. + Endre til HTTPS + Bruk HTTPS? + Ingen skjermlås er satt. For å lagre dine innloggingsopplysninger på en sikker måte, sett med OK et mønster eller passord. + Sett skjermlås? + Sett skjermlås + Ingen grunnleggende autentisering er satt opp i systemet + Registrer minst én finger/ansikt for å bruke denne tjenesten. + I denne modusen kan sensitive data skrives til en loggfil på enheten (f.eks. filnavn og stier). Passord, cookies, etc. er eksplisitt ekskludert.\n\nHusk å deaktivere feilsøkingsmodus så snart som mulig. + Merk følgende + Aktiver + Denne innstillingen er en sikkerhetsfunksjon og forhindrer andre apper fra å lure brukere til å gjøre ting de ikke ønsker å gjøre.\n\nved å deaktivere, bekrefter du at du er oppmerksom på risikoen. + Merk følgende + Deaktiver + Appen er tilslørt + En annen app viser noe på toppen av Cryptomator (f.eks. en blått lysfilter eller nattmodusapp). Av sikkerhetsgrunner er Cryptomator deaktivert.\n\nHvordan aktivere Cryptomator Lukk + Vennligst legg til hvelv på nytt for %1s sky + Mens vi migrerer til denne appversjonen må vi fjerne følgende hvelv fra appen:\n%2s \n\nDisse hvelvene er ikke fjernet fra skyen, men bare fra denne appen. Beklager ulempen. Legg disse hvelvene til på nytt for å fortsette å jobbe med dem. + Hvelvet er rotmappen på skytilkoblingen + Opprett en ny sky-tilkobling der du velger minst den overordnede mappen av dette hvelvet sin mappe som rotkatalog for å legge til dette hvelvet. + Denne innstillingen er en sikkerhetsfunksjon og forhindrer andre apper fra å lure brukere til å gjøre ting de ikke ønsker å gjøre.\n\nVed å deaktivere bekrefter du at du er oppmerksom på risikoen. Er du sikker på at du vil fjerne denne skylagringstilkoblingen? Denne handlingen vil fjerne skylagringsforbindelsen og alle hvelv i denne skyen. + Slette %1$d elementer? + Er du sikker på at du vil slette disse elementene? + Er du sikker på at du vil slette denne filen? + Dette vil slette hele mappens innhold. Er du sikker på at du vil slette mappen? + Biometrisk autentisering deaktivert + Fordi nøkkelen er ugyldig, er biometrisk autentisering deaktivert. For å re-aktivere, åpne innstillingene for Cryptomator. + Oppgi en gyldig lisens + Vi oppdaget at du installerte Cryptomator uten å bruke Google Play Store. Oppgi en gyldig lisens, som kan kjøpes på https://cryptomator.org/android/ + Den oppgitte lisensen er ikke gyldig. Kontroller at du har skrevet den inn riktig. + Denne nøkkelen er et skrivebord supporter sertifikat. Vennligst angi en gyldig lisens. + Ingen lisens oppgitt. Vennligst skriv inn en gyldig lisens. + Avslutt + Lisensbekreftelse + Takk %1$s for at du oppgir en gyldig lisens. + Oppdatering tilgjengelig + Oppdater Cryptomator til den nyeste versjonen. Ved å trykke OK laster vi ned appen i bakgrunnen og ber deg om å installere den. + Oppdater nå + Gå til nedlastingsside + Senere + Laster ned + Laster ned siste versjon av Cryptomator + Mappen er en symbolsk kobling + Du kan ikke navigere i denne symbolske lenken Tilbake + Kunne ikke laste innholdet i katalogen + Skymappen \'%1$s\' har ikke en gyldig mappefil. Det kan være at mappen ble opprettet på en annen enhet og er ennå ikke fullt synkronisert til skyen. Sjekk i skyen om følgende fil eksisterer og ikke er tom:\n%2$s + Ingen flere bilder å vise… + Legitimasjonen til \'%1$s\' er oppdatert + Hvis du planlegger å legge til en ny pCloud konto, klikk på denne nettadressen www.pcloud. om, logg ut fra gjeldende konto og klikk igjen på \'+\' i denne appen for å opprette en ny skyforbindelse. + Cryptomator trenger lagringstilgang for å bruke lokale hvelv + Cryptomator trenger lagringstilgang for å bruke automatisk bildeopplasting + Null kB + byte + kB + MB + GB + TB + sekund + sekunder + minutt minutter + time + timer + dag + dager + uke + uker + måned + måneder + år + år + Biometrisk innlogging + Logg inn med biometriske legitimasjon + Bruk hvelv passord + Kan ikke laste opp filer automatisk + Hvelv opplåst: %1$d + Autolås om %1$s + Lås alle + Avbryt opplasting + Automatisk bildeopplasting kjører + Laster opp %1d/%2d + Automatisk bildeopplasting fullført + %1$d bilder lastet opp til hvelvet + Automatisk bildeopplasting mislyktes + Generell feil oppstod under opplasting. + Valgte mappe for opplasting er ikke tilgjengelig lenger. Gå til innstillinger og velg en ny + Hvelvet ble låst under opplasting, åpne hvelvet på nytt for å fortsette + Det angitte hvelvet for automatisk opplasting eksisterer ikke lenger. + Åpne skrivbar fil + Hvelvet forblir opplåst til redigeringen er ferdig + Siste versjon er installert + Autentiserer… Hurtigminne Hurtigminnet åpnet nylig filer som er kryptert lokalt på enheten, for senere gjenbruk når de åpnes igjen Total hurtigminnestørrelse Tøm hurtigminnet Endringer vil bli tatt i bruk ved neste omstart av appen + Registrert for + %1$s + Intervall for å se etter oppdateringer + Se etter oppdateringer + Sist kjørt %1$s Hurtigminnestørrelse per skytjeneste + Med en gang + 1 minutt + 2 minutter + 5 minutter + 10 minutter + Aldri 50 MB 100 MB @@ -217,7 +405,12 @@ 1 GB 5 GB + Stil + Automatisk (følg systemet) Lys Mørk + Daglig + Ukentlig + Månedlig diff --git a/presentation/src/main/res/values-pt-rBR/strings.xml b/presentation/src/main/res/values-pt-rBR/strings.xml index b41531a8..714539db 100644 --- a/presentation/src/main/res/values-pt-rBR/strings.xml +++ b/presentation/src/main/res/values-pt-rBR/strings.xml @@ -1,9 +1,9 @@ - Encriptar + Criptografar - Ocorreu um erro + Um erro ocorreu Falha de autenticação Falha na autenticação, por favor faça o login usando %1$s Sem conexão com a internet @@ -48,11 +48,11 @@ Anterior Próximo Ordenar - A - Z - Z - A + A — Z + Z — A Mais recentes primeiro - Mais antigos primeiro - Maior primeiro + Antigos primeiro + Maiores primeiro Menores primeiro diff --git a/presentation/src/main/res/values-sw-rTZ/strings.xml b/presentation/src/main/res/values-sw-rTZ/strings.xml new file mode 100644 index 00000000..b1f67a72 --- /dev/null +++ b/presentation/src/main/res/values-sw-rTZ/strings.xml @@ -0,0 +1,411 @@ + + + + Shiriki_na_maandiko + + Hitilafu imetokea + Uthibitisho umeshindikana + Uthibitisho umeshindikana, tafadhali ingia kwa kutumia %1$s + Hakuna muunganisho wa mtandao + Neno la siri si sahihi + Faili au folda tayari imekuwepo. + Toleo la kuba %1$s haikubaliki. Kuba hii imeundwa na toleo la zamani au jipya zaidi Cryptomator. + %1$s faili halipo kwenye folda yako ya kuba. Hakikisha kuwa faili hili lipo kwenye folda yako kwenye wingu. + Kuba tayari ipo. + Faili haipo. + Kuba imefungwa. + Wingu tayari lipo. + Tafadhali pakua programu amabyo inaweza kufungua faili hii. + Server haijapatikana. + Tafadhali fungua mpangilio wa kifaa chako na useti loku ya skrini kwa mkono + Uhamishaji umeshindikana. Jaribu kuondoa vibambo maalum kutoka kwa majina ya faili na kuhamisha tena. + Haiwezi kuwa na vibambo maalum. + Jina na la faili haliwezi kuwa na vibambo maalum. + Jina la kuba haliwezi kuwa na vibambo maalum. + Kagua sasishi imeshindikana. Kosa la jumla limetokea. + Kagua sasishi imeshindikana. Hash iliyohesabiwa haioani na faili iliyopakiwa + Kagua sasishi imeshindikana. Hakuna muunganisho wa tovuti. + Imeshindwa kusimbua neno la siri ya WebDAV, tafadhali ongeza tena katika mpangilio + Huduma ya Google Play haijasanikishwa + Uhalalishaji wan biometriska umefutwa + Toleo lililobainishwa katika %1$s ni tofati na %2$s + %1$s hailingani na hii %2$s + Kosa la jumla wakati wa kupakia conf ya kuba + Faili ya ndani haipo tena baada ya kurudi kwenye Cryptomator. Mabadiliko yanayowezekana hayawezi kuenezwa tena kwenye wingu. + Hakuna ndoo ya utafutaji + Mahali maalumu pa Masterkey bado haijategemezwa bado + + + Hifadhi ya ndani + + + Cryptomator inahitaji ufikiaji wa kuhifadhi ili kuhamisha mafaili + Cryptomator inahitaji ufikiaji wa kuhifadhi ili kupakia mafaili + Cryptomator inahitaji ufikiaji wa kuhifadhi ili kusiriki mafaili + Cryptomator imepoteza ruhusa ya kufikia mahali hapa. Tafadhali teua kabrasha hili tena ili kurejesha kibali. + Kipimo + Tafuta + Iliyotangulia + Ijayo + Panga + A-Z + Z-A + Mpya zaidi ya kwanza + Zamani zaidi ya kwanza + Kubwa ya kwanza + Ndogo ya kwanza + + + Ongeza kwenye Cryptomator + Unda kuba mpya + Ongeza kuba iliyopo + Ondoa + Bofya hapa ili kuunda kuba mpya + Neno la siri limebadilishwa kwa ufanisi + + Kuba + Teua faili ya masterkey + Weka hapa + Jina la kuba: %1$s + Hamisha + Kabrasha tupu + imerekebishwa %1$s iliyopita + Shiriki na + Chagua fikio + Chagua + Hakuna kitu cha kushiriki + Ongeza kwenye %1$s + Unda kabrasha + Unda faili matini + Pakia mafaili + Mafaili + Faili imehamishwa + Faili zilizohamishwa + Hakuna kitu cha kuuza nje + Kuunda mpangilio orodha wa upakuaji umeshindikana + Kushiriki + Ita jina jipya + Hariri + Hamisha + Futa + Funga na… + Teua vipengee + %1$d teuliwa + Teua + Teua zote + Onesha upya + Hakuna muunganisho + Jaribu tena + + Imehifadhiwa kwa ufanisi + + Hifadhi %1$s kwa … + ujumbe + faili + mafaili + Majina ya faili yanapaswa kuwa ya kipekee, tafadhali badilisha jina la nakala. + Hifadhi mahali + Hifadhi + Usimbaji fiche umekamilika + + Huduma ya wingu + + Chagua mahali + Bofya hapa ili kuongeza mahali + Seva haionekani kuwa sambamba na WebDAV + Hakuna faili maneja lililopatikana inasaidia kufungua saraka + + URL + Jina la mtumiaji + Neno la siri + Kuunganisha + URL haiwezi kuwa tupu. + URL ni batili. + Jina la mtumiaji haliwezi kuwa tupu. + Neno la siri haliwezi kuwa tupu. + + Onyesha Jina + Ufunguo wa Ufikivu + Ufunguo wa Siri + Ndoo Iliyopo + Mwisho pointi + Mkoa + Onyesha Jina haliwezi kuwa tupu + Ufunguo wa Ufikivu hauwezi kuwa tupu + Ufunguo wa Siri hauwezi kuwa tupu + Ndoo haiwezi kuwa tupu + Mwisho au Mkoa haliwezi kuwa tupu + + Jina la kuba haliwezi kuwa tupu. + Jina la kuba + Unda + + Seti neno la siri + Nywila haioani na nywila iliyochapwa upya. + Tayari + MUHIMU: Ikiwa unasahau neno la siri lako, hakuna njia ya kurejesha data yako. + Chapa upya neno la siri + Dhaifu sana kuunda kuba + Dhaifu + Haki + Imara + Imara sana + + Jumla + Huduma za wingu + Uhalalishaji wa Biometriska + Amilisha uhalalishaji wa biometriska + Thibitisha kufungua uso (ikiwa inapatikana) + Zuia programu wakati imefichwa + Zuia kuzuia ingizo na kuonyesha kiolesura cha uongo cha mtumiaji + Zuia viwambo + Zuia viwambo katika orodha ya hivi karibuni na ndani ya programu + Tafuta + Utafutaji wa moja kwa moja + Sasisha matokeo ya utafutaji wakati wa kuingiza ulizo + Tafuta kwa kutumia muundo wa glob + Tumia muundo wa glob unaolingana kama alice.*.jpg + Ufungashaji Otomatiki + Funga baada ya + Wakati skrini imelemazwa + Upakiaji wa picha Otomatiki + Chagua kuba kwa ajili ya kupakia + Kuamilisha + Kukamata picha kwa nyuma na mara tu kuba iliyochaguliwa inapofunguliwa, anza kupakia + Pakia papo hapo + Pakia moja kwa moja ikiwa kuba imefunguliwa + Pakia tu kwa kutumia WIFI + Pakia video + Hifadhi faili za kupakia kiotomatiki kwenye … + Tovuti ya Cryptomator + Tufuate kwenye Twitter + Kisheria + Leseni + Masharti ya leseni + Msaada + Omba msaada + Rekebisha hali + Tuma faili logi + Kutuma kumeshindikana + Vidokezo vya usalama + Toleo + Mipangilio Pevu + Kuharakisha kufungua + Pakua usanidi wa kuba mandharinyuma unapoombwa kuingiza nenosiri au auth ya biometriska + Endelea kufungua + Weka kuba wazi wakati wa kuhariri faili + + Miunganisho ya OneDrive + Miunganisho ya WebDAV + miunganisho ya pCloud + Miunganisho ya S3 + Maeneo ya hifadhi ya ndani + Ingia kwenye + Ondoka kutoka + + + %1$s haikuweza kuthibitishwa. + Sasisha hati za utambulisho za pCloud + + + Katisha + Fungua + Neno la siri la zamani + Neno la siri jipya + Badilisha neno la siri + Neno la siri la zamani haliwezi kuwa tupu. + Neno la siri jipya haliwezi kuwa tupu. + Nneno la siri jipya haioani na neno la siri lililochapwa upya. + + Kuba%1$s haijapatikana + Kuba imepewa jina jipya, kuhamishwa au kufutwa. Ondoa kuba hii kutoka kwenye orodha na uiongeze tena ili kuendelea. Ondoa sasa? + Ondoa + Faili tayari ipo + Badilisha + Faili inayoitwa \'%1$s\' tayari ipo. + Ruka iliyopo + Badilisha yote + Badilisha iliyopo + Badilisha + Faili inayoitwa \'%1$s\' tayari ipo. Unataka kuibadilisha? + Faili zote tayari zipo. Unataka kubadilisha yao? + %1$d faili tayari zipo. Unataka kubadilisha yao? + Badilisha faili? + Badilisha faili? + Haiwezi kugawiza mafaili + Hujasanidi kuba yoyote. Tafadhali unda kuba mpya na programu ya Cryptomator kwanza. + Sawa + Unda kuba + Haiwezi fungua%1$s + Tafadhali pakua programu ambayo inaweza kufungua faili hii au unapenda kuhifadhi kwenye kifaa chako? + Ita jina jipya kuba + Ita jina jipya kabrasha + Ita jina jipya la faili + Una mabadiliko ambayo hayajahifadhiwa + Je, kweli unataka kuacha bila kuhifadhi? + Tupa + ujumbe.txt + Una uhakika unataka kuondoa kuba hii? + Kitendo hiki kitaondoa tu kuba kutoka kwenye orodha hii na sio kuifuta kimwili. + Inapakia… + Faili %1$d ya %2$d + Kusafirisha (%1$d/%2$d) + Tafadhali subiri… + Kuunda kabrasha… + Unda faili matini… + Uhalalishaji… + Inaita jina jipya… + Kufuta… + Inafungua kuba… + Kubadilisha neno la siri… + Kutengeneza kuba… + Inapakia… + Inapakua… + Inasimba… + Kusimbua =… + Kusonga… + Funga + Cheti batili cha SSL + Heti cha SSL ni batili. Je, unataka kuamini hilo hata hivyo? + Maelezo + Hii inaweza kuwa hatari kwa usalama. Najua kile ninachofanya. + Lemaza uboreshaji wa betri + Ili kupata picha na video mpya bila kukimbia kwa mandharinyuma, tunahitaji kuchagua kutoka kwa uboreshaji wa betri. Lakini usijali, %1$s haitumii nishati nyingi.\n\nKuitumia, badilisha \'Haijaboreshwa\' kuwa \'Programu zote\', chagua %1$s na uchague \'Usiboreshe\' baada ya kubofya \'%2$s\' katika mazungumzo haya. + Je, si kuuliza tena? + Matumizi ya HTTP ni salama. Tunapendekeza kutumia HTTPS badala yake. Ikiwa unajua hatari, unaweza kuendelea na HTTP. + Badilisha hadi HTTPS + Tumia HTTPS? + Hakuna kufuli ya skrini iliyowekwa. Ili kuhifadhi hati zako za utambulisho kwa njia salama, weka na Sawa muundo au neno la siri. + Weka kufuli skrini? + Weka kufuli skrini + Hakuna uhalalishaji wa msingi uliosanidiwa katika mfumo + Jiandikishe angalau kidole kimoja / uso ili kutumia huduma hii. + Katika hali hii, data nyeti inaweza kuandikwa kwa faili ya kumbukumbu kwenye kifaa chako (kwa mfano, majina ya faili na njia). Nywila, vidakuzi, n.k. zimetengwa wazi.\n\nKukumbuka ili kuzima hali ya utatuzi haraka iwezekanavyo. + Makini + Wezesha + Mpangilio huu ni kipengele cha usalama na huzuia programu zingine kuwadanganya watumiaji kufanya mambo ambayo hawastahili kufanya.\n\nKuzima, unathibitisha kuwa wewe ni kujishwa na hatari. + Makini + Lemaza + Programu imefichwa + Programu nyingine inaonyesha kitu juu ya Cryptomator (kwa mfano, kichujio cha mwanga wa bluu au programu ya hali ya usiku). Kwa sababu za usalama, Cryptomator imezimwa..\n\nHow to enable Cryptomator + Funga + Tafadhali ongeza tena kuba kwa %1s wingu + Wakati wa kuhamia kwenye toleo hili la programu tunahitaji kuondoa vaults zifuatazo kutoka kwa programu:\n%2s \n\nKuboreshaji hazijaondolewa kwenye wingu lakini tu kutoka kwa programu hii. Samahani kwa usumbufu na tafadhali ongeza tena vaults hizi ili kuendelea kufanya kazi nao. + Kuba ni folda ya mizizi ya muunganisho wa wingu + Unda muunganisho mpya wa wingu ambapo unachagua angalau folda kuu ya folda hii ya kuba kama saraka ya mizizi ili kuongeza kuba hii. + Mpangilio huu ni kipengele cha usalama na huzuia programu zingine kuwadanganya watumiaji kufanya mambo ambayo hawastahili kufanya.\n\nKuzima, unathibitisha kuwa wewe ni aware of the risks. + Una hakika unataka kuondoa muunganisho huu wa wingu? + Hatua hii itaondoa unganisho la wingu na kuba zote za wingu hili. + Futa %1$d vipengee? + Una hakika unataka kufuta vipengee hivi? + Una hakika unataka kufuta faili hili? + Hii itafuta yaliyomo kwenye folda yote. Una hakika unataka kufuta kabrasha hili? + Kipengele cha uthibitishaji wa Biometriska kimezimwa + Kwa sababu ufunguo umebatilishwa, kipengele cha uthibitishaji wa biometriska kimezimwa. Ili kuwezesha tena, fungua mipangilio ya Cryptomator. + Toa leseni halali + Tuligundua kuwa ulisakinisha Cryptomator bila kutumia Duka la Google Play. Toa leseni halali, ambayo inaweza kununuliwa kwenye https://cryptomator.org/android/ + Leseni iliyotolewa sio halali. Hakikisha umeiingiza kwa usahihi. + Ufunguo uliotolewa ni cheti cha msaidizi wa eneo-kazi. Tafadhali ingiza leseni halali. + Hakuna leseni iliyotolewa. Tafadhali ingiza leseni halali. + Toka + Uthibitisho wa leseni + Asante %1$s kwa kutoa leseni yako halali. + Sasisha inapatikana + Sasisha Cryptomator hadi toleo la hivi karibuni. Kwa kubonyeza Sawa tutapakua programu chinichini na tutakuuliza uikinishe. + Sasisha sasa + Nenda kwenye tovuti ya kupakua + Baadae + Upakuaji unaendesha + Inapakua toleo la hivi karibuni la Cryptomator + Kabrasha ni kiungo cha mfano + Huwezi kuingia kwenye kiungo hiki cha mfano + Rudi + Haiwezi kupakia yaliyomo kwenye mpangilio orodha + Folda ya wingu \'%1$s\' haina faili halali ya saraka. Inaweza kuwa kwamba folda iliundwa kwenye kifaa kingine na bado haijalandanishwa kikamilifu kwenye wingu. Tafadhali angalia katika wingu lako ikiwa faili ifuatayo ipo na sio tupu:\n%2$s + Hakuna picha zaidi za kuonyesha… + Hati za utambulisho za \'%1$s\' zimesasishwa + Ikiwa ulikusudia kuongeza akaunti mpya ya pWingu, bofya url hii www.pcloud.com, log kutoka kwa akaunti ya sasa na ubofye tena kwenye \' \' katika programu hii ili kuunda muunganisho mpya wa wingu. + Cryptomator inahitaji ufikiaji wa kuhifadhi ili kutumia kuba za ndani + Cryptomator inahitaji ufikiaji wa kuhifadhi ili kutumia upakiaji wa picha kiotomatiki + + + + Sifuri kB + baiti + kB + MB + GB + TB + + sekunde + sekunde + dakika + dakika + saa + masaa + siku + siku + wiki + wiki + mwezi + miezi + mwaka + miaka + + Kuingia kwa Biometriska + Ingia kwa kutumia hati yako ya utambulisho ya biometriska + Tumia neno la siri ya kuba + Haiwezi kupakia faili otomatiki + + Kuba imefunguliwa:%1$d + Otomatiki loku ndani ya %1$s + Funga zote + Katisha upakiaji + Upakiaji wa picha kiotomatiki unaendelea + Inapakia %1d/%2d + Upakiaji wa picha otomatiki umekamilika + %1$d picha zilizopakiwa kwenye kuba + Upakiaji wa picha otomatiki umeshindikana + Kosa la jumla limetokea wakati wa kupakia. + Kabrasha lililoteuliwa la kupakia halipatikani tena. Nenda kwenye mipangilio na uchague mpya + Kuba imefungwa wakati wa kupakia, tafadhali fungua tena kuba ili kuendelea + Kuba iliyobainishwa kwa upakiaji wa kiotomatiki haipo tena. + Fungua faili linalo andikika + Kuba inakaa wazi hadi uhariri uliomalizika + Toleo la hivi karibuni lililosakinishwa + Kuthibitisha… + Kache + Akiba faili zilizofikiwa hivi karibuni zimesimbwa kwa njia fiche ndani ya kifaa kwa matumizi ya baadaye inapofunguliwa tena + Ukubwa wa jumla wa kache + Ondoa Kache + Mabadiliko yatatekelezwa kwenye uanzishaji upya wa programu inayofuata + Imesajiliwa kwa ajili ya + %1$s + Sasisha muda wa ukaguzi + Kagua sasishi + Endesha mwisho%1$s + Ukubwa wa kache kwa kila Wingu + + Papohapo + 1 dakika + 2 dakika + 5 dakika + 10 dakika + Kamwe + + 50 MB + 100 MB + 250 MB + 500 MB + 1 GB + 5 GB + + Mtindo + Moja kwa moja (kufuata mfumo) + Mwanga + Giza + + Mara moja kwa siku + Mara moja kwa wiki + Mara moja kwa mwezi + diff --git a/presentation/src/main/res/values-zh-rCN/strings.xml b/presentation/src/main/res/values-zh-rCN/strings.xml index e384ad5a..bfc189bc 100644 --- a/presentation/src/main/res/values-zh-rCN/strings.xml +++ b/presentation/src/main/res/values-zh-rCN/strings.xml @@ -160,20 +160,20 @@ 启用生物识别认证 确认人脸解锁 (如果有) 被遮罩 (比如某些护眼应用) 时停用 Cryptomator - 阻止 \"输入拦截以及显示错误/诱导性的用户界面\" + 阻止 \"输入拦截以及显示错误、诱导性的用户界面\" 防截屏 在最近任务和应用内阻止截图 搜索 实时搜索 - 边输入边更新搜索结果 + 随输入实时更新搜索结果 使用 glob 模式搜索 使用诸如 alice.*.jpg 的 glob 模式匹配 自动锁定 超时锁定 - 息屏后 + 屏幕锁定后 自动上传图片 选择目标保险库 - 激活 + 启用 后台感知图片,一旦目标保险库解锁即开始上传 实时上传 解锁保险库后直接上传 @@ -284,7 +284,7 @@ 设置屏幕锁 系统中未设置基本身份验证 注册至少一个指纹/面部以使用此服务 - 在此模式下,敏感数据可能会写入您设备上的日志文件 (例如文件名和路径)。密码、cookies等除外\n\n请记住尽快关闭调试模式 + 在此模式下,敏感数据可能会写入您设备上的日志文件 (例如文件名和路径)。密码、cookies等除外\n\n请记住要尽快关闭调试模式 请注意 启用 此为一项安全功能,可防止其他应用诱使用户做出错误操作\n\n如果禁用,即表示您了解其中风险 diff --git a/presentation/src/main/res/values-zh-rTW/strings.xml b/presentation/src/main/res/values-zh-rTW/strings.xml index 693c5d5c..6f1f7382 100644 --- a/presentation/src/main/res/values-zh-rTW/strings.xml +++ b/presentation/src/main/res/values-zh-rTW/strings.xml @@ -159,18 +159,27 @@ 生物識別驗證 開啓生物識別驗證 確認面容解鎖(如果可用) + 被遮擋時阻止應用程序 + 阻止攔截輸入並顯示錯誤的用戶界面 禁用截圖 + 在對話清單或應用程式內停用畫面擷取功能 搜尋 即時搜尋 + 輸入查詢時更新搜索結果 + 使用 glob pattern 模式搜索 + 使用像 alice.*.jpg 这样的 glob pattern 模式搜索 自動鎖定 在多久後鎖定 當螢幕被鎖定 自動上傳像片 選擇要上傳的加密檔案庫 啟動 + 在後台捕獲圖像,一旦選定的加密檔案庫被解鎖,開始上解鎖 即時上傳 + 如果加密檔案庫已解鎖,則直接上傳 僅使用 Wi-Fi 上傳 上傳影片 + 將自動上傳文件保存到 … Cryptomator 網站 在 Twitter 上追蹤我們 在臉書上給我們點讚 @@ -186,7 +195,9 @@ 版本 進階設定 加速解鎖 + 在提示輸入密碼或生物識別身份驗證時在後台下載保險庫配置 保持解鎖 + 編輯文件時保持加密檔案庫解鎖 OneDrive 連結 WebDAV 連線 @@ -226,9 +237,11 @@ 替換檔案? 要取代檔案嗎? 無法分享檔案 + 您尚未設置任何加密檔案庫。 請先使用 Cryptomator 應用程序創建一個新的保管庫。 確認 新建加密檔案庫 無法打開%1$s + 請下載一個可以打開此文件的應用程序,或者您想保存到您的設備嗎? 重命名加密檔案庫 重命名檔案夾 重新命名檔案 @@ -237,11 +250,14 @@ 放棄 文本.txt 您確定要刪除這個加密檔案庫嗎? + 此操作只會從該列表中刪除加密檔案庫,而不是物理刪除它。 正在上傳中…… + 第%1$d个(共%2$d个) 正在導出中(%1$d/%2$d) 請稍候…… 正在創建資料夾…… 正在創建文本檔案…… + 正在驗證 … 正在重命名…… 正在删除… 正在解鎖加密檔案庫…… @@ -257,39 +273,63 @@ 這個 SSL 認證無效,您仍要信任它嗎? 詳情 這可能會是個安全風險。我清楚我在做什麼。 + 停用電池效能最佳化設定 + 要在不在後台運行的情況下檢索新圖片和視頻,我們需要選擇退出電池優化。 不過不用擔心,%1$s 不會消耗太多能量。\n\n要應用它,請將“未優化”更改為“所有應用”,選擇 %1$s 並在點擊後選擇“不優化” 此對話框中的“ %2$s ”。 + 不要再詢問? 使用 HTTP 是不安全的。我們推薦使用 HTTPS 來取代。如果您瞭解風險,您可以使用 HTTP 繼續。 更換為 HTTPS 是否使用 HTTPS? + 未設置屏幕鎖定。 要以安全的方式存儲您的憑據,請使用 OK 設置模式或密碼。 設定螢幕鎖定? 設定螢幕鎖定 + 系統中未設置基本身份驗證 + 註冊至少一個手指、面部以使用此服務。 + 在此模式下,敏感數據可能會寫入您設備上的日誌文件(例如文件名和路徑)。 密碼、cookies 等被明確排除在外。\n\n請記住盡快禁用調試模式。 注意 啟用 + 此設置是一項安全功能,可防止其他應用程序欺騙用戶做他們不想做的事情\n\n如果禁用這項功能,請確定你已經了解風險 注意 禁用 + 應用程序被遮擋 + 另一個應用程序在 Cryptomator 上顯示一些東西(例如,藍光過濾器或夜間模式應用程序)。出於安全考慮,Cryptomator 已經被禁用。\n\n怎樣啟用Cryptomator 關閉 + 請為 %1s 雲重新添加加密檔案庫 + 在遷移到此應用程序版本時,我們需要從應用程序中刪除以下保管庫\n%2s\n\n這些加密檔案庫不會從雲中刪除,而只是從這個應用程序中刪除。 很抱歉給您帶來不便,請重新添加這些加密檔案庫以繼續使用它們。 + 加密檔案庫是雲連接的根文件夾 + 創建一個新的雲連接,您至少選擇此加密檔案庫文件夾的父文件夾作為根目錄以添加此加密檔案庫。 + 此設置是一項安全功能,可防止其他應用程序欺騙用戶做他們不想做的事情\n\n如果禁用這項功能,請確定你已經了解風險 您確定要刪除此雲端連結嗎? + 此操作將刪除雲連接和該雲的所有加密檔案庫。 是否刪除%1$d個項目? 您確定要刪除這些項目嗎? 您確定要刪除這個檔案嗎? 這將會刪除檔案夾中的全部內容。您確定要刪除這個檔案夾嗎? 生物識別認證功能已關閉 + 由於密鑰已失效,生物特徵認證功能已停用。 要重新啟用,請打開 Cryptomator 設置 提供一個有效的許可證書 我們檢測到你沒有使用 Google Play 商店安裝 Cryptomator。提供一個有效的許可證書,證書可以從https://cryptomator.org/android/購買 提供的許可證書無效。請確認您輸入無誤。 + 提供的密鑰是桌面支持者證書。請輸入有效的許可證。 未提供許可證書。請輸入一個有效的許可證書。 退出 許可證書確認 + 感謝 %1$s 輸入你的密鑰 有可用更新 + 將 Cryptomator 更新到最新版本。 按 OK,我們將在後台下載該應用程序並要求您安裝它。 現在更新 前往下載網址 以後再說 正在下載 下載最新版本的 Cryptomator + 文件夾是符號鏈接 + 您無法導航到此符號鏈接 上一頁 無法讀取資料夾內的檔案資訊 + 雲文件夾“%1$s”沒有有效的目錄文件。 可能是該文件夾是在另一台設備上創建的,並且尚未完全同步到雲端。 如果以下文件存在且不為空,請檢查您的雲:\n%2$s 已無更多圖片可供顯示 … %1$s 的帳戶資訊已更新 如果您想要新增一個 pCloud 帳戶,請在點擊此連結 www.pcloud.com 後登出目前的帳號,並重新點擊本程式中的「+」來建立一個新的雲端連結。 + Cryptomator 需要存儲訪問權限用以使用本地加密檔案庫 Cryptomator 需要存儲權限以便開啟自動圖片上傳 @@ -339,6 +379,7 @@ 已安裝最新版本 正在驗證 … 緩存 + 緩存設備上本地加密的最近訪問的文件,以便以後重新打開時重複使用 緩存總大小 清除緩存 變更將會在應用程式下次重啓後啓用。 diff --git a/presentation/src/main/res/values/arrays.xml b/presentation/src/main/res/values/arrays.xml index 9998d544..6840e5ca 100644 --- a/presentation/src/main/res/values/arrays.xml +++ b/presentation/src/main/res/values/arrays.xml @@ -44,14 +44,10 @@ @string/update_interval_1d - @string/update_interval_1w - @string/update_interval_1m @string/update_interval_never 1 - 7 - 30 Never diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 47def0bb..915d78d0 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -600,8 +600,6 @@ Once a day - Once a week - Once a month @string/lock_timeout_never diff --git a/presentation/src/main/res/xml/preferences.xml b/presentation/src/main/res/xml/preferences.xml index be07dbd7..0ff1497c 100644 --- a/presentation/src/main/res/xml/preferences.xml +++ b/presentation/src/main/res/xml/preferences.xml @@ -244,7 +244,7 @@ android:title="@string/app_name" /> { - val updateInterval = defaultSharedPreferences.getValue(UPDATE_INTERVAL, "7") + fun updateIntervalInDays(): Optional { + val updateInterval = defaultSharedPreferences.getValue(UPDATE_INTERVAL, "1") if (updateInterval == "Never") { return Optional.absent() @@ -200,6 +200,12 @@ constructor(context: Context) : SharedPreferences.OnSharedPreferenceChangeListen return Optional.of(Integer.parseInt(updateInterval)) } + fun setUpdateIntervalInDays(days: Optional) = if (days.isPresent) { + defaultSharedPreferences.setValue(UPDATE_INTERVAL, days.get().toString()) + } else { + defaultSharedPreferences.setValue(UPDATE_INTERVAL, "Never") + } + fun lastUpdateCheck(): Date? { val date = defaultSharedPreferences.getString(LAST_UPDATE_CHECK, "") if (date.isNullOrEmpty()) { @@ -254,7 +260,7 @@ constructor(context: Context) : SharedPreferences.OnSharedPreferenceChangeListen fun vaultsRemovedDuringMigration(): Pair>? { val vaultsRemovedDuringMigrationType = defaultSharedPreferences.getString(VAULTS_REMOVED_DURING_MIGRATION_TYPE, null) val vaultsRemovedDuringMigration = defaultSharedPreferences.getString(VAULTS_REMOVED_DURING_MIGRATION, null) - return if(vaultsRemovedDuringMigrationType != null && vaultsRemovedDuringMigration != null) { + return if (vaultsRemovedDuringMigrationType != null && vaultsRemovedDuringMigration != null) { Pair(vaultsRemovedDuringMigrationType, ArrayList(vaultsRemovedDuringMigration.split(','))) } else { null