Better handling of the revocation of the "Storage" permission
* Check if permission is set when launching the app * Show specific notification when auto upload fails due this state Fixes #391 and fixes #397
This commit is contained in:
parent
c685cc3645
commit
07f93c0833
@ -1,5 +1,6 @@
|
||||
package org.cryptomator.presentation.presenter
|
||||
|
||||
import android.Manifest
|
||||
import android.app.KeyguardManager
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.ActivityNotFoundException
|
||||
@ -56,6 +57,7 @@ import org.cryptomator.presentation.workflow.ActivityResult
|
||||
import org.cryptomator.presentation.workflow.AddExistingVaultWorkflow
|
||||
import org.cryptomator.presentation.workflow.AuthenticationExceptionHandler
|
||||
import org.cryptomator.presentation.workflow.CreateNewVaultWorkflow
|
||||
import org.cryptomator.presentation.workflow.PermissionsResult
|
||||
import org.cryptomator.presentation.workflow.Workflow
|
||||
import org.cryptomator.util.SharedPreferencesHandler
|
||||
import javax.inject.Inject
|
||||
@ -112,6 +114,10 @@ class VaultListPresenter @Inject constructor( //
|
||||
}
|
||||
|
||||
checkLicense()
|
||||
|
||||
if(sharedPreferencesHandler.usePhotoUpload()) {
|
||||
checkLocalStoragePermissionRegardingAutoUpload()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLicense() {
|
||||
@ -185,6 +191,27 @@ class VaultListPresenter @Inject constructor( //
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLocalStoragePermissionRegardingAutoUpload() {
|
||||
requestPermissions(
|
||||
PermissionsResultCallbacks.onLocalStoragePermissionGrantedForAutoUpload(), //
|
||||
R.string.permission_snackbar_auth_auto_upload, //
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
}
|
||||
|
||||
@Callback
|
||||
fun onLocalStoragePermissionGrantedForAutoUpload(result: PermissionsResult) {
|
||||
if (!result.granted()) {
|
||||
Timber.tag("VaultListPresenter").e("Local storage permission not granted, auto upload will not work")
|
||||
}
|
||||
}
|
||||
|
||||
fun loadVaultList() {
|
||||
view?.hideVaultCreationHint()
|
||||
vaultList
|
||||
assertUnlockingVaultIsLocked()
|
||||
}
|
||||
|
||||
private fun assertUnlockingVaultIsLocked() {
|
||||
if (view?.isShowingDialog(EnterPasswordDialog::class) == true) {
|
||||
if (view?.currentDialog() != null) {
|
||||
@ -196,12 +223,6 @@ class VaultListPresenter @Inject constructor( //
|
||||
}
|
||||
}
|
||||
|
||||
fun loadVaultList() {
|
||||
view?.hideVaultCreationHint()
|
||||
vaultList
|
||||
assertUnlockingVaultIsLocked()
|
||||
}
|
||||
|
||||
fun deleteVault(vaultModel: VaultModel) {
|
||||
deleteVaultUseCase //
|
||||
.withVault(vaultModel.toVault()) //
|
||||
|
@ -47,18 +47,15 @@ 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)
|
||||
return NotificationCompat.Action.Builder( //
|
||||
R.drawable.ic_lock, //
|
||||
getString(R.string.notification_cancel_auto_upload), //
|
||||
cancelNowIntent() //
|
||||
cancelIntent //
|
||||
).build()
|
||||
}
|
||||
|
||||
private fun cancelNowIntent(): PendingIntent {
|
||||
val intentAction = cancelAutoUploadIntent(context)
|
||||
return PendingIntent.getService(context, 0, intentAction, FLAG_CANCEL_CURRENT)
|
||||
}
|
||||
|
||||
private fun startTheActivity(): PendingIntent {
|
||||
val startTheActivity = Intent(context, VaultListActivity::class.java)
|
||||
startTheActivity.action = ACTION_MAIN
|
||||
@ -67,8 +64,8 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
|
||||
}
|
||||
|
||||
fun update(progress: Int) {
|
||||
builder.setContentIntent(startTheActivity())
|
||||
builder //
|
||||
.setContentIntent(startTheActivity())
|
||||
.setContentText( //
|
||||
String.format(
|
||||
context.getString(R.string.notification_auto_upload_message), //
|
||||
@ -105,27 +102,32 @@ class AutoUploadNotification(private val context: Context, private val amountOfP
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_failed_due_to_vault_not_found))
|
||||
}
|
||||
|
||||
fun showPermissionNotGrantedNotification() {
|
||||
Timber.tag("AutoUploadNotification").i("Show storage permission required notification")
|
||||
showErrorWithMessage(context.getString(R.string.notification_auto_upload_permission_not_granted))
|
||||
}
|
||||
|
||||
private fun showErrorWithMessage(message: String) {
|
||||
builder.setContentIntent(startTheActivity())
|
||||
builder //
|
||||
builder
|
||||
.setContentIntent(startTheActivity())
|
||||
.setContentTitle(context.getString(R.string.notification_auto_upload_failed_title))
|
||||
.setContentText(message) //
|
||||
.setProgress(0, 0, false)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(false)
|
||||
.mActions.clear()
|
||||
.clearActions()
|
||||
show()
|
||||
}
|
||||
|
||||
fun showUploadFinished(size: Int) {
|
||||
builder.setContentIntent(startTheActivity())
|
||||
builder //
|
||||
builder
|
||||
.setContentIntent(startTheActivity())
|
||||
.setContentTitle(context.getString(R.string.notification_auto_upload_finished_title))
|
||||
.setContentText(format(context.getString(R.string.notification_auto_upload_finished_message), size)) //
|
||||
.setContentText(format(context.getString(R.string.notification_auto_upload_finished_message), size))
|
||||
.setProgress(0, 0, false)
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(false)
|
||||
.mActions.clear()
|
||||
.clearActions()
|
||||
show()
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.OsConstants;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@ -37,6 +39,7 @@ import org.cryptomator.presentation.util.FileUtil;
|
||||
import org.cryptomator.util.SharedPreferencesHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@ -111,6 +114,8 @@ public class AutoUploadService extends Service {
|
||||
notification.showVaultLockedDuringUpload();
|
||||
} else if (e instanceof CancellationException) {
|
||||
Timber.tag("AutoUploadService").i("Upload canceled by user");
|
||||
} else if (wrappedStoragePermissionException(e)) {
|
||||
notification.showPermissionNotGrantedNotification();
|
||||
} else {
|
||||
notification.showGeneralErrorDuringUpload();
|
||||
}
|
||||
@ -122,6 +127,14 @@ public class AutoUploadService extends Service {
|
||||
worker.start();
|
||||
}
|
||||
|
||||
private boolean wrappedStoragePermissionException(Exception e) {
|
||||
return e.getCause() != null //
|
||||
&& e.getCause() instanceof FileNotFoundException //
|
||||
&& e.getCause().getCause() != null //
|
||||
&& e.getCause().getCause() instanceof ErrnoException //
|
||||
&& ((ErrnoException) e.getCause().getCause()).errno == OsConstants.EACCES;
|
||||
}
|
||||
|
||||
private void updateNotification(int asPercentage) {
|
||||
if (elapsedTimeAutoUploadNotificationDelay > 200 && !cancelled) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
@ -170,8 +183,7 @@ public class AutoUploadService extends Service {
|
||||
} 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) {
|
||||
} catch (Exception e) {
|
||||
cancelled = true;
|
||||
fileUtil.removeImagesFromAutoUploads(uploadedCloudFileNames);
|
||||
throw e;
|
||||
@ -200,7 +212,7 @@ 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) {
|
||||
if (size == null) {
|
||||
throw new FileRemovedDuringUploadException();
|
||||
}
|
||||
CloudFile source = cloudContentRepository.file(parent, fileName, size);
|
||||
|
@ -538,6 +538,7 @@
|
||||
<string name="notification_auto_upload_failed_due_to_folder_not_exists">Selected folder for upload isn\'t available anymore. Go to settings and choose a new one</string>
|
||||
<string name="notification_auto_upload_failed_due_to_vault_locked">Vault locked during upload, please reopen vault to continue</string>
|
||||
<string name="notification_auto_upload_failed_due_to_vault_not_found">Vault specified for auto upload doesn\'t exist anymore.</string>
|
||||
<string name="notification_auto_upload_permission_not_granted" translatable="false">@string/permission_snackbar_auth_auto_upload</string>
|
||||
|
||||
<string name="notification_cancel_open_writable_file" translatable="false">@string/dialog_button_cancel</string>
|
||||
<string name="notification_open_writable_file_title">Open writable file</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user