display reason why file is read only when first opening a database

This commit is contained in:
Philipp Crocoll
2016-01-13 05:13:02 +01:00
parent cd5fc13939
commit 64e265b2be
10 changed files with 86 additions and 13 deletions

View File

@@ -206,12 +206,15 @@ namespace keepass2android.Io
return _ctx.ContentResolver.PersistedUriPermissions.Any(p => p.Uri.ToString().Equals(ioc.Path));
}
public bool IsReadOnly(IOConnectionInfo ioc)
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
//on pre-Kitkat devices, we can't write content:// files
if (!IsKitKatOrLater)
{
Kp2aLog.Log("File is read-only because we're not on KitKat or later.");
if (reason != null)
reason.Result = UiStringKey.ReadOnlyReason_PreKitKat;
return true;
}
@@ -226,7 +229,12 @@ namespace keepass2android.Io
{
int flags = cursor.GetInt(cursor.GetColumnIndex(DocumentsContract.Document.ColumnFlags));
Kp2aLog.Log("File flags: " + flags);
return (flags & (long) DocumentContractFlags.SupportsWrite) == 0;
if ((flags & (long) DocumentContractFlags.SupportsWrite) == 0)
{
if (reason != null)
reason.Result = UiStringKey.ReadOnlyReason_ReadOnlyFlag;
return true;
}
}
}
finally

View File

@@ -370,14 +370,24 @@ namespace keepass2android.Io
}
public bool IsReadOnly(IOConnectionInfo ioc)
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
if (ioc.IsLocalFile())
{
if (IsLocalFileFlaggedReadOnly(ioc))
{
if (reason != null)
reason.Result = UiStringKey.ReadOnlyReason_ReadOnlyFlag;
return true;
}
if (IsReadOnlyBecauseKitkatRestrictions(ioc))
{
if (reason != null)
reason.Result = UiStringKey.ReadOnlyReason_ReadOnlyKitKat;
return true;
}
return false;
}

View File

@@ -556,11 +556,11 @@ namespace keepass2android.Io
return _cachedStorage.IsPermanentLocation(ioc);
}
public bool IsReadOnly(IOConnectionInfo ioc)
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
//even though the cache can always be written, the changes made in the cache could not be transferred to the cached file
//so we better treat the cache as read-only as well.
return _cachedStorage.IsReadOnly(ioc);
return _cachedStorage.IsReadOnly(ioc, reason);
}
private void StoreFilePath(IOConnectionInfo folderPath, string filename, IOConnectionInfo res)

View File

@@ -15,6 +15,11 @@ namespace keepass2android.Io
FileChooserPrepared = FullFilenameSelected + 1,
FileUsagePrepared = FileChooserPrepared + 1
}
public class OptionalOut<T>
{
public T Result { get; set; }
}
public static class FileStorageSetupDefs
{
@@ -165,10 +170,14 @@ namespace keepass2android.Io
/// Does not require to exist forever!
bool IsPermanentLocation(IOConnectionInfo ioc);
/// <summary>
/// Should return true if the file cannot be written.
/// </summary>
bool IsReadOnly(IOConnectionInfo ioc);
bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null );
}
public interface IPermissionRequestingFileStorage

View File

@@ -289,7 +289,7 @@ namespace keepass2android.Io
return true;
}
public bool IsReadOnly(IOConnectionInfo ioc)
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
return false; //TODO implement. note, however, that we MAY return false even if it's read-only
}

View File

@@ -176,9 +176,9 @@ namespace keepass2android.Io
return _baseStorage.IsPermanentLocation(ioc);
}
public bool IsReadOnly(IOConnectionInfo ioc)
public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null)
{
return _baseStorage.IsReadOnly(ioc);
return _baseStorage.IsReadOnly(ioc, reason);
}
public void OnRequestPermissionsResult(IFileStorageSetupActivity fileStorageSetupActivity, int requestCode,

View File

@@ -81,6 +81,9 @@ namespace keepass2android
TemplateTitle_Membership,
TemplateGroupName,
AskAddTemplatesTitle,
AskAddTemplatesMessage
AskAddTemplatesMessage,
ReadOnlyReason_PreKitKat,
ReadOnlyReason_ReadOnlyFlag,
ReadOnlyReason_ReadOnlyKitKat
}
}

View File

@@ -153,12 +153,24 @@ namespace keepass2android
public static string GetFingerprintPrefKey(IOConnectionInfo ioc)
{
SHA256Managed sha256 = new SHA256Managed();
string iocAsHexString = MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())));
var iocAsHexString = IocAsHexString(ioc);
return "kp2a_ioc_" + iocAsHexString;
}
public string IocAsHexString()
{
return IocAsHexString(Ioc);
}
private static string IocAsHexString(IOConnectionInfo ioc)
{
SHA256Managed sha256 = new SHA256Managed();
string iocAsHexString =
MemUtil.ByteArrayToHexString(sha256.ComputeHash(Encoding.Unicode.GetBytes(ioc.Path.ToCharArray())));
return iocAsHexString;
}
public static string GetFingerprintModePrefKey(IOConnectionInfo ioc)
{
return GetFingerprintPrefKey(ioc) + "_mode";