mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Add support for backing up wallpapers.
This commit is contained in:
@@ -70,6 +70,7 @@ import org.thoughtcrime.securesms.attachments.Attachment
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId
|
||||
import org.thoughtcrime.securesms.attachments.Cdn
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.attachments.WallpaperAttachment
|
||||
import org.thoughtcrime.securesms.audio.AudioHash
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash
|
||||
import org.thoughtcrime.securesms.crypto.AttachmentSecret
|
||||
@@ -182,6 +183,7 @@ class AttachmentTable(
|
||||
const val TRANSFER_RESTORE_IN_PROGRESS = 6
|
||||
const val TRANSFER_RESTORE_OFFLOADED = 7
|
||||
const val PREUPLOAD_MESSAGE_ID: Long = -8675309
|
||||
const val WALLPAPER_MESSAGE_ID: Long = -8675308
|
||||
|
||||
private val PROJECTION = arrayOf(
|
||||
ID,
|
||||
@@ -816,7 +818,7 @@ class AttachmentTable(
|
||||
fun trimAllAbandonedAttachments() {
|
||||
val deleteCount = writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.where("$MESSAGE_ID != $PREUPLOAD_MESSAGE_ID AND $MESSAGE_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})")
|
||||
.where("$MESSAGE_ID != $PREUPLOAD_MESSAGE_ID AND $MESSAGE_ID != $WALLPAPER_MESSAGE_ID AND $MESSAGE_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})")
|
||||
.run()
|
||||
|
||||
if (deleteCount > 0) {
|
||||
@@ -2184,6 +2186,16 @@ class AttachmentTable(
|
||||
throw MmsException(e)
|
||||
}
|
||||
|
||||
return insertAttachmentWithData(messageId, dataStream, attachment, quote)
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an attachment with existing data. This is likely an outgoing attachment that we're in the process of sending.
|
||||
*
|
||||
* @param dataStream The stream to read the data from. This stream will be closed by this method.
|
||||
*/
|
||||
@Throws(MmsException::class)
|
||||
private fun insertAttachmentWithData(messageId: Long, dataStream: InputStream, attachment: Attachment, quote: Boolean): AttachmentId {
|
||||
// To avoid performing long-running operations in a transaction, we write the data to an independent file first in a way that doesn't rely on db state.
|
||||
val fileWriteResult: DataFileWriteResult = writeToDataFile(newDataFile(context), dataStream, attachment.transformProperties ?: TransformProperties.empty())
|
||||
Log.d(TAG, "[insertAttachmentWithData] Wrote data to file: ${fileWriteResult.file.absolutePath} (MessageId: $messageId, ${attachment.uri})")
|
||||
@@ -2212,12 +2224,16 @@ class AttachmentTable(
|
||||
}
|
||||
|
||||
if (hashMatch != null) {
|
||||
if (fileWriteResult.hash == hashMatch.hashStart) {
|
||||
Log.i(TAG, "[insertAttachmentWithData] Found that the new attachment hash matches the DATA_HASH_START of ${hashMatch.id}. Using all of it's fields. (MessageId: $messageId, ${attachment.uri})")
|
||||
} else if (fileWriteResult.hash == hashMatch.hashEnd) {
|
||||
Log.i(TAG, "[insertAttachmentWithData] Found that the new attachment hash matches the DATA_HASH_END of ${hashMatch.id}. Using all of it's fields. (MessageId: $messageId, ${attachment.uri})")
|
||||
} else {
|
||||
throw IllegalStateException("Should not be possible based on query.")
|
||||
when (fileWriteResult.hash) {
|
||||
hashMatch.hashStart -> {
|
||||
Log.i(TAG, "[insertAttachmentWithData] Found that the new attachment hash matches the DATA_HASH_START of ${hashMatch.id}. Using all of it's fields. (MessageId: $messageId, ${attachment.uri})")
|
||||
}
|
||||
hashMatch.hashEnd -> {
|
||||
Log.i(TAG, "[insertAttachmentWithData] Found that the new attachment hash matches the DATA_HASH_END of ${hashMatch.id}. Using all of it's fields. (MessageId: $messageId, ${attachment.uri})")
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Should not be possible based on query.")
|
||||
}
|
||||
}
|
||||
|
||||
contentValues.put(DATA_FILE, hashMatch.file.absolutePath)
|
||||
@@ -2309,6 +2325,21 @@ class AttachmentTable(
|
||||
return attachmentId
|
||||
}
|
||||
|
||||
fun insertWallpaper(dataStream: InputStream): AttachmentId {
|
||||
return insertAttachmentWithData(WALLPAPER_MESSAGE_ID, dataStream, WallpaperAttachment(), quote = false).also { id ->
|
||||
createKeyIvIfNecessary(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllWallpapers(): List<AttachmentId> {
|
||||
return readableDatabase
|
||||
.select(ID)
|
||||
.from(TABLE_NAME)
|
||||
.where("$MESSAGE_ID = $WALLPAPER_MESSAGE_ID")
|
||||
.run()
|
||||
.readToList { AttachmentId(it.requireLong(ID)) }
|
||||
}
|
||||
|
||||
private fun getTransferFile(db: SQLiteDatabase, attachmentId: AttachmentId): File? {
|
||||
return db
|
||||
.select(TRANSFER_FILE)
|
||||
|
||||
@@ -98,6 +98,7 @@ import org.thoughtcrime.securesms.util.ProfileUtil
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory
|
||||
import org.thoughtcrime.securesms.wallpaper.WallpaperStorage
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
@@ -1968,7 +1969,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
for (pair in idWithWallpaper) {
|
||||
AppDependencies.databaseObserver.notifyRecipientChanged(pair.first)
|
||||
if (pair.second != null) {
|
||||
WallpaperStorage.onWallpaperDeselected(context, Uri.parse(pair.second))
|
||||
WallpaperStorage.onWallpaperDeselected(Uri.parse(pair.second))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1980,11 +1981,11 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
}
|
||||
}
|
||||
|
||||
fun setWallpaper(id: RecipientId, chatWallpaper: ChatWallpaper?) {
|
||||
setWallpaper(id, chatWallpaper?.serialize())
|
||||
fun setWallpaper(id: RecipientId, chatWallpaper: ChatWallpaper?, notifyDeselected: Boolean) {
|
||||
setWallpaper(id, chatWallpaper?.serialize(), notifyDeselected)
|
||||
}
|
||||
|
||||
private fun setWallpaper(id: RecipientId, wallpaper: Wallpaper?) {
|
||||
private fun setWallpaper(id: RecipientId, wallpaper: Wallpaper?, notifyDeselected: Boolean) {
|
||||
val existingWallpaperUri = getWallpaperUri(id)
|
||||
val values = ContentValues().apply {
|
||||
put(WALLPAPER, wallpaper?.encode())
|
||||
@@ -1999,8 +2000,8 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
AppDependencies.databaseObserver.notifyRecipientChanged(id)
|
||||
}
|
||||
|
||||
if (existingWallpaperUri != null) {
|
||||
WallpaperStorage.onWallpaperDeselected(context, existingWallpaperUri)
|
||||
if (notifyDeselected && existingWallpaperUri != null) {
|
||||
WallpaperStorage.onWallpaperDeselected(existingWallpaperUri)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2010,7 +2011,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
.dimLevelInDarkTheme(if (enabled) ChatWallpaper.FIXED_DIM_LEVEL_FOR_DARK_THEME else 0f)
|
||||
.build()
|
||||
|
||||
setWallpaper(id, updated)
|
||||
setWallpaper(id, updated, false)
|
||||
}
|
||||
|
||||
private fun getWallpaper(id: RecipientId): Wallpaper? {
|
||||
@@ -2055,6 +2056,23 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates all recipients using [legacyUri] for their wallpaper to [newUri].
|
||||
* Needed for an app migration.
|
||||
*/
|
||||
fun migrateWallpaperUri(legacyUri: Uri, newUri: Uri): Int {
|
||||
val newWallpaper = ChatWallpaperFactory.create(newUri)
|
||||
|
||||
return writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(
|
||||
WALLPAPER to newWallpaper.serialize().encode(),
|
||||
WALLPAPER_URI to newUri.toString()
|
||||
)
|
||||
.where("$WALLPAPER_URI = ?", legacyUri)
|
||||
.run()
|
||||
}
|
||||
|
||||
fun getPhoneNumberDiscoverability(id: RecipientId): PhoneNumberDiscoverableState? {
|
||||
return readableDatabase
|
||||
.select(PHONE_NUMBER_DISCOVERABLE)
|
||||
|
||||
Reference in New Issue
Block a user