mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Change binary attachment compression after change compression setting
This commit is contained in:
@@ -21,9 +21,7 @@ package com.kunzisoft.keepass.database.action
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.kunzisoft.keepass.database.element.Database
|
import com.kunzisoft.keepass.database.element.Database
|
||||||
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
|
||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
open class SaveDatabaseRunnable(protected var context: Context,
|
open class SaveDatabaseRunnable(protected var context: Context,
|
||||||
protected var database: Database,
|
protected var database: Database,
|
||||||
@@ -38,9 +36,7 @@ open class SaveDatabaseRunnable(protected var context: Context,
|
|||||||
if (saveDatabase && result.isSuccess) {
|
if (saveDatabase && result.isSuccess) {
|
||||||
try {
|
try {
|
||||||
database.saveData(context.contentResolver)
|
database.saveData(context.contentResolver)
|
||||||
} catch (e: IOException) {
|
} catch (e: Exception) {
|
||||||
setError(e.message)
|
|
||||||
} catch (e: DatabaseOutputException) {
|
|
||||||
setError(e.message)
|
setError(e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Jeremy Jamet / Kunzisoft.
|
||||||
|
*
|
||||||
|
* This file is part of KeePass DX.
|
||||||
|
*
|
||||||
|
* KeePass DX is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* KeePass DX is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.kunzisoft.keepass.database.action
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.kunzisoft.keepass.database.element.Database
|
||||||
|
import com.kunzisoft.keepass.database.element.PwCompressionAlgorithm
|
||||||
|
|
||||||
|
class UpdateCompressionBinariesDatabaseRunnable (
|
||||||
|
context: Context,
|
||||||
|
database: Database,
|
||||||
|
private val oldCompressionAlgorithm: PwCompressionAlgorithm,
|
||||||
|
private val newCompressionAlgorithm: PwCompressionAlgorithm,
|
||||||
|
saveDatabase: Boolean)
|
||||||
|
: SaveDatabaseRunnable(context, database, saveDatabase) {
|
||||||
|
|
||||||
|
override fun onStartRun() {
|
||||||
|
// Set new compression
|
||||||
|
if (database.allowDataCompression) {
|
||||||
|
try {
|
||||||
|
database.apply {
|
||||||
|
updateDataBinaryCompression(oldCompressionAlgorithm, newCompressionAlgorithm)
|
||||||
|
compressionAlgorithm = newCompressionAlgorithm
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
setError(e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onStartRun()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinishRun() {
|
||||||
|
super.onFinishRun()
|
||||||
|
|
||||||
|
if (database.allowDataCompression) {
|
||||||
|
if (!result.isSuccess) {
|
||||||
|
try {
|
||||||
|
database.apply {
|
||||||
|
compressionAlgorithm = oldCompressionAlgorithm
|
||||||
|
updateDataBinaryCompression(newCompressionAlgorithm, oldCompressionAlgorithm)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
setError(e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,25 +20,27 @@
|
|||||||
package com.kunzisoft.keepass.database.element
|
package com.kunzisoft.keepass.database.element
|
||||||
|
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedBinary
|
import com.kunzisoft.keepass.database.element.security.BinaryAttachment
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
class BinaryPool {
|
class BinaryPool {
|
||||||
private val pool = SparseArray<ProtectedBinary>()
|
private val pool = SparseArray<BinaryAttachment>()
|
||||||
|
|
||||||
operator fun get(key: Int): ProtectedBinary? {
|
operator fun get(key: Int): BinaryAttachment? {
|
||||||
return pool[key]
|
return pool[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun put(key: Int, value: ProtectedBinary) {
|
fun put(key: Int, value: BinaryAttachment) {
|
||||||
pool.put(key, value)
|
pool.put(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doForEachBinary(action: (key: Int, binary: ProtectedBinary) -> Unit) {
|
fun doForEachBinary(action: (key: Int, binary: BinaryAttachment) -> Unit) {
|
||||||
for (i in 0 until pool.size()) {
|
for (i in 0 until pool.size()) {
|
||||||
action.invoke(i, pool.get(pool.keyAt(i)))
|
action.invoke(i, pool.get(pool.keyAt(i)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
fun clear() {
|
fun clear() {
|
||||||
doForEachBinary { _, binary ->
|
doForEachBinary { _, binary ->
|
||||||
binary.clear()
|
binary.clear()
|
||||||
@@ -46,9 +48,9 @@ class BinaryPool {
|
|||||||
pool.clear()
|
pool.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(protectedBinary: ProtectedBinary) {
|
fun add(fileBinary: BinaryAttachment) {
|
||||||
if (findKey(protectedBinary) == null) {
|
if (findKey(fileBinary) == null) {
|
||||||
pool.put(findUnusedKey(), protectedBinary)
|
pool.put(findUnusedKey(), fileBinary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +61,7 @@ class BinaryPool {
|
|||||||
return unusedKey
|
return unusedKey
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findKey(pb: ProtectedBinary): Int? {
|
fun findKey(pb: BinaryAttachment): Int? {
|
||||||
for (i in 0 until pool.size()) {
|
for (i in 0 until pool.size()) {
|
||||||
if (pool.get(pool.keyAt(i)) == pb) return i
|
if (pool.get(pool.keyAt(i)) == pb) return i
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ class Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateDataBinaryCompression(oldCompression: PwCompressionAlgorithm,
|
||||||
|
newCompression: PwCompressionAlgorithm) {
|
||||||
|
pwDatabaseV4?.changeBinaryCompression(oldCompression, newCompression)
|
||||||
|
}
|
||||||
|
|
||||||
val allowNoMasterKey: Boolean
|
val allowNoMasterKey: Boolean
|
||||||
get() = pwDatabaseV4 != null
|
get() = pwDatabaseV4 != null
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,30 @@
|
|||||||
package com.kunzisoft.keepass.database.element
|
package com.kunzisoft.keepass.database.element
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.utils.ObjectNameResource
|
import com.kunzisoft.keepass.utils.ObjectNameResource
|
||||||
|
import com.kunzisoft.keepass.utils.readEnum
|
||||||
|
import com.kunzisoft.keepass.utils.writeEnum
|
||||||
|
|
||||||
|
|
||||||
// Note: We can get away with using int's to store unsigned 32-bit ints
|
// Note: We can get away with using int's to store unsigned 32-bit ints
|
||||||
// since we won't do arithmetic on these values (also unlikely to
|
// since we won't do arithmetic on these values (also unlikely to
|
||||||
// reach negative ids).
|
// reach negative ids).
|
||||||
enum class PwCompressionAlgorithm : ObjectNameResource {
|
enum class PwCompressionAlgorithm : ObjectNameResource, Parcelable {
|
||||||
|
|
||||||
None,
|
None,
|
||||||
GZip;
|
GZip;
|
||||||
|
|
||||||
|
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||||
|
dest.writeEnum(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun describeContents(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
override fun getName(resources: Resources): String {
|
override fun getName(resources: Resources): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
None -> resources.getString(R.string.compression_none)
|
None -> resources.getString(R.string.compression_none)
|
||||||
@@ -38,4 +51,14 @@ enum class PwCompressionAlgorithm : ObjectNameResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object CREATOR : Parcelable.Creator<PwCompressionAlgorithm> {
|
||||||
|
override fun createFromParcel(parcel: Parcel): PwCompressionAlgorithm {
|
||||||
|
return parcel.readEnum<PwCompressionAlgorithm>() ?: None
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<PwCompressionAlgorithm?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class PwDatabaseV4 : PwDatabase<UUID, UUID, PwGroupV4, PwEntryV4> {
|
|||||||
val customIcons = ArrayList<PwIconCustom>()
|
val customIcons = ArrayList<PwIconCustom>()
|
||||||
val customData = HashMap<String, String>()
|
val customData = HashMap<String, String>()
|
||||||
|
|
||||||
var binPool = BinaryPool()
|
var binaryPool = BinaryPool()
|
||||||
|
|
||||||
var localizedAppName = "KeePassDX"
|
var localizedAppName = "KeePassDX"
|
||||||
|
|
||||||
@@ -161,6 +161,39 @@ class PwDatabaseV4 : PwDatabase<UUID, UUID, PwGroupV4, PwEntryV4> {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun changeBinaryCompression(oldCompression: PwCompressionAlgorithm,
|
||||||
|
newCompression: PwCompressionAlgorithm) {
|
||||||
|
binaryPool.doForEachBinary { key, binary ->
|
||||||
|
|
||||||
|
try {
|
||||||
|
when (oldCompression) {
|
||||||
|
PwCompressionAlgorithm.None -> {
|
||||||
|
when (newCompression) {
|
||||||
|
PwCompressionAlgorithm.None -> {
|
||||||
|
}
|
||||||
|
PwCompressionAlgorithm.GZip -> {
|
||||||
|
// To compress, create a new binary with file
|
||||||
|
binary.compress()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PwCompressionAlgorithm.GZip -> {
|
||||||
|
when (newCompression) {
|
||||||
|
PwCompressionAlgorithm.None -> {
|
||||||
|
// To decompress, create a new binary with file
|
||||||
|
binary.decompress()
|
||||||
|
}
|
||||||
|
PwCompressionAlgorithm.GZip -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Unable to change compression for $key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val availableEncryptionAlgorithms: List<PwEncryptionAlgorithm>
|
override val availableEncryptionAlgorithms: List<PwEncryptionAlgorithm>
|
||||||
get() {
|
get() {
|
||||||
val list = ArrayList<PwEncryptionAlgorithm>()
|
val list = ArrayList<PwEncryptionAlgorithm>()
|
||||||
@@ -501,8 +534,12 @@ class PwDatabaseV4 : PwDatabase<UUID, UUID, PwGroupV4, PwEntryV4> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun clearCache() {
|
override fun clearCache() {
|
||||||
super.clearCache()
|
try {
|
||||||
binPool.clear()
|
super.clearCache()
|
||||||
|
binaryPool.clear()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Unable to clear cache", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ package com.kunzisoft.keepass.database.element
|
|||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedBinary
|
import com.kunzisoft.keepass.database.element.security.BinaryAttachment
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||||
import com.kunzisoft.keepass.utils.ParcelableUtil
|
import com.kunzisoft.keepass.utils.ParcelableUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -49,7 +49,7 @@ class PwEntryV4 : PwEntry<UUID, UUID, PwGroupV4, PwEntryV4>, PwNodeV4Interface {
|
|||||||
var iconCustom = PwIconCustom.UNKNOWN_ICON
|
var iconCustom = PwIconCustom.UNKNOWN_ICON
|
||||||
private var customData = HashMap<String, String>()
|
private var customData = HashMap<String, String>()
|
||||||
var fields = HashMap<String, ProtectedString>()
|
var fields = HashMap<String, ProtectedString>()
|
||||||
var binaries = HashMap<String, ProtectedBinary>()
|
var binaries = HashMap<String, BinaryAttachment>()
|
||||||
var foregroundColor = ""
|
var foregroundColor = ""
|
||||||
var backgroundColor = ""
|
var backgroundColor = ""
|
||||||
var overrideURL = ""
|
var overrideURL = ""
|
||||||
@@ -98,7 +98,7 @@ class PwEntryV4 : PwEntry<UUID, UUID, PwGroupV4, PwEntryV4>, PwNodeV4Interface {
|
|||||||
locationChanged = parcel.readParcelable(PwDate::class.java.classLoader) ?: locationChanged
|
locationChanged = parcel.readParcelable(PwDate::class.java.classLoader) ?: locationChanged
|
||||||
customData = ParcelableUtil.readStringParcelableMap(parcel)
|
customData = ParcelableUtil.readStringParcelableMap(parcel)
|
||||||
fields = ParcelableUtil.readStringParcelableMap(parcel, ProtectedString::class.java)
|
fields = ParcelableUtil.readStringParcelableMap(parcel, ProtectedString::class.java)
|
||||||
binaries = ParcelableUtil.readStringParcelableMap(parcel, ProtectedBinary::class.java)
|
binaries = ParcelableUtil.readStringParcelableMap(parcel, BinaryAttachment::class.java)
|
||||||
foregroundColor = parcel.readString() ?: foregroundColor
|
foregroundColor = parcel.readString() ?: foregroundColor
|
||||||
backgroundColor = parcel.readString() ?: backgroundColor
|
backgroundColor = parcel.readString() ?: backgroundColor
|
||||||
overrideURL = parcel.readString() ?: overrideURL
|
overrideURL = parcel.readString() ?: overrideURL
|
||||||
@@ -274,7 +274,7 @@ class PwEntryV4 : PwEntry<UUID, UUID, PwGroupV4, PwEntryV4>, PwNodeV4Interface {
|
|||||||
fields[label] = value
|
fields[label] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putProtectedBinary(key: String, value: ProtectedBinary) {
|
fun putProtectedBinary(key: String, value: BinaryAttachment) {
|
||||||
binaries[key] = value
|
binaries[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,21 +21,22 @@ package com.kunzisoft.keepass.database.element.security
|
|||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.util.Log
|
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BUFFER_SIZE_BYTES
|
||||||
|
import com.kunzisoft.keepass.stream.ReadBytes
|
||||||
|
import com.kunzisoft.keepass.stream.readFromStream
|
||||||
import java.io.*
|
import java.io.*
|
||||||
|
import java.util.zip.GZIPInputStream
|
||||||
|
import java.util.zip.GZIPOutputStream
|
||||||
|
|
||||||
import java.util.Arrays
|
class BinaryAttachment : Parcelable {
|
||||||
|
|
||||||
class ProtectedBinary : Parcelable {
|
var isCompressed: Boolean? = null
|
||||||
|
private set
|
||||||
var isCompressed: Boolean? = null // Only for KDBX3.1-
|
|
||||||
var isProtected: Boolean = false
|
var isProtected: Boolean = false
|
||||||
private var data: ByteArray? = null
|
private set
|
||||||
private var dataFile: File? = null
|
private var dataFile: File? = null
|
||||||
|
|
||||||
fun length(): Long {
|
fun length(): Long {
|
||||||
if (data != null)
|
|
||||||
return data!!.size.toLong()
|
|
||||||
if (dataFile != null)
|
if (dataFile != null)
|
||||||
return dataFile!!.length()
|
return dataFile!!.length()
|
||||||
return 0
|
return 0
|
||||||
@@ -47,28 +48,12 @@ class ProtectedBinary : Parcelable {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.isCompressed = null
|
this.isCompressed = null
|
||||||
this.isProtected = false
|
this.isProtected = false
|
||||||
this.data = null
|
|
||||||
this.dataFile = null
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(protectedBinary: ProtectedBinary) {
|
|
||||||
this.isCompressed = protectedBinary.isCompressed
|
|
||||||
this.isProtected = protectedBinary.isProtected
|
|
||||||
this.data = protectedBinary.data
|
|
||||||
this.dataFile = protectedBinary.dataFile
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(data: ByteArray?, enableProtection: Boolean = false, compressed: Boolean? = null) {
|
|
||||||
this.isCompressed = compressed
|
|
||||||
this.isProtected = enableProtection
|
|
||||||
this.data = data
|
|
||||||
this.dataFile = null
|
this.dataFile = null
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(dataFile: File, enableProtection: Boolean = false, compressed: Boolean? = null) {
|
constructor(dataFile: File, enableProtection: Boolean = false, compressed: Boolean? = null) {
|
||||||
this.isCompressed = compressed
|
this.isCompressed = compressed
|
||||||
this.isProtected = enableProtection
|
this.isProtected = enableProtection
|
||||||
this.data = null
|
|
||||||
this.dataFile = dataFile
|
this.dataFile = dataFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,24 +61,74 @@ class ProtectedBinary : Parcelable {
|
|||||||
val compressedByte = parcel.readByte().toInt()
|
val compressedByte = parcel.readByte().toInt()
|
||||||
isCompressed = if (compressedByte == 2) null else compressedByte != 0
|
isCompressed = if (compressedByte == 2) null else compressedByte != 0
|
||||||
isProtected = parcel.readByte().toInt() != 0
|
isProtected = parcel.readByte().toInt() != 0
|
||||||
data = ByteArray(parcel.readInt())
|
|
||||||
parcel.readByteArray(data)
|
|
||||||
dataFile = File(parcel.readString())
|
dataFile = File(parcel.readString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun getInputDataStream(): InputStream {
|
fun getInputDataStream(): InputStream {
|
||||||
return when {
|
return when {
|
||||||
data != null -> ByteArrayInputStream(data)
|
|
||||||
dataFile != null -> FileInputStream(dataFile!!)
|
dataFile != null -> FileInputStream(dataFile!!)
|
||||||
else -> throw IOException("Unable to get binary data")
|
// TODO
|
||||||
|
// else -> throw IOException("Unable to get binary data")
|
||||||
|
else -> ByteArrayInputStream(ByteArray(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun compress() {
|
||||||
|
if (dataFile != null) {
|
||||||
|
// To compress, create a new binary with file
|
||||||
|
if (isCompressed != true) {
|
||||||
|
val fileBinaryCompress = File(dataFile!!.parent, dataFile!!.name + "_temp")
|
||||||
|
val outputStream = GZIPOutputStream(FileOutputStream(fileBinaryCompress))
|
||||||
|
readFromStream(getInputDataStream(), BUFFER_SIZE_BYTES,
|
||||||
|
object : ReadBytes {
|
||||||
|
override fun read(buffer: ByteArray) {
|
||||||
|
outputStream.write(buffer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
outputStream.close()
|
||||||
|
|
||||||
|
// Remove unGzip file
|
||||||
|
if (dataFile!!.delete()) {
|
||||||
|
if (fileBinaryCompress.renameTo(dataFile)) {
|
||||||
|
// Harmonize with database compression
|
||||||
|
isCompressed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun decompress() {
|
||||||
|
if (dataFile != null) {
|
||||||
|
if (isCompressed != false) {
|
||||||
|
val fileBinaryDecompress = File(dataFile!!.parent, dataFile!!.name + "_temp")
|
||||||
|
val outputStream = FileOutputStream(fileBinaryDecompress)
|
||||||
|
readFromStream(GZIPInputStream(getInputDataStream()), BUFFER_SIZE_BYTES,
|
||||||
|
object : ReadBytes {
|
||||||
|
override fun read(buffer: ByteArray) {
|
||||||
|
outputStream.write(buffer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
outputStream.close()
|
||||||
|
|
||||||
|
// Remove gzip file
|
||||||
|
if (dataFile!!.delete()) {
|
||||||
|
if (fileBinaryDecompress.renameTo(dataFile)) {
|
||||||
|
// Harmonize with database compression
|
||||||
|
isCompressed = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
fun clear() {
|
fun clear() {
|
||||||
data = null
|
|
||||||
if (dataFile != null && !dataFile!!.delete())
|
if (dataFile != null && !dataFile!!.delete())
|
||||||
Log.e(TAG, "Unable to delete temp file " + dataFile!!.absolutePath)
|
throw IOException("Unable to delete temp file " + dataFile!!.absolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
@@ -101,16 +136,11 @@ class ProtectedBinary : Parcelable {
|
|||||||
return true
|
return true
|
||||||
if (other == null || javaClass != other.javaClass)
|
if (other == null || javaClass != other.javaClass)
|
||||||
return false
|
return false
|
||||||
if (other !is ProtectedBinary)
|
if (other !is BinaryAttachment)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
var sameData = false
|
var sameData = false
|
||||||
if (data != null && Arrays.equals(data, other.data))
|
if (dataFile != null && dataFile == other.dataFile)
|
||||||
sameData = true
|
|
||||||
else if (dataFile != null && dataFile == other.dataFile)
|
|
||||||
sameData = true
|
|
||||||
else if (data == null && other.data == null
|
|
||||||
&& dataFile == null && other.dataFile == null)
|
|
||||||
sameData = true
|
sameData = true
|
||||||
|
|
||||||
return isCompressed == other.isCompressed
|
return isCompressed == other.isCompressed
|
||||||
@@ -124,7 +154,6 @@ class ProtectedBinary : Parcelable {
|
|||||||
result = 31 * result + if (isCompressed == null) 2 else if (isCompressed!!) 1 else 0
|
result = 31 * result + if (isCompressed == null) 2 else if (isCompressed!!) 1 else 0
|
||||||
result = 31 * result + if (isProtected) 1 else 0
|
result = 31 * result + if (isProtected) 1 else 0
|
||||||
result = 31 * result + dataFile!!.hashCode()
|
result = 31 * result + dataFile!!.hashCode()
|
||||||
result = 31 * result + Arrays.hashCode(data)
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,22 +164,20 @@ class ProtectedBinary : Parcelable {
|
|||||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||||
dest.writeByte((if (isCompressed == null) 2 else if (isCompressed!!) 1 else 0).toByte())
|
dest.writeByte((if (isCompressed == null) 2 else if (isCompressed!!) 1 else 0).toByte())
|
||||||
dest.writeByte((if (isProtected) 1 else 0).toByte())
|
dest.writeByte((if (isProtected) 1 else 0).toByte())
|
||||||
dest.writeInt(data?.size ?: 0)
|
|
||||||
dest.writeByteArray(data)
|
|
||||||
dest.writeString(dataFile?.absolutePath)
|
dest.writeString(dataFile?.absolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val TAG = ProtectedBinary::class.java.name
|
private val TAG = BinaryAttachment::class.java.name
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val CREATOR: Parcelable.Creator<ProtectedBinary> = object : Parcelable.Creator<ProtectedBinary> {
|
val CREATOR: Parcelable.Creator<BinaryAttachment> = object : Parcelable.Creator<BinaryAttachment> {
|
||||||
override fun createFromParcel(parcel: Parcel): ProtectedBinary {
|
override fun createFromParcel(parcel: Parcel): BinaryAttachment {
|
||||||
return ProtectedBinary(parcel)
|
return BinaryAttachment(parcel)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun newArray(size: Int): Array<ProtectedBinary?> {
|
override fun newArray(size: Int): Array<BinaryAttachment?> {
|
||||||
return arrayOfNulls(size)
|
return arrayOfNulls(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,8 +26,7 @@ import com.kunzisoft.keepass.crypto.StreamCipherFactory
|
|||||||
import com.kunzisoft.keepass.crypto.engine.CipherEngine
|
import com.kunzisoft.keepass.crypto.engine.CipherEngine
|
||||||
import com.kunzisoft.keepass.database.element.*
|
import com.kunzisoft.keepass.database.element.*
|
||||||
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BASE_64_FLAG
|
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BASE_64_FLAG
|
||||||
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BUFFER_SIZE_BYTES
|
import com.kunzisoft.keepass.database.element.security.BinaryAttachment
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedBinary
|
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||||
import com.kunzisoft.keepass.database.exception.*
|
import com.kunzisoft.keepass.database.exception.*
|
||||||
import com.kunzisoft.keepass.database.file.KDBX4DateUtil
|
import com.kunzisoft.keepass.database.file.KDBX4DateUtil
|
||||||
@@ -44,6 +43,7 @@ import java.nio.charset.Charset
|
|||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.GZIPInputStream
|
import java.util.zip.GZIPInputStream
|
||||||
|
import java.util.zip.GZIPOutputStream
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class ImporterV4(private val streamDir: File,
|
|||||||
private var hashOfHeader: ByteArray? = null
|
private var hashOfHeader: ByteArray? = null
|
||||||
|
|
||||||
private val unusedCacheFileName: String
|
private val unusedCacheFileName: String
|
||||||
get() = mDatabase.binPool.findUnusedKey().toString()
|
get() = mDatabase.binaryPool.findUnusedKey().toString()
|
||||||
|
|
||||||
private var readNextNode = true
|
private var readNextNode = true
|
||||||
private val ctxGroups = Stack<PwGroupV4>()
|
private val ctxGroups = Stack<PwGroupV4>()
|
||||||
@@ -65,7 +65,7 @@ class ImporterV4(private val streamDir: File,
|
|||||||
private var ctxStringName: String? = null
|
private var ctxStringName: String? = null
|
||||||
private var ctxStringValue: ProtectedString? = null
|
private var ctxStringValue: ProtectedString? = null
|
||||||
private var ctxBinaryName: String? = null
|
private var ctxBinaryName: String? = null
|
||||||
private var ctxBinaryValue: ProtectedBinary? = null
|
private var ctxBinaryValue: BinaryAttachment? = null
|
||||||
private var ctxATName: String? = null
|
private var ctxATName: String? = null
|
||||||
private var ctxATSeq: String? = null
|
private var ctxATSeq: String? = null
|
||||||
private var entryInHistory = false
|
private var entryInHistory = false
|
||||||
@@ -242,8 +242,8 @@ class ImporterV4(private val streamDir: File,
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
val protectedBinary = ProtectedBinary(file, protectedFlag)
|
val protectedBinary = BinaryAttachment(file, protectedFlag)
|
||||||
mDatabase.binPool.add(protectedBinary)
|
mDatabase.binaryPool.add(protectedBinary)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
return false
|
return false
|
||||||
@@ -433,7 +433,7 @@ class ImporterV4(private val streamDir: File,
|
|||||||
if (key != null) {
|
if (key != null) {
|
||||||
val pbData = readBinary(xpp)
|
val pbData = readBinary(xpp)
|
||||||
val id = Integer.parseInt(key)
|
val id = Integer.parseInt(key)
|
||||||
mDatabase.binPool.put(id, pbData!!)
|
mDatabase.binaryPool.put(id, pbData!!)
|
||||||
} else {
|
} else {
|
||||||
readUnknown(xpp)
|
readUnknown(xpp)
|
||||||
}
|
}
|
||||||
@@ -938,7 +938,7 @@ class ImporterV4(private val streamDir: File,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(XmlPullParserException::class, IOException::class)
|
@Throws(XmlPullParserException::class, IOException::class)
|
||||||
private fun readBinary(xpp: XmlPullParser): ProtectedBinary? {
|
private fun readBinary(xpp: XmlPullParser): BinaryAttachment? {
|
||||||
|
|
||||||
// Reference Id to a binary already present in binary pool
|
// Reference Id to a binary already present in binary pool
|
||||||
val ref = xpp.getAttributeValue(null, PwDatabaseV4XML.AttrRef)
|
val ref = xpp.getAttributeValue(null, PwDatabaseV4XML.AttrRef)
|
||||||
@@ -946,7 +946,7 @@ class ImporterV4(private val streamDir: File,
|
|||||||
xpp.next() // Consume end tag
|
xpp.next() // Consume end tag
|
||||||
|
|
||||||
val id = Integer.parseInt(ref)
|
val id = Integer.parseInt(ref)
|
||||||
return mDatabase.binPool[id]
|
return mDatabase.binaryPool[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
// New binary to retrieve
|
// New binary to retrieve
|
||||||
@@ -968,18 +968,20 @@ class ImporterV4(private val streamDir: File,
|
|||||||
|
|
||||||
val base64 = readString(xpp)
|
val base64 = readString(xpp)
|
||||||
if (base64.isEmpty())
|
if (base64.isEmpty())
|
||||||
return ProtectedBinary()
|
return BinaryAttachment()
|
||||||
val data = Base64.decode(base64, BASE_64_FLAG)
|
val data = Base64.decode(base64, BASE_64_FLAG)
|
||||||
|
|
||||||
return if (data.size <= BUFFER_SIZE_BYTES) {
|
val file = File(streamDir, unusedCacheFileName)
|
||||||
// Small data, don't need a file
|
return FileOutputStream(file).use { outputStream ->
|
||||||
ProtectedBinary(data, protected, compressed)
|
// Force compression in this specific case
|
||||||
} else {
|
if (mDatabase.compressionAlgorithm == PwCompressionAlgorithm.GZip
|
||||||
val file = File(streamDir, unusedCacheFileName)
|
&& compressed == false) {
|
||||||
FileOutputStream(file).use { outputStream ->
|
GZIPOutputStream(outputStream).write(data)
|
||||||
|
BinaryAttachment(file, protected, true)
|
||||||
|
} else {
|
||||||
outputStream.write(data)
|
outputStream.write(data)
|
||||||
|
BinaryAttachment(file, protected)
|
||||||
}
|
}
|
||||||
ProtectedBinary(file, protected, compressed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class PwDbInnerHeaderOutputV4(private val database: PwDatabaseV4,
|
|||||||
dataOutputStream.writeInt(streamKeySize)
|
dataOutputStream.writeInt(streamKeySize)
|
||||||
dataOutputStream.write(header.innerRandomStreamKey)
|
dataOutputStream.write(header.innerRandomStreamKey)
|
||||||
|
|
||||||
database.binPool.doForEachBinary { _, protectedBinary ->
|
database.binaryPool.doForEachBinary { _, protectedBinary ->
|
||||||
var flag = PwDbHeaderV4.KdbxBinaryFlags.None
|
var flag = PwDbHeaderV4.KdbxBinaryFlags.None
|
||||||
if (protectedBinary.isProtected) {
|
if (protectedBinary.isProtected) {
|
||||||
flag = flag or PwDbHeaderV4.KdbxBinaryFlags.Protected
|
flag = flag or PwDbHeaderV4.KdbxBinaryFlags.Protected
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.kunzisoft.keepass.database.NodeHandler
|
|||||||
import com.kunzisoft.keepass.database.element.*
|
import com.kunzisoft.keepass.database.element.*
|
||||||
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BASE_64_FLAG
|
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BASE_64_FLAG
|
||||||
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BUFFER_SIZE_BYTES
|
import com.kunzisoft.keepass.database.element.PwDatabaseV4.Companion.BUFFER_SIZE_BYTES
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedBinary
|
import com.kunzisoft.keepass.database.element.security.BinaryAttachment
|
||||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||||
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
||||||
import com.kunzisoft.keepass.database.exception.UnknownKDF
|
import com.kunzisoft.keepass.database.exception.UnknownKDF
|
||||||
@@ -46,6 +46,7 @@ import java.io.*
|
|||||||
import java.security.NoSuchAlgorithmException
|
import java.security.NoSuchAlgorithmException
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.zip.GZIPInputStream
|
||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import javax.crypto.CipherOutputStream
|
import javax.crypto.CipherOutputStream
|
||||||
@@ -217,9 +218,10 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4,
|
|||||||
writeUuid(PwDatabaseV4XML.ElemLastSelectedGroup, mDatabaseV4.lastSelectedGroupUUID)
|
writeUuid(PwDatabaseV4XML.ElemLastSelectedGroup, mDatabaseV4.lastSelectedGroupUUID)
|
||||||
writeUuid(PwDatabaseV4XML.ElemLastTopVisibleGroup, mDatabaseV4.lastTopVisibleGroupUUID)
|
writeUuid(PwDatabaseV4XML.ElemLastTopVisibleGroup, mDatabaseV4.lastTopVisibleGroupUUID)
|
||||||
|
|
||||||
if (header!!.version < PwDbHeaderV4.FILE_VERSION_32_4) {
|
// Seem to work properly if always in meta
|
||||||
writeBinariesKDBX31()
|
// if (header!!.version < PwDbHeaderV4.FILE_VERSION_32_4)
|
||||||
}
|
writeMetaBinaries()
|
||||||
|
|
||||||
writeCustomData(mDatabaseV4.customData)
|
writeCustomData(mDatabaseV4.customData)
|
||||||
|
|
||||||
xml.endTag(null, PwDatabaseV4XML.ElemMeta)
|
xml.endTag(null, PwDatabaseV4XML.ElemMeta)
|
||||||
@@ -405,14 +407,15 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4,
|
|||||||
writeObject(name, String(Base64.encode(data, BASE_64_FLAG)))
|
writeObject(name, String(Base64.encode(data, BASE_64_FLAG)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only for KDBX3.1-
|
|
||||||
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
||||||
private fun writeBinariesKDBX31() {
|
private fun writeMetaBinaries() {
|
||||||
xml.startTag(null, PwDatabaseV4XML.ElemBinaries)
|
xml.startTag(null, PwDatabaseV4XML.ElemBinaries)
|
||||||
|
|
||||||
mDatabaseV4.binPool.doForEachBinary { key, binary ->
|
mDatabaseV4.binaryPool.doForEachBinary { key, binary ->
|
||||||
xml.startTag(null, PwDatabaseV4XML.ElemBinary)
|
xml.startTag(null, PwDatabaseV4XML.ElemBinary)
|
||||||
xml.attribute(null, PwDatabaseV4XML.AttrId, key.toString())
|
xml.attribute(null, PwDatabaseV4XML.AttrId, key.toString())
|
||||||
|
|
||||||
|
// Force binary compression from database (compression was harmonized during import)
|
||||||
xml.attribute(null, PwDatabaseV4XML.AttrCompressed,
|
xml.attribute(null, PwDatabaseV4XML.AttrCompressed,
|
||||||
if (mDatabaseV4.compressionAlgorithm === PwCompressionAlgorithm.GZip) {
|
if (mDatabaseV4.compressionAlgorithm === PwCompressionAlgorithm.GZip) {
|
||||||
PwDatabaseV4XML.ValTrue
|
PwDatabaseV4XML.ValTrue
|
||||||
@@ -420,23 +423,17 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4,
|
|||||||
PwDatabaseV4XML.ValFalse
|
PwDatabaseV4XML.ValFalse
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
/*
|
|
||||||
// TODO compression needed here ?
|
|
||||||
// Binary need to be compressed before storage
|
|
||||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
|
||||||
val gzipOutputStream = GZIPOutputStream(byteArrayOutputStream)
|
|
||||||
IOUtils.copy(binary.getInputDataStream(), gzipOutputStream)
|
|
||||||
gzipOutputStream.close()
|
|
||||||
readFromStream(ByteArrayInputStream(byteArrayOutputStream.toByteArray()), BUFFER_SIZE_BYTES,
|
|
||||||
object : ReadBytes {
|
|
||||||
override fun read(buffer: ByteArray) {
|
|
||||||
xml.text(String(Base64.encode(buffer, BASE_64_FLAG)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
readFromStream(binary.getInputDataStream(), BUFFER_SIZE_BYTES,
|
// Force decompression in this specific case
|
||||||
|
val binaryInputStream = if (mDatabaseV4.compressionAlgorithm == PwCompressionAlgorithm.None
|
||||||
|
&& binary.isCompressed == true) {
|
||||||
|
GZIPInputStream(binary.getInputDataStream())
|
||||||
|
} else {
|
||||||
|
binary.getInputDataStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the XML
|
||||||
|
readFromStream(binaryInputStream, BUFFER_SIZE_BYTES,
|
||||||
object : ReadBytes {
|
object : ReadBytes {
|
||||||
override fun read(buffer: ByteArray) {
|
override fun read(buffer: ByteArray) {
|
||||||
val charArray = String(Base64.encode(buffer, BASE_64_FLAG)).toCharArray()
|
val charArray = String(Base64.encode(buffer, BASE_64_FLAG)).toCharArray()
|
||||||
@@ -541,7 +538,7 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
|
||||||
private fun writeEntryBinaries(binaries: Map<String, ProtectedBinary>) {
|
private fun writeEntryBinaries(binaries: Map<String, BinaryAttachment>) {
|
||||||
for ((key, binary) in binaries) {
|
for ((key, binary) in binaries) {
|
||||||
xml.startTag(null, PwDatabaseV4XML.ElemBinary)
|
xml.startTag(null, PwDatabaseV4XML.ElemBinary)
|
||||||
xml.startTag(null, PwDatabaseV4XML.ElemKey)
|
xml.startTag(null, PwDatabaseV4XML.ElemKey)
|
||||||
@@ -549,7 +546,7 @@ class PwDbV4Output(private val mDatabaseV4: PwDatabaseV4,
|
|||||||
xml.endTag(null, PwDatabaseV4XML.ElemKey)
|
xml.endTag(null, PwDatabaseV4XML.ElemKey)
|
||||||
|
|
||||||
xml.startTag(null, PwDatabaseV4XML.ElemValue)
|
xml.startTag(null, PwDatabaseV4XML.ElemValue)
|
||||||
val ref = mDatabaseV4.binPool.findKey(binary)
|
val ref = mDatabaseV4.binaryPool.findKey(binary)
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
xml.attribute(null, PwDatabaseV4XML.AttrRef, ref.toString())
|
xml.attribute(null, PwDatabaseV4XML.AttrRef, ref.toString())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ import android.os.Bundle
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||||
import com.kunzisoft.keepass.database.action.AssignPasswordInDatabaseRunnable
|
import com.kunzisoft.keepass.database.action.*
|
||||||
import com.kunzisoft.keepass.database.action.CreateDatabaseRunnable
|
|
||||||
import com.kunzisoft.keepass.database.action.LoadDatabaseRunnable
|
|
||||||
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable
|
|
||||||
import com.kunzisoft.keepass.database.action.node.*
|
import com.kunzisoft.keepass.database.action.node.*
|
||||||
import com.kunzisoft.keepass.database.element.*
|
import com.kunzisoft.keepass.database.element.*
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
@@ -107,11 +104,11 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
|||||||
ACTION_DATABASE_COPY_NODES_TASK -> buildDatabaseCopyNodesActionTask(intent)
|
ACTION_DATABASE_COPY_NODES_TASK -> buildDatabaseCopyNodesActionTask(intent)
|
||||||
ACTION_DATABASE_MOVE_NODES_TASK -> buildDatabaseMoveNodesActionTask(intent)
|
ACTION_DATABASE_MOVE_NODES_TASK -> buildDatabaseMoveNodesActionTask(intent)
|
||||||
ACTION_DATABASE_DELETE_NODES_TASK -> buildDatabaseDeleteNodesActionTask(intent)
|
ACTION_DATABASE_DELETE_NODES_TASK -> buildDatabaseDeleteNodesActionTask(intent)
|
||||||
|
ACTION_DATABASE_UPDATE_COMPRESSION_TASK -> buildDatabaseUpdateCompressionActionTask(intent)
|
||||||
ACTION_DATABASE_UPDATE_NAME_TASK,
|
ACTION_DATABASE_UPDATE_NAME_TASK,
|
||||||
ACTION_DATABASE_UPDATE_DESCRIPTION_TASK,
|
ACTION_DATABASE_UPDATE_DESCRIPTION_TASK,
|
||||||
ACTION_DATABASE_UPDATE_DEFAULT_USERNAME_TASK,
|
ACTION_DATABASE_UPDATE_DEFAULT_USERNAME_TASK,
|
||||||
ACTION_DATABASE_UPDATE_COLOR_TASK,
|
ACTION_DATABASE_UPDATE_COLOR_TASK,
|
||||||
ACTION_DATABASE_UPDATE_COMPRESSION_TASK,
|
|
||||||
ACTION_DATABASE_UPDATE_MAX_HISTORY_ITEMS_TASK,
|
ACTION_DATABASE_UPDATE_MAX_HISTORY_ITEMS_TASK,
|
||||||
ACTION_DATABASE_UPDATE_MAX_HISTORY_SIZE_TASK,
|
ACTION_DATABASE_UPDATE_MAX_HISTORY_SIZE_TASK,
|
||||||
ACTION_DATABASE_UPDATE_ENCRYPTION_TASK,
|
ACTION_DATABASE_UPDATE_ENCRYPTION_TASK,
|
||||||
@@ -409,6 +406,25 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun buildDatabaseUpdateCompressionActionTask(intent: Intent): ActionRunnable? {
|
||||||
|
return if (intent.hasExtra(OLD_ELEMENT_KEY)
|
||||||
|
&& intent.hasExtra(NEW_ELEMENT_KEY)
|
||||||
|
&& intent.hasExtra(SAVE_DATABASE_KEY)) {
|
||||||
|
return UpdateCompressionBinariesDatabaseRunnable(this,
|
||||||
|
Database.getInstance(),
|
||||||
|
intent.getParcelableExtra(OLD_ELEMENT_KEY),
|
||||||
|
intent.getParcelableExtra(NEW_ELEMENT_KEY),
|
||||||
|
intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
|
||||||
|
).apply {
|
||||||
|
mAfterSaveDatabase = { result ->
|
||||||
|
result.data = intent.extras
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildDatabaseUpdateElementActionTask(intent: Intent): ActionRunnable? {
|
private fun buildDatabaseUpdateElementActionTask(intent: Intent): ActionRunnable? {
|
||||||
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
|
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
|
||||||
return SaveDatabaseRunnable(this,
|
return SaveDatabaseRunnable(this,
|
||||||
|
|||||||
@@ -96,3 +96,9 @@ object ParcelableUtil {
|
|||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Enum<T>> Parcel.readEnum() =
|
||||||
|
readString()?.let { enumValueOf<T>(it) }
|
||||||
|
|
||||||
|
inline fun <T : Enum<T>> Parcel.writeEnum(value: T?) =
|
||||||
|
writeString(value?.name)
|
||||||
|
|||||||
Reference in New Issue
Block a user