Merge branch 'release/1.6.5'
This commit is contained in:
commit
515a5f1766
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -1,7 +1,9 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
[push, pull_request]
|
||||
push:
|
||||
pull_request_target:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -2,7 +2,7 @@ apply from: 'buildsystem/dependencies.gradle'
|
||||
apply plugin: "com.vanniktech.android.junit.jacoco"
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.5.31'
|
||||
ext.kotlin_version = '1.6.0'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
@ -39,7 +39,7 @@ allprojects {
|
||||
ext {
|
||||
androidApplicationId = 'org.cryptomator'
|
||||
androidVersionCode = getVersionCode()
|
||||
androidVersionName = '1.6.4'
|
||||
androidVersionName = '1.6.5'
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -29,12 +29,12 @@ ext {
|
||||
rxAndroidVersion = '2.1.1'
|
||||
rxBindingVersion = '2.2.0'
|
||||
|
||||
daggerVersion = '2.40'
|
||||
daggerVersion = '2.40.2'
|
||||
|
||||
gsonVersion = '2.8.8'
|
||||
gsonVersion = '2.8.9'
|
||||
|
||||
okHttpVersion = '4.9.2'
|
||||
okHttpDigestVersion = '2.5'
|
||||
okHttpDigestVersion = '2.6'
|
||||
|
||||
velocityVersion = '2.3'
|
||||
|
||||
@ -74,9 +74,9 @@ ext {
|
||||
|
||||
// testing dependencies
|
||||
|
||||
jUnitVersion = '5.8.1'
|
||||
jUnitVersion = '5.8.2'
|
||||
assertJVersion = '1.7.1'
|
||||
mockitoVersion = '4.0.0'
|
||||
mockitoVersion = '4.1.0'
|
||||
mockitoKotlinVersion = '4.0.0'
|
||||
hamcrestVersion = '1.3'
|
||||
dexmakerVersion = '1.0'
|
||||
|
@ -0,0 +1,7 @@
|
||||
package org.cryptomator.domain.exception;
|
||||
|
||||
public class FileRemovedDuringUploadException extends BackendException {
|
||||
|
||||
public FileRemovedDuringUploadException() {
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import androidx.multidex.MultiDexApplication
|
||||
import org.cryptomator.data.cloud.crypto.Cryptors
|
||||
import org.cryptomator.data.cloud.crypto.CryptorsModule
|
||||
import org.cryptomator.data.repository.RepositoryModule
|
||||
import org.cryptomator.domain.Cloud
|
||||
import org.cryptomator.presentation.di.HasComponent
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent
|
||||
import org.cryptomator.presentation.di.component.DaggerApplicationComponent
|
||||
@ -20,6 +21,7 @@ import org.cryptomator.presentation.di.module.ThreadModule
|
||||
import org.cryptomator.presentation.logging.CrashLogging.Companion.setup
|
||||
import org.cryptomator.presentation.logging.DebugLogger
|
||||
import org.cryptomator.presentation.logging.ReleaseLogger
|
||||
import org.cryptomator.presentation.service.AutoUploadNotification
|
||||
import org.cryptomator.presentation.service.AutoUploadService
|
||||
import org.cryptomator.presentation.service.CryptorsService
|
||||
import org.cryptomator.util.NoOpActivityLifecycleCallbacks
|
||||
@ -37,7 +39,7 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
|
||||
private var cryptoServiceBinder: CryptorsService.Binder? = null
|
||||
|
||||
@Volatile
|
||||
private lateinit var autoUploadServiceBinder: AutoUploadService.Binder
|
||||
private var autoUploadServiceBinder: AutoUploadService.Binder? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@ -59,8 +61,8 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
|
||||
)
|
||||
Timber.tag("App").d("appId %s", BuildConfig.APPLICATION_ID)
|
||||
|
||||
launchServices()
|
||||
initializeInjector()
|
||||
launchServices()
|
||||
registerActivityLifecycleCallbacks(serviceNotifier)
|
||||
AppCompatDelegate.setDefaultNightMode(SharedPreferencesHandler(applicationContext()).screenStyleMode)
|
||||
cleanupCache()
|
||||
@ -106,7 +108,7 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
|
||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||
Timber.tag("App").i("Auto upload service connected")
|
||||
autoUploadServiceBinder = service as AutoUploadService.Binder
|
||||
autoUploadServiceBinder.init( //
|
||||
autoUploadServiceBinder?.init( //
|
||||
applicationComponent.cloudContentRepository(), //
|
||||
applicationComponent.fileUtil(), //
|
||||
applicationComponent.contentResolverUtil(), //
|
||||
@ -120,6 +122,10 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
|
||||
}, BIND_AUTO_CREATE)
|
||||
}
|
||||
|
||||
fun startAutoUpload(cloud: Cloud) {
|
||||
autoUploadServiceBinder?.startUpload(cloud)
|
||||
}
|
||||
|
||||
fun startAutoUpload() {
|
||||
val sharedPreferencesHandler = SharedPreferencesHandler(applicationContext())
|
||||
if (checkToStartAutoImageUpload(sharedPreferencesHandler)) {
|
||||
@ -130,9 +136,13 @@ class CryptomatorApp : MultiDexApplication(), HasComponent<ApplicationComponent>
|
||||
}
|
||||
if (vault?.isUnlocked == true) {
|
||||
val cloud = applicationComponent.cloudRepository().decryptedViewOf(vault)
|
||||
applicationContext().startService(AutoUploadService.startAutoUploadIntent(applicationContext(), cloud))
|
||||
startAutoUpload(cloud)
|
||||
} else if (vault == null) {
|
||||
applicationContext().startService(AutoUploadService.vaultNotFoundUploadIntent(applicationContext()))
|
||||
autoUploadServiceBinder?.vaultNotFound()
|
||||
?: run {
|
||||
Timber.tag("App").i("autoUploadServiceBinder not yet initialized, manually show notification")
|
||||
AutoUploadNotification(applicationContext, 0).showVaultNotFoundNotification()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import org.cryptomator.domain.usecases.vault.RenameVaultUseCase
|
||||
import org.cryptomator.domain.usecases.vault.SaveVaultUseCase
|
||||
import org.cryptomator.generator.Callback
|
||||
import org.cryptomator.presentation.BuildConfig
|
||||
import org.cryptomator.presentation.CryptomatorApp
|
||||
import org.cryptomator.presentation.R
|
||||
import org.cryptomator.presentation.exception.ExceptionHandlers
|
||||
import org.cryptomator.presentation.intent.Intents
|
||||
@ -42,7 +43,6 @@ import org.cryptomator.presentation.model.CloudTypeModel
|
||||
import org.cryptomator.presentation.model.ProgressModel
|
||||
import org.cryptomator.presentation.model.VaultModel
|
||||
import org.cryptomator.presentation.model.mappers.CloudFolderModelMapper
|
||||
import org.cryptomator.presentation.service.AutoUploadService
|
||||
import org.cryptomator.presentation.ui.activity.LicenseCheckActivity
|
||||
import org.cryptomator.presentation.ui.activity.view.VaultListView
|
||||
import org.cryptomator.presentation.ui.dialog.AppIsObscuredInfoDialog
|
||||
@ -386,12 +386,14 @@ class VaultListPresenter @Inject constructor( //
|
||||
.withCloud(cloud) //
|
||||
.run(object : DefaultResultHandler<CloudFolder>() {
|
||||
override fun onSuccess(folder: CloudFolder) {
|
||||
val vault = (folder.cloud as CryptoCloud).vault
|
||||
val cryptoCloud = (folder.cloud as CryptoCloud)
|
||||
val vault = cryptoCloud.vault
|
||||
view?.addOrUpdateVault(VaultModel(vault))
|
||||
navigateToVaultContent(vault, folder)
|
||||
view?.showProgress(ProgressModel.COMPLETED)
|
||||
if (checkToStartAutoImageUpload(vault)) {
|
||||
context().startService(AutoUploadService.startAutoUploadIntent(context(), folder.cloud))
|
||||
val cryptomatorApp = activity().application as CryptomatorApp
|
||||
cryptomatorApp.startAutoUpload(cryptoCloud)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -17,6 +17,7 @@ import org.cryptomator.presentation.ui.activity.VaultListActivity
|
||||
import org.cryptomator.presentation.util.ResourceHelper.Companion.getColor
|
||||
import org.cryptomator.presentation.util.ResourceHelper.Companion.getString
|
||||
import java.lang.String.format
|
||||
import timber.log.Timber
|
||||
|
||||
class AutoUploadNotification(private val context: Context, private val amountOfPictures: Int) {
|
||||
|
||||
@ -85,18 +86,22 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
|
||||
}
|
||||
|
||||
fun showFolderMissing() {
|
||||
Timber.tag("AutoUploadNotification").i("Show folder not found notification")
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_due_to_folder_not_exists))
|
||||
}
|
||||
|
||||
fun showVaultLockedDuringUpload() {
|
||||
Timber.tag("AutoUploadNotification").i("Show vault locked during upload notification")
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_due_to_vault_locked))
|
||||
}
|
||||
|
||||
fun showGeneralErrorDuringUpload() {
|
||||
Timber.tag("AutoUploadNotification").i("Show general error during upload notficiation")
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_general_error))
|
||||
}
|
||||
|
||||
fun showVaultNotFoundNotification() {
|
||||
Timber.tag("AutoUploadNotification").i("Show vault not found notification")
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_due_to_vault_not_found))
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.cryptomator.presentation.service;
|
||||
|
||||
import static org.cryptomator.domain.usecases.cloud.UploadFile.anUploadFile;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -17,6 +20,7 @@ import org.cryptomator.domain.exception.BackendException;
|
||||
import org.cryptomator.domain.exception.CancellationException;
|
||||
import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException;
|
||||
import org.cryptomator.domain.exception.FatalBackendException;
|
||||
import org.cryptomator.domain.exception.FileRemovedDuringUploadException;
|
||||
import org.cryptomator.domain.exception.MissingCryptorException;
|
||||
import org.cryptomator.domain.exception.NoSuchCloudFileException;
|
||||
import org.cryptomator.domain.repository.CloudContentRepository;
|
||||
@ -42,16 +46,10 @@ import java.util.Set;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.cryptomator.domain.usecases.cloud.UploadFile.anUploadFile;
|
||||
|
||||
public class AutoUploadService extends Service {
|
||||
|
||||
private static final String ACTION_START_AUTO_UPLOAD = "START_AUTO_UPLOAD";
|
||||
private static final String ACTION_CANCEL_AUTO_UPLOAD = "CANCEL_AUTO_UPLOAD";
|
||||
private static final String ACTION_VAULT_NOT_FOUND = "VAULT_NOT_FOUND";
|
||||
|
||||
private static Cloud cloud;
|
||||
private AutoUploadNotification notification;
|
||||
private CloudContentRepository cloudContentRepository;
|
||||
private ContentResolverUtil contentResolverUtil;
|
||||
@ -70,25 +68,12 @@ public class AutoUploadService extends Service {
|
||||
}
|
||||
};
|
||||
|
||||
public static Intent startAutoUploadIntent(Context context, Cloud myCloud) {
|
||||
cloud = myCloud;
|
||||
Intent startAutoUpload = new Intent(context, AutoUploadService.class);
|
||||
startAutoUpload.setAction(ACTION_START_AUTO_UPLOAD);
|
||||
return startAutoUpload;
|
||||
}
|
||||
|
||||
public static Intent cancelAutoUploadIntent(Context context) {
|
||||
Intent cancelAutoUploadIntent = new Intent(context, AutoUploadService.class);
|
||||
cancelAutoUploadIntent.setAction(ACTION_CANCEL_AUTO_UPLOAD);
|
||||
return cancelAutoUploadIntent;
|
||||
}
|
||||
|
||||
public static Intent vaultNotFoundUploadIntent(Context context) {
|
||||
Intent cancelAutoUploadIntent = new Intent(context, AutoUploadService.class);
|
||||
cancelAutoUploadIntent.setAction(ACTION_VAULT_NOT_FOUND);
|
||||
return cancelAutoUploadIntent;
|
||||
}
|
||||
|
||||
private void startBackgroundImageUpload(Cloud cloud) {
|
||||
try {
|
||||
uploadFiles = getUploadFiles(fileUtil.getAutoUploadFilesStore());
|
||||
@ -182,7 +167,11 @@ public class AutoUploadService extends Service {
|
||||
} catch (CloudNodeAlreadyExistsException e) {
|
||||
Timber.tag("AutoUploadService").i("Not uploading file because it already exists in the cloud");
|
||||
Timber.tag("AutoUploadService").v(format("Not uploading file because it already exists in the cloud %s", file.getFileName()));
|
||||
} catch (Exception e) {
|
||||
} catch (FileRemovedDuringUploadException e) {
|
||||
Timber.tag("AutoUploadService").i("Not uploading file because it was removed during upload");
|
||||
Timber.tag("AutoUploadService").v(format("Not uploading file because it was removed during upload %s", file.getFileName()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
cancelled = true;
|
||||
fileUtil.removeImagesFromAutoUploads(uploadedCloudFileNames);
|
||||
throw e;
|
||||
@ -211,6 +200,9 @@ public class AutoUploadService extends Service {
|
||||
|
||||
private CloudFile writeCloudFile(String fileName, CancelAwareDataSource dataSource, boolean replacing, ProgressAware<UploadState> progressAware) throws BackendException {
|
||||
Long size = dataSource.size(context);
|
||||
if(size == null) {
|
||||
throw new FileRemovedDuringUploadException();
|
||||
}
|
||||
CloudFile source = cloudContentRepository.file(parent, fileName, size);
|
||||
return cloudContentRepository.write(source, dataSource, progressAware, replacing, size);
|
||||
}
|
||||
@ -225,36 +217,18 @@ public class AutoUploadService extends Service {
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Timber.tag("AutoUploadService").i("started");
|
||||
if (isStartAutoUpload(intent)) {
|
||||
Timber.tag("AutoUploadService").i("Received start upload");
|
||||
|
||||
startBackgroundImageUpload(cloud);
|
||||
} else if (isCancelAutoUpload(intent)) {
|
||||
if (isCancelAutoUpload(intent)) {
|
||||
Timber.tag("AutoUploadService").i("Received stop auto upload");
|
||||
|
||||
cancelled = true;
|
||||
|
||||
hideNotification();
|
||||
} else if(isVaultNotFound(intent)) {
|
||||
Timber.tag("AutoUploadService").i("Received show vault not found notification");
|
||||
notification.showVaultNotFoundNotification();
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private boolean isStartAutoUpload(Intent intent) {
|
||||
return intent != null //
|
||||
&& ACTION_START_AUTO_UPLOAD.equals(intent.getAction());
|
||||
}
|
||||
|
||||
private boolean isCancelAutoUpload(Intent intent) {
|
||||
return intent != null //
|
||||
&& ACTION_CANCEL_AUTO_UPLOAD.equals(intent.getAction());
|
||||
}
|
||||
|
||||
private boolean isVaultNotFound(Intent intent) {
|
||||
return intent != null //
|
||||
&& ACTION_VAULT_NOT_FOUND.equals(intent.getAction());
|
||||
return intent != null && ACTION_CANCEL_AUTO_UPLOAD.equals(intent.getAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -294,5 +268,13 @@ public class AutoUploadService extends Service {
|
||||
contentResolverUtil = myContentResolverUtil;
|
||||
context = myContext;
|
||||
}
|
||||
|
||||
public void startUpload(Cloud cloud) {
|
||||
startBackgroundImageUpload(cloud);
|
||||
}
|
||||
|
||||
public void vaultNotFound() {
|
||||
notification.showVaultNotFoundNotification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user