diff --git a/app/src/androidTest/assets/backupTests/account_data_00.binproto b/app/src/androidTest/assets/backupTests/account_data_00.binproto index 930fef9be2..12e22c994e 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_00.binproto and b/app/src/androidTest/assets/backupTests/account_data_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_01.binproto b/app/src/androidTest/assets/backupTests/account_data_01.binproto index 4389792403..ebf6db591c 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_01.binproto and b/app/src/androidTest/assets/backupTests/account_data_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_02.binproto b/app/src/androidTest/assets/backupTests/account_data_02.binproto index abf8888fb9..0abda25245 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_02.binproto and b/app/src/androidTest/assets/backupTests/account_data_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_03.binproto b/app/src/androidTest/assets/backupTests/account_data_03.binproto index b313f13749..31d7af97dc 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_03.binproto and b/app/src/androidTest/assets/backupTests/account_data_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_04.binproto b/app/src/androidTest/assets/backupTests/account_data_04.binproto index 3cb0dde101..9049824f43 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_04.binproto and b/app/src/androidTest/assets/backupTests/account_data_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_05.binproto b/app/src/androidTest/assets/backupTests/account_data_05.binproto index a9ba3887e2..35308d035a 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_05.binproto and b/app/src/androidTest/assets/backupTests/account_data_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_06.binproto b/app/src/androidTest/assets/backupTests/account_data_06.binproto index 44572df1e8..7bb18720c0 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_06.binproto and b/app/src/androidTest/assets/backupTests/account_data_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_07.binproto b/app/src/androidTest/assets/backupTests/account_data_07.binproto index dbf948079c..fd91e243f7 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_07.binproto and b/app/src/androidTest/assets/backupTests/account_data_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_08.binproto b/app/src/androidTest/assets/backupTests/account_data_08.binproto index 8781bc8c98..d63ec99c9d 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_08.binproto and b/app/src/androidTest/assets/backupTests/account_data_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_09.binproto b/app/src/androidTest/assets/backupTests/account_data_09.binproto index 44f05adaa8..c1f5e82832 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_09.binproto and b/app/src/androidTest/assets/backupTests/account_data_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_10.binproto b/app/src/androidTest/assets/backupTests/account_data_10.binproto index 4ee80eae8c..05df879b4a 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_10.binproto and b/app/src/androidTest/assets/backupTests/account_data_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_11.binproto b/app/src/androidTest/assets/backupTests/account_data_11.binproto index b804ffce36..c15d1d5585 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_11.binproto and b/app/src/androidTest/assets/backupTests/account_data_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_12.binproto b/app/src/androidTest/assets/backupTests/account_data_12.binproto index bccd830a1c..0591b596b7 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_12.binproto and b/app/src/androidTest/assets/backupTests/account_data_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_13.binproto b/app/src/androidTest/assets/backupTests/account_data_13.binproto index 7539406c3d..88689ac5c8 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_13.binproto and b/app/src/androidTest/assets/backupTests/account_data_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_14.binproto b/app/src/androidTest/assets/backupTests/account_data_14.binproto index 63b6e087bb..31c6f8b855 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_14.binproto and b/app/src/androidTest/assets/backupTests/account_data_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_15.binproto b/app/src/androidTest/assets/backupTests/account_data_15.binproto index a34fddf9b0..5c9a002e9a 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_15.binproto and b/app/src/androidTest/assets/backupTests/account_data_15.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_16.binproto b/app/src/androidTest/assets/backupTests/account_data_16.binproto index fbaefee333..cfa08b9947 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_16.binproto and b/app/src/androidTest/assets/backupTests/account_data_16.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_17.binproto b/app/src/androidTest/assets/backupTests/account_data_17.binproto index 87a8f3e5ab..dad8364349 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_17.binproto and b/app/src/androidTest/assets/backupTests/account_data_17.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_18.binproto b/app/src/androidTest/assets/backupTests/account_data_18.binproto index ff58c6f18a..e175c08f41 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_18.binproto and b/app/src/androidTest/assets/backupTests/account_data_18.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_19.binproto b/app/src/androidTest/assets/backupTests/account_data_19.binproto index 9b82f0c193..e3fdef2dc3 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_19.binproto and b/app/src/androidTest/assets/backupTests/account_data_19.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_20.binproto b/app/src/androidTest/assets/backupTests/account_data_20.binproto index a97e7f0bd6..b26bdbf4e9 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_20.binproto and b/app/src/androidTest/assets/backupTests/account_data_20.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_21.binproto b/app/src/androidTest/assets/backupTests/account_data_21.binproto index dc43c45deb..c52a09b538 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_21.binproto and b/app/src/androidTest/assets/backupTests/account_data_21.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_22.binproto b/app/src/androidTest/assets/backupTests/account_data_22.binproto index 69a932e8fd..34b4f9ad4b 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_22.binproto and b/app/src/androidTest/assets/backupTests/account_data_22.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_23.binproto b/app/src/androidTest/assets/backupTests/account_data_23.binproto index 6689dfdbfd..501b8a6f0d 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_23.binproto and b/app/src/androidTest/assets/backupTests/account_data_23.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_24.binproto b/app/src/androidTest/assets/backupTests/account_data_24.binproto index 6ec32daa62..a8d380e976 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_24.binproto and b/app/src/androidTest/assets/backupTests/account_data_24.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_25.binproto b/app/src/androidTest/assets/backupTests/account_data_25.binproto index 2d44211306..a3aee1d81f 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_25.binproto and b/app/src/androidTest/assets/backupTests/account_data_25.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_26.binproto b/app/src/androidTest/assets/backupTests/account_data_26.binproto index ea4c057c41..e1b6cbbe35 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_26.binproto and b/app/src/androidTest/assets/backupTests/account_data_26.binproto differ diff --git a/app/src/androidTest/assets/backupTests/account_data_27.binproto b/app/src/androidTest/assets/backupTests/account_data_27.binproto index ef83c99285..a2318802b1 100644 Binary files a/app/src/androidTest/assets/backupTests/account_data_27.binproto and b/app/src/androidTest/assets/backupTests/account_data_27.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_00.binproto b/app/src/androidTest/assets/backupTests/chat_00.binproto index 3dba406f9d..b5cc1a3ba4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_00.binproto and b/app/src/androidTest/assets/backupTests/chat_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_01.binproto b/app/src/androidTest/assets/backupTests/chat_01.binproto index 3eda02c9c3..0467e35123 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_01.binproto and b/app/src/androidTest/assets/backupTests/chat_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_02.binproto b/app/src/androidTest/assets/backupTests/chat_02.binproto index f5d6fa0067..25246afb3d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_02.binproto and b/app/src/androidTest/assets/backupTests/chat_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_03.binproto b/app/src/androidTest/assets/backupTests/chat_03.binproto index 428c6798f9..ad32f43e94 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_03.binproto and b/app/src/androidTest/assets/backupTests/chat_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_04.binproto b/app/src/androidTest/assets/backupTests/chat_04.binproto index ef40790d00..ddd2688f42 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_04.binproto and b/app/src/androidTest/assets/backupTests/chat_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_05.binproto b/app/src/androidTest/assets/backupTests/chat_05.binproto index 11304a626f..13db26d4ea 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_05.binproto and b/app/src/androidTest/assets/backupTests/chat_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_06.binproto b/app/src/androidTest/assets/backupTests/chat_06.binproto index 8b954d38e2..a818a196e5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_06.binproto and b/app/src/androidTest/assets/backupTests/chat_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_07.binproto b/app/src/androidTest/assets/backupTests/chat_07.binproto index 4cfc4df717..0cc4d39eef 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_07.binproto and b/app/src/androidTest/assets/backupTests/chat_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_08.binproto b/app/src/androidTest/assets/backupTests/chat_08.binproto index af462927b8..d854b90550 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_08.binproto and b/app/src/androidTest/assets/backupTests/chat_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_09.binproto b/app/src/androidTest/assets/backupTests/chat_09.binproto index bcc0409f70..fe3a7c34e1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_09.binproto and b/app/src/androidTest/assets/backupTests/chat_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_10.binproto b/app/src/androidTest/assets/backupTests/chat_10.binproto index cbd4585e83..165d34376c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_10.binproto and b/app/src/androidTest/assets/backupTests/chat_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_11.binproto b/app/src/androidTest/assets/backupTests/chat_11.binproto index daea7d3bce..e95a931df2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_11.binproto and b/app/src/androidTest/assets/backupTests/chat_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_12.binproto b/app/src/androidTest/assets/backupTests/chat_12.binproto index 44ce2fd62b..f885eb5c3f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_12.binproto and b/app/src/androidTest/assets/backupTests/chat_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_13.binproto b/app/src/androidTest/assets/backupTests/chat_13.binproto index dbd391e708..3c8fc80aba 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_13.binproto and b/app/src/androidTest/assets/backupTests/chat_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_14.binproto b/app/src/androidTest/assets/backupTests/chat_14.binproto index 772973b3fc..feb44958e4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_14.binproto and b/app/src/androidTest/assets/backupTests/chat_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_15.binproto b/app/src/androidTest/assets/backupTests/chat_15.binproto index 8807550d4e..78cb521749 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_15.binproto and b/app/src/androidTest/assets/backupTests/chat_15.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_16.binproto b/app/src/androidTest/assets/backupTests/chat_16.binproto index cecb85635f..22655afb06 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_16.binproto and b/app/src/androidTest/assets/backupTests/chat_16.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_17.binproto b/app/src/androidTest/assets/backupTests/chat_17.binproto index ee8fa2a346..668a4dc027 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_17.binproto and b/app/src/androidTest/assets/backupTests/chat_17.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_18.binproto b/app/src/androidTest/assets/backupTests/chat_18.binproto index 86ba047961..bedaf696ba 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_18.binproto and b/app/src/androidTest/assets/backupTests/chat_18.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_19.binproto b/app/src/androidTest/assets/backupTests/chat_19.binproto index cc4d79cb7d..86b532747e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_19.binproto and b/app/src/androidTest/assets/backupTests/chat_19.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_20.binproto b/app/src/androidTest/assets/backupTests/chat_20.binproto index 62067d8c1e..f6676c2937 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_20.binproto and b/app/src/androidTest/assets/backupTests/chat_20.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_21.binproto b/app/src/androidTest/assets/backupTests/chat_21.binproto index b807fae3c5..4ea0f9d7b5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_21.binproto and b/app/src/androidTest/assets/backupTests/chat_21.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_22.binproto b/app/src/androidTest/assets/backupTests/chat_22.binproto index cef596c97e..63797f65f6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_22.binproto and b/app/src/androidTest/assets/backupTests/chat_22.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_23.binproto b/app/src/androidTest/assets/backupTests/chat_23.binproto index f2decffcc5..befe449f73 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_23.binproto and b/app/src/androidTest/assets/backupTests/chat_23.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_24.binproto b/app/src/androidTest/assets/backupTests/chat_24.binproto index af05b5607b..a73835b84b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_24.binproto and b/app/src/androidTest/assets/backupTests/chat_24.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_25.binproto b/app/src/androidTest/assets/backupTests/chat_25.binproto index 3213db2c53..06a3854c05 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_25.binproto and b/app/src/androidTest/assets/backupTests/chat_25.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_26.binproto b/app/src/androidTest/assets/backupTests/chat_26.binproto index dbcf7b32a3..595468e1c9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_26.binproto and b/app/src/androidTest/assets/backupTests/chat_26.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_folder_00.binproto b/app/src/androidTest/assets/backupTests/chat_folder_00.binproto index cc97e0efe2..0a1f0cc037 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_folder_00.binproto and b/app/src/androidTest/assets/backupTests/chat_folder_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_folder_01.binproto b/app/src/androidTest/assets/backupTests/chat_folder_01.binproto index c17f83d676..d5c7883034 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_folder_01.binproto and b/app/src/androidTest/assets/backupTests/chat_folder_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_folder_02.binproto b/app/src/androidTest/assets/backupTests/chat_folder_02.binproto index 0fc2d39d3a..59e1ef56d3 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_folder_02.binproto and b/app/src/androidTest/assets/backupTests/chat_folder_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_folder_03.binproto b/app/src/androidTest/assets/backupTests/chat_folder_03.binproto index ee9be5c87e..9a81a5ec2d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_folder_03.binproto and b/app/src/androidTest/assets/backupTests/chat_folder_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_00.binproto index c3ba3adebf..d60b2cc6fc 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_01.binproto index e1f1c7c8b1..0b93708d00 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_02.binproto index b5fbaf90d3..5958964467 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_03.binproto index 06ffdd33a9..5f5dc1126a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_04.binproto index eba7b05744..e0ce2f6a4d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_05.binproto index 7d7dc339a1..ccf43166f6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_06.binproto index b0cb844395..cbf7a83214 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_07.binproto index 4c58ebcecc..04e6a306e1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_08.binproto index ce0ec19460..b2c9c89c95 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_09.binproto index 556869ee54..e53699a064 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_10.binproto index 41bd4309ba..ec3f85534b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_11.binproto index b23009c64a..c947cbc01f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_12.binproto index 7960153e5c..4a8ba09d7e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_13.binproto index 7d43c29852..823c042aa1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_contact_message_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_contact_message_14.binproto index 964701ccf1..d550c1b373 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_contact_message_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_contact_message_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_00.binproto index b9e69bb821..d6589a066b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_01.binproto index 7d22539640..a00cbaa563 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_02.binproto index 30de5bd0d7..5deec4e8e0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_03.binproto index 1217ac968b..62aded9d30 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_04.binproto index 57863c549d..724a5322a1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_05.binproto index 8c4fd29715..7960524537 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_06.binproto index 852ddc0f70..3481b30745 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_07.binproto index dd191cfba8..965181cb18 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_08.binproto index 8ca4a55972..9dc49d38af 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_09.binproto index 77af7f7fc0..2277ddcfad 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_10.binproto index dbf9f35246..82d73be647 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_11.binproto index 8ab0bf08bf..a7a841bf08 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_12.binproto index 9b9d2dac9d..91c5378c39 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_13.binproto index 0cbc5ad8ec..8d726bfff8 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_14.binproto index 7d9cfa1a7f..691c8917ac 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_00.binproto index 72ce2d59d5..3154da64ee 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_01.binproto index 5e61437106..bd969ca9d9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_02.binproto index a962fe37fc..a00a2392ec 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_03.binproto index e0a7084e88..820e2212ff 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_04.binproto index 9518ee23d4..070d17cd37 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_05.binproto index 90c2db5ad2..eeb307c85e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_06.binproto index d80251ffa3..954c1aa3ef 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_07.binproto index 415a43a7dc..e884d8c364 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_08.binproto index 6cebf5e9a5..ac64e2dd17 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_09.binproto index b6d294f404..561c939118 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_10.binproto index cf9a8b694e..2a640f5e0c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_direct_story_reply_with_edits_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_00.binproto index a9d17df69e..a22ea18864 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_01.binproto index db06c660ea..411d0eb720 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_02.binproto index c7fbf5c13f..a7f507987b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_03.binproto index 49a564ac47..4bf2265e8a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_04.binproto index 2e133c8480..0f4edf9f5b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_05.binproto index 2731dd0f22..a140a79d31 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_06.binproto index 0572e04d19..9c0b101d4c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_07.binproto index e6941ca8a1..23cffce86b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_08.binproto index 3674421636..89c1bdfbdd 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_09.binproto index 29791dd17c..c3f8f67e0e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_10.binproto index e568e17a77..f4c616ea9f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_11.binproto index af0d405b57..891c56b7c6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_12.binproto index 15d7e21b7a..fb68195463 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_13.binproto index d25a3e47c7..2f99fa57f1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_14.binproto index 02ca4063b4..af0dbfdd6a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_gift_badge_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_gift_badge_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_00.binproto index 31a0c3853a..823064b8ef 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_01.binproto index 089a33777a..884fca74e2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_02.binproto index 8d16efbb74..f30bbe4a63 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_03.binproto index 44c3411537..7fc4d4317e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_04.binproto index 14ec8a67f4..76082d6498 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_05.binproto index e9ae913ec1..79fcaa4263 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_06.binproto index b07d7cf808..0da136c811 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_07.binproto index 0513ebc606..bb1835d8b0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_08.binproto index 7254e28a56..c8c175302b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_multiple_update_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_00.binproto index 0d03c30ec0..f7fb12311f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_01.binproto index 1063d34c8d..ac24ca2125 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_02.binproto index fd1d2ff3c6..1abe78d2c2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_03.binproto index e6bb96519b..b56d53867b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_04.binproto index 5f52295fa7..eb91a13a8c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_05.binproto index 63d3f6318a..2ef6cd19f8 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_06.binproto index 4397657868..632d212f87 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_07.binproto index 73e19bf549..c266f408b7 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_08.binproto index f8d3411746..95feeb3846 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_09.binproto index 4425908fa9..e9c5a66125 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_10.binproto index da4e7e36ec..0f1d179b15 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_11.binproto index 41e3868ce3..5b5da23430 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_12.binproto index 7954c537bf..c1f82e26ad 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_13.binproto index b5d238b0f3..1297329fc4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_14.binproto index bc9b40bf7e..3407dc0fd8 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_15.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_15.binproto index 14938f8512..a97216aeb3 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_15.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_15.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_16.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_16.binproto index 4e88e890af..d16562c7ac 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_16.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_16.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_17.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_17.binproto index 8a84f4253e..f83f05e543 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_17.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_17.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_18.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_18.binproto index ef3167a4f7..26932fe0ba 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_18.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_18.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_19.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_19.binproto index aa139a289d..773799f385 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_19.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_19.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_20.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_20.binproto index 3c2ad649c8..d0ccb5db9a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_20.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_20.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_21.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_21.binproto index 3895df58b8..3c3276de74 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_21.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_21.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_22.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_22.binproto index c4edfa4eb8..9dbb281ba3 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_22.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_22.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_23.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_23.binproto index 056bb57da3..e027381a54 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_23.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_23.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_24.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_24.binproto index 23169fe556..2ea11a67ca 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_24.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_24.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_25.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_25.binproto index 2353c6cf5c..4e1f05eb5f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_25.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_25.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_26.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_26.binproto index 2dc6e3d996..cfee33cba6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_26.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_26.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_27.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_27.binproto index 622c5b076e..dd84182548 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_27.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_27.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_28.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_28.binproto index 33dea2e965..f0f1103af2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_28.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_28.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_29.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_29.binproto index a509a05665..b5130c3047 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_29.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_29.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_30.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_30.binproto index 2183a5e3d6..bf889a230c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_30.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_30.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_31.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_31.binproto index c27b07ee96..2925a7f6ef 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_31.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_31.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_32.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_32.binproto index 37999f2e2b..f1f2c48311 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_32.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_32.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_33.binproto b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_33.binproto index ee5759183f..79afae46da 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_33.binproto and b/app/src/androidTest/assets/backupTests/chat_item_group_change_chat_update_33.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_00.binproto index d31734cc5c..c43a452070 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_01.binproto index 88e4052921..d645a2452f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_02.binproto index e0008a3fb3..7b16164acb 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_03.binproto index 310e55cf3d..e6435ff62c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_04.binproto index 64b4635901..191d2de7e1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_05.binproto index 56ba297e91..7aba5d6faf 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_06.binproto index 6c8f586fad..43e8e7d5b4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_07.binproto index 3951e2e40b..326aad26c6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_08.binproto index 02ebef2de5..ffeac0913c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_09.binproto index 2302fa7ab5..489f83566e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_10.binproto index 8bdd5ef461..acd8c8db52 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_11.binproto index 3663d2a4f5..1183ac128a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_12.binproto index 1639144949..3296e8ce2b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_13.binproto index 1924dc523b..cad152580d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_14.binproto index 436433d0a4..0a3ac457af 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_payment_notification_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_payment_notification_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_00.binproto index ccf0933371..b017b057f9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_01.binproto index 442453e55f..767fa2c1e6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_02.binproto index ccf5d935ee..f425845834 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_03.binproto index ed8d2743ff..c373526b2a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_04.binproto index d1ab375595..d4e0679161 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_05.binproto index 917a992c00..cbd66f6792 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_06.binproto index d91cd80e1b..c93c838c57 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_07.binproto index 51faac4747..4ab531fbef 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_08.binproto index 079b440674..399a36e086 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_09.binproto index 1b84609d4f..312717584c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_10.binproto index 57d13ce59a..b674c124d9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_11.binproto index c4667ff351..c9bc5f399c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_12.binproto index d498235d7b..d26b7628d2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_13.binproto index d4621a2484..cd2791ede9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_14.binproto index c59c450568..03e4d7cefc 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_remote_delete_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_remote_delete_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_00.binproto index ffe052779e..a1157973d2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_01.binproto index 1e81ef6832..d36988332b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_02.binproto index f063a9db34..f81484c314 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_03.binproto index 1d9c25d81d..feea7c7f72 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_04.binproto index e858b7d7a6..54eb6ae3e1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_05.binproto index 868ceb312a..2485cc03e3 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_06.binproto index fa25914abd..71fa31e4ee 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_07.binproto index f336814dc7..0d3593c7cf 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_08.binproto index 6461a067b5..17c1f76e00 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_09.binproto index 7cb90f5ec5..4e14923533 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_10.binproto index f70bb3ffdc..d73ff833e0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_11.binproto index 824c126f7c..4c80639c7a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_12.binproto index 3c327aa3e8..f85145cecc 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_13.binproto index 53fb0dd6c8..0e5a964593 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_14.binproto index 7bf920e8c8..f9b501a9ca 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_formatted_text_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_00.binproto index 3773f14a70..0872e219b0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_01.binproto index 23c6a8f964..62a2eb3eb5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_02.binproto index 421a31aea1..ce726b9683 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_03.binproto index 2b210a81fb..ca01243250 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_04.binproto index 172f67ddb1..60ad2e1b1a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_05.binproto index d5dcdc93cf..64de0f9de7 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_06.binproto index 51878197e5..c1905bc0d0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_07.binproto index b0eba70d3d..19e6ae2f0c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_08.binproto index 74e81cbab9..5ef6e3e794 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_09.binproto index 5cb464b13f..053158a0c2 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_10.binproto index 82d5e43882..043b9ae852 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_11.binproto index 6e7df96b5b..2bf0b96178 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_12.binproto index aa0cfcfe5d..b81c6a15ad 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_13.binproto index 2aa9b391df..0375d18fbc 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_14.binproto index 993ad746b4..f43753776a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_long_text_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_00.binproto index bdb56ae7d1..4e8fed95ac 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_01.binproto index 9775c36b7e..a80f49fdf3 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_02.binproto index c68f336276..cd01efba24 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_03.binproto index 55c380de2e..9442dedc8a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_04.binproto index e60ec3b028..68c1306c84 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_05.binproto index e673f1123c..3ca89b7638 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_06.binproto index d498d4728f..6ef1a1d6d4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_07.binproto index d2d2f91bc6..61e05b440f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_08.binproto index 817cd32fa0..9cc6cbee70 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_09.binproto index 4cdb958225..c61fd6825f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_10.binproto index 0c79ec802c..0d7c9c39e4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_11.binproto index 8b0d759560..2d0c770d46 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_12.binproto index ad53a185c0..feb09dc772 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_13.binproto index a1765c9a55..21bbcfe8eb 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_14.binproto index b2f0f0e248..eb027926e6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_sms_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_00.binproto index 04fd57b73a..668a69b07d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_01.binproto index b2b4a0dde2..bfb4689640 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_02.binproto index 5d477fda48..748953ca69 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_03.binproto index 5d0733805b..79ee80da9a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_04.binproto index f58d3d1d74..55e8596972 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_05.binproto index 0e6b09b63f..c5a8eef798 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_06.binproto index cfab6bd85f..5ead9dc848 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_07.binproto index 4bfe55a924..0164f1ced5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_08.binproto index ec545d3094..0ab8537214 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_09.binproto index 220bc2ec90..d042e7b4ed 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_10.binproto index 1a8b492bc3..099ff35112 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_11.binproto index fd0286e9b5..b499ac6518 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_12.binproto index 01ca790064..c49c335f65 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_13.binproto index c47560b30b..856ab1f681 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_14.binproto index d56316ee10..4788c508ca 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_special_attachments_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_00.binproto index 8ef3ccc0c5..57c32011aa 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_01.binproto index 04d9714a59..4089f263de 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_02.binproto index e08bf6ca90..48cfe64259 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_03.binproto index e8ac0cf436..d0db77285f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_04.binproto index 4f99799c64..c23efb59c6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_05.binproto index 4df88f857c..58b76fe610 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_06.binproto index 896cefea8e..f308f98e22 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_07.binproto index eae3a56330..0fdd517aea 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_08.binproto index 1db2c3bdff..2963f1dc63 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_09.binproto index 82396c984f..ed346f2c37 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_10.binproto index 1f4ac06de0..22bff7e216 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_11.binproto index e404cc7c7c..6fda1fcbb9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_12.binproto index 69e2bb43c5..6dc70c84a4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_13.binproto index a298ca01a7..39a12a83cf 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_14.binproto index e0b2532aa5..915d255bce 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_standard_attachments_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_00.binproto index d34c5dcc58..b7bb281397 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_01.binproto index cc803cdb61..acf3f0551e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_02.binproto index 5a5d19cacd..dd1cf9b6bc 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_03.binproto index d153613ac9..0100566f84 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_04.binproto index 1198c39d86..cd64e94d34 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_05.binproto index cb543ed123..8120761082 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_06.binproto index 12bc152a20..e6fb110b5c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_07.binproto index 183379c426..b9674e4561 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_08.binproto index 9d86996e00..af80d29802 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_09.binproto index 39be5a4d58..ca12ee7076 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_10.binproto index a09fa28f37..901e11f6f1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_11.binproto index 519a5f85ad..7997fb5490 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_12.binproto index 81c7b158a9..2535a280be 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_13.binproto index a66aa23282..8c20f123cf 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_14.binproto index 7c9c5f9120..be5a8c3f66 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_text_only_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_00.binproto index 829314faf1..7081787fb8 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_01.binproto index f2601b768d..806d8539f5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_02.binproto index 3dfc638594..7b1ebc096f 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_edits_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_00.binproto index b6554998a7..5f12a71b7c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_01.binproto index d1b1a5dafb..0857d50063 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_02.binproto index cc86d85481..c504d4e195 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_03.binproto index e8023ef5dc..517e17d494 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_04.binproto index 694c0ca149..a8fa7fdaf9 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_05.binproto index 68be1e7f51..6a829d50da 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_06.binproto index 5b99c7cf1c..0c52e2bb28 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_07.binproto index 123920193a..593a9f05c6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_08.binproto index 4b58ecc3a7..56a951829e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_09.binproto index 42e1d10113..4c4ed795fd 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_10.binproto index 67cb595f17..5ee32d7d02 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_11.binproto index 7c5c2df68a..8e1707f465 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_12.binproto index b2856d6666..020f82b5f6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_13.binproto index b5266b2f35..8e9929e92b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_14.binproto index d0041bd8cf..808edcd6e4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_link_preview_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_00.binproto index 9c25c3e8d6..7bc1c0cbda 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto index 476d998262..adb25a5f41 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_02.binproto index 1cd2f41406..a9aaecc105 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_03.binproto index 99aac1c830..92ef5c7354 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_04.binproto index 998f9e9a95..a08966a22d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_05.binproto index 5a26cdcf8c..74181c146d 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto index 653c24360f..0e1cf09ce4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_07.binproto index 4bc6c59b1b..85b709cbd4 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_08.binproto index 918e388011..f42379c442 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_09.binproto index c7a2729eeb..93cb1488a0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_10.binproto index 5f4e8c3f71..e129edfe1a 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto index 006e204e7c..a9d4a9500e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_12.binproto index 827eafd581..8a3f8ae4a0 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto index b1e61d43af..d9c82f37c1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto index efa0e49a17..816fc66d31 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_00.binproto index f11189aaea..c292838eca 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_01.binproto index 0cdb5ebc72..a7577a8940 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_02.binproto index abc7f3bb82..b95e90add5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_03.binproto index 47beb147d3..0d9528549e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_04.binproto index e67682f5b3..638b012d28 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_05.binproto index 31c8d75c53..8d4d29498e 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_06.binproto index b96e8a27ae..799a01a0ec 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_07.binproto index 507664766c..df8edc1d11 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_08.binproto index 147cc07d8d..1845d7aae5 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_09.binproto index e9be214aa8..76b0805f92 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_10.binproto index 7cb1c6ecd5..0ae3ca1e98 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_11.binproto index d9160805b8..b575a6bba1 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_12.binproto index 0e0f36c7a9..246421dbb6 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_13.binproto index 81378115f2..b59484f06c 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_14.binproto index 16e20e3285..d8d5c3c6da 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_sticker_message_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_sticker_message_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_00.binproto index e2d6569756..f658afc248 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_00.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_01.binproto index 6a187b1c08..f1be90bc1b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_01.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_02.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_02.binproto index bfe2d481bf..06b53fb232 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_02.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_03.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_03.binproto index ef08963db4..eae21b361b 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_03.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_04.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_04.binproto index f74d5337d1..d3425e12fa 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_04.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_05.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_05.binproto index 2617acf09f..4cd770e609 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_05.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_06.binproto index ce4bbbef05..7a02b0b6ac 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_06.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_07.binproto index e89a4b2234..3c319f0163 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_07.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_08.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_08.binproto index 4f5cc9712b..f502647e44 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_08.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_09.binproto index 05c6c657c2..c560ee4874 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_09.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_10.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_10.binproto index 342c6cba78..cb5c0fa206 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_10.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_11.binproto index b8fa5a5dab..83834d2adf 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_11.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_12.binproto index 732254af87..af2792e2fd 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_12.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_12.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_13.binproto index c0764c40b4..3ad6d1c8c7 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_13.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_13.binproto differ diff --git a/app/src/androidTest/assets/backupTests/chat_item_view_once_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_view_once_14.binproto index cd6c169271..d25ad113ea 100644 Binary files a/app/src/androidTest/assets/backupTests/chat_item_view_once_14.binproto and b/app/src/androidTest/assets/backupTests/chat_item_view_once_14.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_00.binproto b/app/src/androidTest/assets/backupTests/notification_profile_00.binproto index ba86841538..26645e19aa 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_00.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_01.binproto b/app/src/androidTest/assets/backupTests/notification_profile_01.binproto index 4bc4b96657..4d87f846fb 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_01.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_02.binproto b/app/src/androidTest/assets/backupTests/notification_profile_02.binproto index ff058e2ff7..0a8a73c783 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_02.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_03.binproto b/app/src/androidTest/assets/backupTests/notification_profile_03.binproto index de20ced25e..d4aa60c711 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_03.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_04.binproto b/app/src/androidTest/assets/backupTests/notification_profile_04.binproto index f85c699e35..bdd289eb72 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_04.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_05.binproto b/app/src/androidTest/assets/backupTests/notification_profile_05.binproto index 04c8048e18..746e5c92ef 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_05.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_06.binproto b/app/src/androidTest/assets/backupTests/notification_profile_06.binproto index 636634a2d9..e26a740bc4 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_06.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_07.binproto b/app/src/androidTest/assets/backupTests/notification_profile_07.binproto index 4da8e55dc8..4aae82fbd0 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_07.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_08.binproto b/app/src/androidTest/assets/backupTests/notification_profile_08.binproto index 1aad305397..c2faa65292 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_08.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_09.binproto b/app/src/androidTest/assets/backupTests/notification_profile_09.binproto index e76246a52f..49add81696 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_09.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_10.binproto b/app/src/androidTest/assets/backupTests/notification_profile_10.binproto index 04311e2fa5..5e8135bb02 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_10.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/notification_profile_11.binproto b/app/src/androidTest/assets/backupTests/notification_profile_11.binproto index 092a36ff20..fdb40ad8e9 100644 Binary files a/app/src/androidTest/assets/backupTests/notification_profile_11.binproto and b/app/src/androidTest/assets/backupTests/notification_profile_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_00.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_00.binproto index 188bbf1633..1129e03fd4 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_00.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_01.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_01.binproto index 18a03fa1b7..d0726446bd 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_01.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_02.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_02.binproto index 7fb227c761..3b3ffebab0 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_02.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_03.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_03.binproto index 5f602ec265..f11d1b0c9c 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_03.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_04.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_04.binproto index effe33c600..42cc6bc7b2 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_04.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_05.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_05.binproto index 1a03a944a5..c2a7e462ef 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_05.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_06.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_06.binproto index 0f3f671db0..bf15218a01 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_06.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_07.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_07.binproto index bf94a61835..8613dfd36f 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_07.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_08.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_08.binproto index 8a1a86c4d4..fdf11b5238 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_08.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_09.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_09.binproto index bd7912df09..66531835e6 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_09.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_10.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_10.binproto index 395596400b..547d8f1d0d 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_10.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_contacts_11.binproto b/app/src/androidTest/assets/backupTests/recipient_contacts_11.binproto index ef18d9da2d..4f54f4ae2e 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_contacts_11.binproto and b/app/src/androidTest/assets/backupTests/recipient_contacts_11.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_distribution_list_00.binproto b/app/src/androidTest/assets/backupTests/recipient_distribution_list_00.binproto index 37419ba59b..c690f11ca1 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_distribution_list_00.binproto and b/app/src/androidTest/assets/backupTests/recipient_distribution_list_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_distribution_list_01.binproto b/app/src/androidTest/assets/backupTests/recipient_distribution_list_01.binproto index ff22da0db2..4bf8235ea4 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_distribution_list_01.binproto and b/app/src/androidTest/assets/backupTests/recipient_distribution_list_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_distribution_list_02.binproto b/app/src/androidTest/assets/backupTests/recipient_distribution_list_02.binproto index d64e13841e..c1e929b8d2 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_distribution_list_02.binproto and b/app/src/androidTest/assets/backupTests/recipient_distribution_list_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_distribution_list_03.binproto b/app/src/androidTest/assets/backupTests/recipient_distribution_list_03.binproto index 70ab5137fd..763629a999 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_distribution_list_03.binproto and b/app/src/androidTest/assets/backupTests/recipient_distribution_list_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_00.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_00.binproto index bd64b3af3a..b3df57e51d 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_00.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_00.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_01.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_01.binproto index d471bf0ccf..16b25c1e30 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_01.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_01.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_02.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_02.binproto index 8d5931e648..7e83aee026 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_02.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_02.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_03.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_03.binproto index 7d880ca4d0..627ebfa001 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_03.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_03.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_04.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_04.binproto index 74fffbb495..f0e23d0859 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_04.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_04.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_05.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_05.binproto index 5ad6e57f27..75a60c4d44 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_05.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_05.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_06.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_06.binproto index 50b3ca41ea..05f177bd6f 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_06.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_06.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_07.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_07.binproto index 01350e2de5..d2b0d3bb98 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_07.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_07.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_08.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_08.binproto index 8bdb424e20..a032b11d9b 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_08.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_08.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_09.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_09.binproto index e133bcd165..7ba84602c1 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_09.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_09.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_10.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_10.binproto index 167f53fce3..82e11ff8c8 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_10.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_10.binproto differ diff --git a/app/src/androidTest/assets/backupTests/recipient_groups_11.binproto b/app/src/androidTest/assets/backupTests/recipient_groups_11.binproto index 55e0f3fce5..6f3a874551 100644 Binary files a/app/src/androidTest/assets/backupTests/recipient_groups_11.binproto and b/app/src/androidTest/assets/backupTests/recipient_groups_11.binproto differ diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt index 2756e0964f..cf87832881 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest.kt @@ -15,6 +15,7 @@ import org.junit.Before import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith +import org.signal.core.util.Base64.decodeBase64OrThrow import org.signal.core.util.copyTo import org.signal.core.util.readFully import org.signal.core.util.stream.NullOutputStream @@ -200,7 +201,7 @@ class AttachmentTableTest { // Give data to attachment table val cipherInputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintext.size.toLong(), key, badlyPaddedDigest, null, 4) - SignalDatabase.attachments.finalizeAttachmentAfterDownload(mmsId, attachmentId, cipherInputStream, iv) + SignalDatabase.attachments.finalizeAttachmentAfterDownload(mmsId, attachmentId, cipherInputStream) // Verify the digest has been updated to the properly padded one val properlyPaddedPlaintext = PaddingInputStream(plaintext.inputStream(), plaintext.size.toLong()).readFully() @@ -231,7 +232,7 @@ class AttachmentTableTest { // Give data to attachment table val cipherInputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintext.size.toLong(), key, digest, null, 4) - SignalDatabase.attachments.finalizeAttachmentAfterDownload(mmsId, attachmentId, cipherInputStream, iv) + SignalDatabase.attachments.finalizeAttachmentAfterDownload(mmsId, attachmentId, cipherInputStream) // Verify the digest hasn't changed val newDigest = SignalDatabase.attachments.getAttachment(attachmentId)!!.remoteDigest!! @@ -239,7 +240,7 @@ class AttachmentTableTest { } @Test - fun resetArchiveTransferStateByDigest_singleMatch() { + fun resetArchiveTransferStateByPlaintextHashAndRemoteKey_singleMatch() { // Given an attachment with some digest val blob = BlobProvider.getInstance().forData(byteArrayOf(1, 2, 3, 4, 5)).createForSingleSessionInMemory() val attachment = createAttachment(1, blob, AttachmentTable.TransformProperties.empty()) @@ -248,8 +249,9 @@ class AttachmentTableTest { SignalDatabase.attachments.setArchiveTransferState(attachmentId, AttachmentTable.ArchiveTransferState.FINISHED) // Reset the transfer state by digest - val digest = SignalDatabase.attachments.getAttachment(attachmentId)!!.remoteDigest!! - SignalDatabase.attachments.resetArchiveTransferStateByDigest(digest) + val plaintextHash = SignalDatabase.attachments.getAttachment(attachmentId)!!.dataHash!!.decodeBase64OrThrow() + val remoteKey = SignalDatabase.attachments.getAttachment(attachmentId)!!.remoteKey!!.decodeBase64OrThrow() + SignalDatabase.attachments.resetArchiveTransferStateByPlaintextHashAndRemoteKey(plaintextHash, remoteKey) // Verify it's been reset assertThat(SignalDatabase.attachments.getAttachment(attachmentId)!!.archiveTransferState).isEqualTo(AttachmentTable.ArchiveTransferState.NONE) diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTestUtil.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTestUtil.kt index 6b4d651eee..d5dab750a7 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTestUtil.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTestUtil.kt @@ -22,7 +22,6 @@ object AttachmentTableTestUtil { remoteId = SignalServiceAttachmentRemoteId.V4("somewhere-${Random.nextLong()}"), cdnNumber = Cdn.CDN_3.cdnNumber, key = databaseAttachment.remoteKey?.let { Base64.decode(it) } ?: Util.getSecretBytes(64), - iv = databaseAttachment.remoteIv ?: Util.getSecretBytes(16), digest = Random.nextBytes(32), incrementalDigest = Random.nextBytes(16), incrementalDigestChunkSize = 5, diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest_deduping.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest_deduping.kt index 2a59eeeae9..811ce65bc8 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest_deduping.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/AttachmentTableTest_deduping.kt @@ -726,7 +726,7 @@ class AttachmentTableTest_deduping { } fun upload(attachmentId: AttachmentId, uploadTimestamp: Long = System.currentTimeMillis()) { - SignalDatabase.attachments.createKeyIvIfNecessary(attachmentId) + SignalDatabase.attachments.createRemoteKeyIfNecessary(attachmentId) SignalDatabase.attachments.finalizeAttachmentAfterUpload(attachmentId, AttachmentTableTestUtil.createUploadResult(attachmentId, uploadTimestamp)) val attachment = SignalDatabase.attachments.getAttachment(attachmentId)!! @@ -747,8 +747,7 @@ class AttachmentTableTest_deduping { SignalDatabase.attachments.finalizeAttachmentAfterDownload( mmsId = 1, attachmentId = attachmentId, - inputStream = LimitedInputStream(paddedData.inputStream(), data.size.toLong()), - iv = Util.getSecretBytes(16) + inputStream = LimitedInputStream(paddedData.inputStream(), data.size.toLong()) ) } @@ -842,7 +841,6 @@ class AttachmentTableTest_deduping { assertEquals(lhsAttachment.remoteLocation, rhsAttachment.remoteLocation) assertEquals(lhsAttachment.remoteKey, rhsAttachment.remoteKey) - assertArrayEquals(lhsAttachment.remoteIv, rhsAttachment.remoteIv) assertArrayEquals(lhsAttachment.remoteDigest, rhsAttachment.remoteDigest) assertArrayEquals(lhsAttachment.incrementalDigest, rhsAttachment.incrementalDigest) assertEquals(lhsAttachment.incrementalMacChunkSize, rhsAttachment.incrementalMacChunkSize) diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTableTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTableTest.kt index c797c4b8c9..f0f26ff1c8 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTableTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTableTest.kt @@ -146,7 +146,8 @@ class BackupMediaSnapshotTableTest { val mismatches = SignalDatabase.backupMediaSnapshots.getMediaObjectsWithNonMatchingCdn(remoteData) assertThat(mismatches.size).isEqualTo(1) assertThat(mismatches[0].cdn).isEqualTo(99) - assertThat(mismatches[0].digest).isEqualTo(localData[1].digest) + assertThat(mismatches[0].plaintextHash).isEqualTo(localData[1].plaintextHash) + assertThat(mismatches[0].remoteKey).isEqualTo(localData[1].remoteKey) } @Test @@ -300,7 +301,8 @@ class BackupMediaSnapshotTableTest { mediaId = "media_id_$seed", thumbnailMediaId = "thumbnail_media_id_$seed", cdn = cdn, - digest = Util.toByteArray(seed) + plaintextHash = Util.toByteArray(seed), + remoteKey = Util.toByteArray(seed) ) } diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_synchronizeDeleteForMe.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_synchronizeDeleteForMe.kt index d58e5ea9cb..ea215371fa 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_synchronizeDeleteForMe.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/messages/SyncMessageProcessorTest_synchronizeDeleteForMe.kt @@ -684,7 +684,6 @@ class SyncMessageProcessorTest_synchronizeDeleteForMe { cdn = this.cdn, location = this.remoteLocation, key = this.remoteKey, - iv = this.remoteIv, digest = digest, incrementalDigest = this.incrementalDigest, incrementalMacChunkSize = this.incrementalMacChunkSize, @@ -718,7 +717,6 @@ class SyncMessageProcessorTest_synchronizeDeleteForMe { remoteId = SignalServiceAttachmentRemoteId.V4(this.remoteLocation ?: "some-location"), cdnNumber = this.cdn.cdnNumber, key = this.remoteKey?.let { Base64.decode(it) } ?: Util.getSecretBytes(64), - iv = this.remoteIv ?: Util.getSecretBytes(16), digest = digest, incrementalDigest = this.incrementalDigest, incrementalDigestChunkSize = this.incrementalMacChunkSize, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/ArchivedAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/ArchivedAttachment.kt index 492de4a058..0dd4b92971 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/ArchivedAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/ArchivedAttachment.kt @@ -23,13 +23,7 @@ class ArchivedAttachment : Attachment { val archiveCdn: Int? @JvmField - val archiveMediaName: String - - @JvmField - val archiveMediaId: String - - @JvmField - val archiveThumbnailMediaId: String + val plaintextHash: ByteArray constructor( contentType: String?, @@ -37,13 +31,9 @@ class ArchivedAttachment : Attachment { cdn: Int, uploadTimestamp: Long?, key: ByteArray, - iv: ByteArray?, cdnKey: String?, archiveCdn: Int?, - archiveMediaName: String, - archiveMediaId: String, - archiveThumbnailMediaId: String, - digest: ByteArray, + plaintextHash: ByteArray, incrementalMac: ByteArray?, incrementalMacChunkSize: Int?, width: Int?, @@ -66,8 +56,7 @@ class ArchivedAttachment : Attachment { cdn = Cdn.fromCdnNumber(cdn), remoteLocation = cdnKey, remoteKey = Base64.encodeWithoutPadding(key), - remoteIv = iv, - remoteDigest = digest, + remoteDigest = null, incrementalDigest = incrementalMac, fastPreflightId = null, voiceNote = voiceNote, @@ -85,24 +74,18 @@ class ArchivedAttachment : Attachment { uuid = uuid ) { this.archiveCdn = archiveCdn - this.archiveMediaName = archiveMediaName - this.archiveMediaId = archiveMediaId - this.archiveThumbnailMediaId = archiveThumbnailMediaId + this.plaintextHash = plaintextHash } constructor(parcel: Parcel) : super(parcel) { archiveCdn = parcel.readInt().takeIf { it != NO_ARCHIVE_CDN } - archiveMediaName = parcel.readString()!! - archiveMediaId = parcel.readString()!! - archiveThumbnailMediaId = parcel.readString()!! + plaintextHash = parcel.createByteArray()!! } override fun writeToParcel(dest: Parcel, flags: Int) { super.writeToParcel(dest, flags) dest.writeInt(archiveCdn ?: NO_ARCHIVE_CDN) - dest.writeString(archiveMediaName) - dest.writeString(archiveMediaId) - dest.writeString(archiveThumbnailMediaId) + dest.writeByteArray(plaintextHash) } override val uri: Uri? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt index 38c8db6410..291298d781 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/Attachment.kt @@ -39,8 +39,6 @@ abstract class Attachment( @JvmField val remoteKey: String?, @JvmField - val remoteIv: ByteArray?, - @JvmField val remoteDigest: ByteArray?, @JvmField val incrementalDigest: ByteArray?, @@ -90,7 +88,6 @@ abstract class Attachment( cdn = Cdn.deserialize(parcel.readInt()), remoteLocation = parcel.readString(), remoteKey = parcel.readString(), - remoteIv = ParcelUtil.readByteArray(parcel), remoteDigest = ParcelUtil.readByteArray(parcel), incrementalDigest = ParcelUtil.readByteArray(parcel), fastPreflightId = parcel.readString(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt index 8f47b5ac9a..313e06438a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachment.kt @@ -54,7 +54,6 @@ class DatabaseAttachment : Attachment { cdn: Cdn, location: String?, key: String?, - iv: ByteArray?, digest: ByteArray?, incrementalDigest: ByteArray?, incrementalMacChunkSize: Int, @@ -85,7 +84,6 @@ class DatabaseAttachment : Attachment { cdn = cdn, remoteLocation = location, remoteKey = key, - remoteIv = iv, remoteDigest = digest, incrementalDigest = incrementalDigest, fastPreflightId = fastPreflightId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt index 0ddef132e8..7c14cb93be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/PointerAttachment.kt @@ -47,7 +47,6 @@ class PointerAttachment : Attachment { cdn = cdn, remoteLocation = location, remoteKey = key, - remoteIv = iv, remoteDigest = digest, incrementalDigest = incrementalDigest, fastPreflightId = fastPreflightId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt index a784561846..8c4cb92a49 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/TombstoneAttachment.kt @@ -23,7 +23,6 @@ class TombstoneAttachment : Attachment { cdn = Cdn.CDN_0, remoteLocation = null, remoteKey = null, - remoteIv = null, remoteDigest = null, incrementalDigest = null, fastPreflightId = null, @@ -66,7 +65,6 @@ class TombstoneAttachment : Attachment { cdn = Cdn.CDN_0, remoteLocation = null, remoteKey = null, - remoteIv = null, remoteDigest = null, incrementalDigest = incrementalMac, fastPreflightId = null, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt index e6182fc95a..18439eb2e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/UriAttachment.kt @@ -75,7 +75,6 @@ class UriAttachment : Attachment { cdn = Cdn.CDN_0, remoteLocation = null, remoteKey = null, - remoteIv = null, remoteDigest = null, incrementalDigest = null, fastPreflightId = fastPreflightId, diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/WallpaperAttachment.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/WallpaperAttachment.kt index 06877ef329..c6e4d417c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/WallpaperAttachment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/WallpaperAttachment.kt @@ -20,7 +20,6 @@ class WallpaperAttachment() : Attachment( cdn = Cdn.CDN_0, remoteLocation = null, remoteKey = null, - remoteIv = null, remoteDigest = null, incrementalDigest = null, fastPreflightId = null, diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/ArchiveUploadProgress.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/ArchiveUploadProgress.kt index fc26147a00..490fea2e55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/ArchiveUploadProgress.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/ArchiveUploadProgress.kt @@ -22,7 +22,6 @@ import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.jobs.ArchiveCommitAttachmentDeletesJob import org.thoughtcrime.securesms.jobs.ArchiveThumbnailUploadJob -import org.thoughtcrime.securesms.jobs.BackfillDigestJob import org.thoughtcrime.securesms.jobs.UploadAttachmentToArchiveJob import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.protos.ArchiveUploadProgressState @@ -109,7 +108,6 @@ object ArchiveUploadProgress { ) } - AppDependencies.jobManager.cancelAllInQueue(BackfillDigestJob.QUEUE) AppDependencies.jobManager.cancelAllInQueue(ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE) UploadAttachmentToArchiveJob.getAllQueueKeys().forEach { AppDependencies.jobManager.cancelAllInQueue(it) @@ -126,7 +124,7 @@ object ArchiveUploadProgress { Log.d(TAG, "Flushing job manager queue...") AppDependencies.jobManager.flush() - val queues = setOf(BackfillDigestJob.QUEUE, ArchiveThumbnailUploadJob.KEY, ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE) + UploadAttachmentToArchiveJob.getAllQueueKeys() + val queues = setOf(ArchiveThumbnailUploadJob.KEY, ArchiveCommitAttachmentDeletesJob.ARCHIVE_ATTACHMENT_QUEUE) + UploadAttachmentToArchiveJob.getAllQueueKeys() Log.d(TAG, "Waiting for cancelations to occur...") while (!AppDependencies.jobManager.areQueuesEmpty(queues)) { delay(1.seconds) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index 5e113f6fe7..30215f8d53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -691,7 +691,7 @@ object BackupRepository { val localArchivableAttachments = dbSnapshot .attachmentTable .getLocalArchivableAttachments() - .associateBy { MediaName.fromDigest(it.remoteDigest) } + .associateBy { MediaName.fromPlaintextHashAndRemoteKey(it.plaintextHash, it.remoteKey) } localBackupProgressEmitter.onAttachment(0, localArchivableAttachments.size.toLong()) @@ -1965,13 +1965,14 @@ class ArchiveMediaItemIterator(private val cursor: Cursor) : Iterator - val iv = attachment.remoteIv val combinedKey = Base64.decode(attachment.remoteKey) val destination: OutputStream? = filesFileSystem.fileOutputStream(mediaName) @@ -84,7 +83,7 @@ object LocalArchiver { // todo [local-backup] but deal with attachment disappearing/deleted by normal app use try { PaddingInputStream(sourceStream, attachment.size).use { input -> - AttachmentCipherOutputStream(combinedKey, iv, destination).use { output -> + AttachmentCipherOutputStream(combinedKey, null, destination).use { output -> StreamUtil.copy(input, output) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/util/ArchiveConverterExtensions.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/util/ArchiveConverterExtensions.kt index 0d077d3e44..16e1c825c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/util/ArchiveConverterExtensions.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/util/ArchiveConverterExtensions.kt @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.backup.v2.proto.FilePointer import org.thoughtcrime.securesms.conversation.colors.AvatarColor import org.thoughtcrime.securesms.database.AttachmentTable import org.thoughtcrime.securesms.stickers.StickerLocator -import org.whispersystems.signalservice.api.backup.MediaName import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId import org.whispersystems.signalservice.api.util.UuidUtil @@ -48,81 +47,84 @@ fun FilePointer?.toLocalAttachment( ): Attachment? { if (this == null || this.locatorInfo == null) return null - val hasMediaName = this.locatorInfo.mediaName.isNotEmpty() - val hasTransitInfo = this.locatorInfo.transitCdnKey != null + val attachmentType = when { + this.locatorInfo.plaintextHash != null -> AttachmentType.ARCHIVE + this.locatorInfo.encryptedDigest != null && this.locatorInfo.transitCdnKey != null -> AttachmentType.TRANSIT + else -> AttachmentType.INVALID + } - if (hasTransitInfo && !hasMediaName) { - val signalAttachmentPointer = SignalServiceAttachmentPointer( - cdnNumber = this.locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber, - remoteId = SignalServiceAttachmentRemoteId.from(locatorInfo.transitCdnKey), - contentType = contentType, - key = this.locatorInfo.key.toByteArray(), - size = Optional.ofNullable(locatorInfo.size), - preview = Optional.empty(), - width = this.width ?: 0, - height = this.height ?: 0, - digest = Optional.ofNullable(this.locatorInfo.digest.toByteArray()), - incrementalDigest = Optional.ofNullable(this.incrementalMac?.toByteArray()), - incrementalMacChunkSize = this.incrementalMacChunkSize ?: 0, - fileName = Optional.ofNullable(fileName), - voiceNote = voiceNote, - isBorderless = borderless, - isGif = gif, - caption = Optional.ofNullable(this.caption), - blurHash = Optional.ofNullable(this.blurHash), - uploadTimestamp = this.locatorInfo.transitTierUploadTimestamp?.clampToValidBackupRange() ?: 0, - uuid = UuidUtil.fromByteStringOrNull(uuid) - ) - return PointerAttachment.forPointer( - pointer = Optional.of(signalAttachmentPointer), - stickerLocator = stickerLocator, - transferState = if (wasDownloaded) AttachmentTable.TRANSFER_NEEDS_RESTORE else AttachmentTable.TRANSFER_PROGRESS_PENDING - ).orNull() - } else if (!hasMediaName) { - return TombstoneAttachment( - contentType = contentType, - incrementalMac = this.incrementalMac?.toByteArray(), - incrementalMacChunkSize = this.incrementalMacChunkSize, - width = this.width, - height = this.height, - caption = this.caption, - fileName = this.fileName, - blurHash = this.blurHash, - voiceNote = voiceNote, - borderless = borderless, - gif = gif, - quote = quote, - stickerLocator = stickerLocator, - uuid = UuidUtil.fromByteStringOrNull(uuid) - ) - } else { - return ArchivedAttachment( - contentType = contentType, - size = this.locatorInfo.size.toLong(), - cdn = this.locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber, - uploadTimestamp = this.locatorInfo.transitTierUploadTimestamp ?: 0, - key = this.locatorInfo.key.toByteArray(), - iv = null, - cdnKey = this.locatorInfo.transitCdnKey?.nullIfBlank(), - archiveCdn = this.locatorInfo.mediaTierCdnNumber, - archiveMediaName = this.locatorInfo.mediaName, - archiveMediaId = importState.mediaRootBackupKey.deriveMediaId(MediaName(this.locatorInfo.mediaName)).encode(), - archiveThumbnailMediaId = importState.mediaRootBackupKey.deriveMediaId(MediaName.forThumbnailFromMediaName(this.locatorInfo.mediaName)).encode(), - digest = this.locatorInfo.digest.toByteArray(), - incrementalMac = this.incrementalMac?.toByteArray(), - incrementalMacChunkSize = this.incrementalMacChunkSize, - width = this.width, - height = this.height, - caption = this.caption, - blurHash = this.blurHash, - voiceNote = voiceNote, - borderless = borderless, - gif = gif, - quote = quote, - stickerLocator = stickerLocator, - uuid = UuidUtil.fromByteStringOrNull(uuid), - fileName = fileName - ) + return when (attachmentType) { + AttachmentType.ARCHIVE -> { + ArchivedAttachment( + contentType = contentType, + size = this.locatorInfo.size.toLong(), + cdn = this.locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber, + uploadTimestamp = this.locatorInfo.transitTierUploadTimestamp ?: 0, + key = this.locatorInfo.key.toByteArray(), + cdnKey = this.locatorInfo.transitCdnKey?.nullIfBlank(), + archiveCdn = this.locatorInfo.mediaTierCdnNumber, + plaintextHash = this.locatorInfo.plaintextHash!!.toByteArray(), + incrementalMac = this.incrementalMac?.toByteArray(), + incrementalMacChunkSize = this.incrementalMacChunkSize, + width = this.width, + height = this.height, + caption = this.caption, + blurHash = this.blurHash, + voiceNote = voiceNote, + borderless = borderless, + stickerLocator = stickerLocator, + gif = gif, + quote = quote, + uuid = UuidUtil.fromByteStringOrNull(uuid), + fileName = fileName + ) + } + AttachmentType.TRANSIT -> { + val signalAttachmentPointer = SignalServiceAttachmentPointer( + cdnNumber = this.locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber, + remoteId = SignalServiceAttachmentRemoteId.from(locatorInfo.transitCdnKey!!), + contentType = contentType, + key = this.locatorInfo.key.toByteArray(), + size = Optional.ofNullable(locatorInfo.size), + preview = Optional.empty(), + width = this.width ?: 0, + height = this.height ?: 0, + digest = Optional.ofNullable(this.locatorInfo.encryptedDigest!!.toByteArray()), + incrementalDigest = Optional.ofNullable(this.incrementalMac?.toByteArray()), + incrementalMacChunkSize = this.incrementalMacChunkSize ?: 0, + fileName = Optional.ofNullable(fileName), + voiceNote = voiceNote, + isBorderless = borderless, + isGif = gif, + caption = Optional.ofNullable(this.caption), + blurHash = Optional.ofNullable(this.blurHash), + uploadTimestamp = this.locatorInfo.transitTierUploadTimestamp?.clampToValidBackupRange() ?: 0, + uuid = UuidUtil.fromByteStringOrNull(uuid) + ) + PointerAttachment.forPointer( + pointer = Optional.of(signalAttachmentPointer), + stickerLocator = stickerLocator, + transferState = if (wasDownloaded) AttachmentTable.TRANSFER_NEEDS_RESTORE else AttachmentTable.TRANSFER_PROGRESS_PENDING + ).orNull() + } + AttachmentType.INVALID -> { + TombstoneAttachment( + contentType = contentType, + incrementalMac = this.incrementalMac?.toByteArray(), + incrementalMacChunkSize = this.incrementalMacChunkSize, + width = this.width, + height = this.height, + caption = this.caption, + fileName = this.fileName, + blurHash = this.blurHash, + voiceNote = voiceNote, + borderless = borderless, + gif = gif, + quote = quote, + stickerLocator = stickerLocator, + uuid = UuidUtil.fromByteStringOrNull(uuid) + ) + } } } @@ -192,21 +194,17 @@ fun FilePointer.Builder.setLegacyLocators(attachment: DatabaseAttachment, mediaA } fun DatabaseAttachment.toLocatorInfo(): FilePointer.LocatorInfo { - if (this.remoteKey.isNullOrBlank() || this.remoteDigest == null || this.size == 0L) { - return FilePointer.LocatorInfo() - } + val attachmentType = this.toRemoteAttachmentType() - if (this.transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE && this.archiveTransferState != AttachmentTable.ArchiveTransferState.FINISHED) { + if (attachmentType == AttachmentType.INVALID) { return FilePointer.LocatorInfo() } val locatorBuilder = FilePointer.LocatorInfo.Builder() - val remoteKey = Base64.decode(this.remoteKey).toByteString() - val archiveMediaName = this.getMediaName()?.toString() + val remoteKey = Base64.decode(this.remoteKey!!).toByteString() locatorBuilder.key = remoteKey - locatorBuilder.digest = this.remoteDigest.toByteString() locatorBuilder.size = this.size.toInt() if (this.remoteLocation.isNotNullOrBlank()) { @@ -215,8 +213,17 @@ fun DatabaseAttachment.toLocatorInfo(): FilePointer.LocatorInfo { locatorBuilder.transitTierUploadTimestamp = this.uploadTimestamp.takeIf { it > 0 }?.clampToValidBackupRange() } - locatorBuilder.mediaTierCdnNumber = this.archiveCdn?.takeIf { archiveMediaName != null } - locatorBuilder.mediaName = archiveMediaName.emptyIfNull() + @Suppress("KotlinConstantConditions") + when (attachmentType) { + AttachmentType.ARCHIVE -> { + locatorBuilder.plaintextHash = Base64.decode(this.dataHash!!).toByteString() + locatorBuilder.mediaTierCdnNumber = this.archiveCdn + } + AttachmentType.TRANSIT -> { + locatorBuilder.encryptedDigest = this.remoteDigest!!.toByteString() + } + AttachmentType.INVALID -> Unit + } return locatorBuilder.build() } @@ -260,3 +267,30 @@ fun RemoteAvatarColor.toLocal(): AvatarColor { RemoteAvatarColor.A210 -> AvatarColor.A210 } } + +private fun DatabaseAttachment.toRemoteAttachmentType(): AttachmentType { + if (this.remoteKey.isNullOrBlank()) { + return AttachmentType.INVALID + } + + if (this.transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE && this.archiveTransferState != AttachmentTable.ArchiveTransferState.FINISHED) { + return AttachmentType.INVALID + } + + val activelyOnArchiveCdn = this.archiveTransferState == AttachmentTable.ArchiveTransferState.FINISHED + val couldBeOnArchiveCdn = this.transferState == AttachmentTable.TRANSFER_PROGRESS_DONE && this.archiveTransferState != AttachmentTable.ArchiveTransferState.PERMANENT_FAILURE + + if (this.dataHash != null && (activelyOnArchiveCdn || couldBeOnArchiveCdn)) { + return AttachmentType.ARCHIVE + } + + if (this.remoteDigest != null && this.remoteLocation.isNotNullOrBlank()) { + return AttachmentType.TRANSIT + } + + return AttachmentType.INVALID +} + +private enum class AttachmentType { + TRANSIT, ARCHIVE, INVALID +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt index 98cc123760..0f3d237e2c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/AttachmentTable.kt @@ -36,7 +36,6 @@ import org.signal.core.util.Base64 import org.signal.core.util.SqlUtil import org.signal.core.util.StreamUtil import org.signal.core.util.ThreadUtil -import org.signal.core.util.allMatch import org.signal.core.util.copyTo import org.signal.core.util.count import org.signal.core.util.delete @@ -61,7 +60,6 @@ import org.signal.core.util.requireNonNullString import org.signal.core.util.requireObject import org.signal.core.util.requireString import org.signal.core.util.select -import org.signal.core.util.stream.LimitedInputStream import org.signal.core.util.stream.NullOutputStream import org.signal.core.util.toInt import org.signal.core.util.update @@ -79,17 +77,6 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.COPY_PENDING -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.FINISHED -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.NONE -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.PERMANENT_FAILURE -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.UPLOAD_IN_PROGRESS -import org.thoughtcrime.securesms.database.AttachmentTable.ArchiveTransferState.entries -import org.thoughtcrime.securesms.database.AttachmentTable.Companion.DATA_FILE -import org.thoughtcrime.securesms.database.AttachmentTable.Companion.DATA_HASH_END -import org.thoughtcrime.securesms.database.AttachmentTable.Companion.PREUPLOAD_MESSAGE_ID -import org.thoughtcrime.securesms.database.AttachmentTable.Companion.TRANSFER_PROGRESS_DONE -import org.thoughtcrime.securesms.database.AttachmentTable.ThumbnailRestoreState.entries import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId import org.thoughtcrime.securesms.database.SignalDatabase.Companion.messages import org.thoughtcrime.securesms.database.SignalDatabase.Companion.threads @@ -144,7 +131,6 @@ class AttachmentTable( const val MESSAGE_ID = "message_id" const val CONTENT_TYPE = "content_type" const val REMOTE_KEY = "remote_key" - const val REMOTE_IV = "remote_iv" const val REMOTE_LOCATION = "remote_location" const val REMOTE_DIGEST = "remote_digest" const val REMOTE_INCREMENTAL_DIGEST = "remote_incremental_digest" @@ -203,7 +189,6 @@ class AttachmentTable( MESSAGE_ID, CONTENT_TYPE, REMOTE_KEY, - REMOTE_IV, REMOTE_LOCATION, REMOTE_DIGEST, REMOTE_INCREMENTAL_DIGEST, @@ -284,7 +269,6 @@ class AttachmentTable( $THUMBNAIL_RANDOM BLOB DEFAULT NULL, $THUMBNAIL_RESTORE_STATE INTEGER DEFAULT ${ThumbnailRestoreState.NONE.value}, $ATTACHMENT_UUID TEXT DEFAULT NULL, - $REMOTE_IV BLOB DEFAULT NULL, $OFFLOAD_RESTORED_AT INTEGER DEFAULT 0 ) """ @@ -297,7 +281,7 @@ class AttachmentTable( "CREATE INDEX IF NOT EXISTS attachment_transfer_state_index ON $TABLE_NAME ($TRANSFER_STATE);", "CREATE INDEX IF NOT EXISTS attachment_sticker_pack_id_index ON $TABLE_NAME ($STICKER_PACK_ID);", "CREATE INDEX IF NOT EXISTS attachment_data_hash_start_index ON $TABLE_NAME ($DATA_HASH_START);", - "CREATE INDEX IF NOT EXISTS attachment_data_hash_end_index ON $TABLE_NAME ($DATA_HASH_END);", + "CREATE INDEX IF NOT EXISTS attachment_data_hash_end_remote_key_index ON $TABLE_NAME ($DATA_HASH_END, $REMOTE_KEY);", "CREATE INDEX IF NOT EXISTS $DATA_FILE_INDEX ON $TABLE_NAME ($DATA_FILE);", "CREATE INDEX IF NOT EXISTS attachment_archive_transfer_state ON $TABLE_NAME ($ARCHIVE_TRANSFER_STATE);", "CREATE INDEX IF NOT EXISTS attachment_remote_digest_index ON $TABLE_NAME ($REMOTE_DIGEST);" @@ -511,7 +495,7 @@ class AttachmentTable( return readableDatabase .select(*PROJECTION) .from(TABLE_NAME) - .where("$REMOTE_KEY IS NOT NULL AND $REMOTE_DIGEST IS NOT NULL AND $REMOTE_IV IS NOT NULL AND $DATA_FILE IS NOT NULL") + .where("$REMOTE_KEY IS NOT NULL AND $DATA_HASH_END IS NOT NULL AND $DATA_FILE IS NOT NULL") .orderBy("$ID DESC") .run() .readToList { @@ -519,16 +503,15 @@ class AttachmentTable( file = File(it.requireNonNullString(DATA_FILE)), random = it.requireNonNullBlob(DATA_RANDOM), size = it.requireLong(DATA_SIZE), - remoteDigest = it.requireBlob(REMOTE_DIGEST)!!, remoteKey = it.requireBlob(REMOTE_KEY)!!, - remoteIv = it.requireBlob(REMOTE_IV)!! + plaintextHash = Base64.decode(it.requireNonNullString(DATA_HASH_END)) ) } } fun getRestorableAttachments(batchSize: Int): List { return readableDatabase - .select(ID, MESSAGE_ID, DATA_SIZE, REMOTE_DIGEST, REMOTE_KEY) + .select(ID, MESSAGE_ID, DATA_SIZE, DATA_HASH_END, REMOTE_KEY) .from(TABLE_NAME) .where("$TRANSFER_STATE = ?", TRANSFER_NEEDS_RESTORE) .limit(batchSize) @@ -539,7 +522,7 @@ class AttachmentTable( attachmentId = AttachmentId(it.requireLong(ID)), mmsId = it.requireLong(MESSAGE_ID), size = it.requireLong(DATA_SIZE), - remoteDigest = it.requireBlob(REMOTE_DIGEST), + plaintextHash = it.requireBlob(DATA_HASH_END), remoteKey = it.requireBlob(REMOTE_KEY) ) } @@ -549,7 +532,7 @@ class AttachmentTable( return readableDatabase .select(ID, MESSAGE_ID, DATA_SIZE, REMOTE_DIGEST, REMOTE_KEY) .from(TABLE_NAME) - .where("$TRANSFER_STATE = ?", TRANSFER_RESTORE_OFFLOADED) + .where("$TRANSFER_STATE = ? AND $DATA_HASH_END NOT NULL AND $REMOTE_KEY NOT NULL", TRANSFER_RESTORE_OFFLOADED) .orderBy("$ID DESC") .run() .readToList { @@ -557,8 +540,8 @@ class AttachmentTable( attachmentId = AttachmentId(it.requireLong(ID)), mmsId = it.requireLong(MESSAGE_ID), size = it.requireLong(DATA_SIZE), - remoteDigest = it.requireBlob(REMOTE_DIGEST), - remoteKey = it.requireBlob(REMOTE_KEY) + plaintextHash = it.requireNonNullBlob(DATA_HASH_END), + remoteKey = it.requireNonNullBlob(REMOTE_KEY) ) } } @@ -595,49 +578,31 @@ class AttachmentTable( } /** - * At archive creation time, we need to ensure that all relevant attachments have populated (key, iv, digest) tuples. + * At archive creation time, we need to ensure that all relevant attachments have populated [REMOTE_KEY]s. * This does that. */ - fun createKeyIvDigestForAttachmentsThatNeedArchiveUpload(): Int { + fun createRemoteKeyForAttachmentsThatNeedArchiveUpload(): Int { var count = 0 - writableDatabase.select(ID, REMOTE_KEY, REMOTE_IV, REMOTE_DIGEST, DATA_FILE, DATA_RANDOM) + writableDatabase.select(ID, REMOTE_KEY, DATA_FILE, DATA_RANDOM) .from(TABLE_NAME) .where( """ $ARCHIVE_TRANSFER_STATE = ${ArchiveTransferState.NONE.value} AND $DATA_FILE NOT NULL AND $TRANSFER_STATE = $TRANSFER_PROGRESS_DONE AND - ( - $REMOTE_KEY IS NULL OR - $REMOTE_IV IS NULL OR - $REMOTE_DIGEST IS NULL - ) + $REMOTE_KEY IS NULL """ ) .run() .forEach { cursor -> val attachmentId = AttachmentId(cursor.requireLong(ID)) - Log.w(TAG, "[createKeyIvDigestForAttachmentsThatNeedArchiveUpload][$attachmentId] Missing key, iv, or digest. Generating.") + Log.w(TAG, "[createRemoteKeyForAttachmentsThatNeedArchiveUpload][$attachmentId] Missing key. Generating.") val key = cursor.requireString(REMOTE_KEY)?.let { Base64.decode(it) } ?: Util.getSecretBytes(64) - val iv = cursor.requireBlob(REMOTE_IV) ?: Util.getSecretBytes(16) - val digest = run { - val fileInfo = getDataFileInfo(attachmentId)!! - try { - calculateDigest(fileInfo, key, iv) - } catch (e: FileNotFoundException) { - Log.w(TAG, "[createKeyIvDigestForAttachmentsThatNeedArchiveUpload][$attachmentId] Could not find file ${fileInfo.file}. Delete all later?") - return@forEach - } - } writableDatabase.update(TABLE_NAME) - .values( - REMOTE_KEY to Base64.encodeWithPadding(key), - REMOTE_IV to iv, - REMOTE_DIGEST to digest - ) + .values(REMOTE_KEY to Base64.encodeWithPadding(key)) .where("$ID = ?", attachmentId.id) .run() @@ -717,14 +682,14 @@ class AttachmentTable( /** * Sets the archive transfer state for the given attachment by digest. */ - fun resetArchiveTransferStateByDigest(digest: ByteArray) { + fun resetArchiveTransferStateByPlaintextHashAndRemoteKey(plaintextHash: ByteArray, remoteKey: ByteArray) { writableDatabase .update(TABLE_NAME) .values( ARCHIVE_TRANSFER_STATE to ArchiveTransferState.NONE.value, ARCHIVE_CDN to null ) - .where("$REMOTE_DIGEST = ?", digest) + .where("$DATA_HASH_END = ? AND $REMOTE_KEY = ?", plaintextHash, remoteKey) .run() } @@ -1188,11 +1153,9 @@ class AttachmentTable( * When we find out about a new inbound attachment pointer, we insert a row for it that contains all the info we need to download it via [insertAttachmentWithData]. * Later, we download the data for that pointer. Call this method once you have the data to associate it with the attachment. At this point, it is assumed * that the content of the attachment will never change. - * - * @return True if we had to change the digest as part of saving the file, otherwise false. */ @Throws(MmsException::class) - fun finalizeAttachmentAfterDownload(mmsId: Long, attachmentId: AttachmentId, inputStream: LimitedInputStream, iv: ByteArray, offloadRestoredAt: Duration? = null): Boolean { + fun finalizeAttachmentAfterDownload(mmsId: Long, attachmentId: AttachmentId, inputStream: InputStream, offloadRestoredAt: Duration? = null) { Log.i(TAG, "[finalizeAttachmentAfterDownload] Finalizing downloaded data for $attachmentId. (MessageId: $mmsId, $attachmentId)") val existingPlaceholder: DatabaseAttachment = getAttachment(attachmentId) ?: throw MmsException("No attachment found for id: $attachmentId") @@ -1200,23 +1163,6 @@ class AttachmentTable( val fileWriteResult: DataFileWriteResult = writeToDataFile(newDataFile(context), inputStream, TransformProperties.empty(), closeInputStream = false) val transferFile: File? = getTransferFile(databaseHelper.signalReadableDatabase, attachmentId) - val paddingAllZeroes = inputStream.use { limitStream -> - limitStream.leftoverStream().allMatch { it == 0x00.toByte() } - } - - // Existing digest may be null for non-user attachments, like things pulled from S3 - val digest = if (existingPlaceholder.remoteDigest != null && paddingAllZeroes) { - Log.d(TAG, "[finalizeAttachmentAfterDownload] $attachmentId has all-zero padding. Digest is good.") - existingPlaceholder.remoteDigest - } else { - Log.w(TAG, "[finalizeAttachmentAfterDownload] $attachmentId has non-zero padding bytes. Recomputing digest.") - - val key = Base64.decode(existingPlaceholder.remoteKey!!) - calculateDigest(fileWriteResult, key, iv) - } - - val digestChanged = !digest.contentEquals(existingPlaceholder.remoteDigest) - val foundDuplicate = writableDatabase.withinTransaction { db -> // We can look and see if we have any exact matches on hash_ends and dedupe the file if we see one. // We don't look at hash_start here because that could result in us matching on a file that got compressed down to something smaller, effectively lowering @@ -1263,15 +1209,10 @@ class AttachmentTable( values.put(REMOTE_LOCATION, existingPlaceholder.remoteLocation) values.put(CDN_NUMBER, existingPlaceholder.cdn.serialize()) values.put(REMOTE_KEY, existingPlaceholder.remoteKey!!) - values.put(REMOTE_IV, iv) - values.put(REMOTE_DIGEST, digest) + values.put(REMOTE_DIGEST, existingPlaceholder.remoteDigest) values.put(REMOTE_INCREMENTAL_DIGEST, existingPlaceholder.incrementalDigest) values.put(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE, existingPlaceholder.incrementalMacChunkSize) - if (digestChanged) { - values.put(UPLOAD_TIMESTAMP, 0) - } - if (offloadRestoredAt != null) { values.put(OFFLOAD_RESTORED_AT, offloadRestoredAt.inWholeMilliseconds) } @@ -1313,8 +1254,6 @@ class AttachmentTable( if (MediaUtil.isAudio(existingPlaceholder)) { GenerateAudioWaveFormJob.enqueue(existingPlaceholder.attachmentId) } - - return digestChanged } @Throws(IOException::class) @@ -1390,7 +1329,6 @@ class AttachmentTable( CDN_NUMBER to uploadResult.cdnNumber, REMOTE_LOCATION to uploadResult.remoteId.toString(), REMOTE_KEY to Base64.encodeWithPadding(uploadResult.key), - REMOTE_IV to uploadResult.iv, REMOTE_DIGEST to uploadResult.digest, REMOTE_INCREMENTAL_DIGEST to uploadResult.incrementalDigest, REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE to uploadResult.incrementalDigestChunkSize, @@ -1500,9 +1438,8 @@ class AttachmentTable( } } - fun createKeyIvIfNecessary(attachmentId: AttachmentId) { + fun createRemoteKeyIfNecessary(attachmentId: AttachmentId) { val key = Util.getSecretBytes(64) - val iv = Util.getSecretBytes(16) writableDatabase.withinTransaction { writableDatabase @@ -1510,12 +1447,6 @@ class AttachmentTable( .values(REMOTE_KEY to Base64.encodeWithPadding(key)) .where("$ID = ? AND $REMOTE_KEY IS NULL", attachmentId.id) .run() - - writableDatabase - .update(TABLE_NAME) - .values(REMOTE_IV to iv) - .where("$ID = ? AND $REMOTE_IV IS NULL", attachmentId.id) - .run() } } @@ -1562,30 +1493,14 @@ class AttachmentTable( .readToList { it.requireNonNullString(DATA_FILE) } } - /** - * As part of the digest backfill process, this updates the (key, IV, digest) tuple for an attachment. - */ - fun updateKeyIvDigest(attachmentId: AttachmentId, key: ByteArray, iv: ByteArray, digest: ByteArray) { - writableDatabase - .update(TABLE_NAME) - .values( - REMOTE_KEY to Base64.encodeWithPadding(key), - REMOTE_IV to iv, - REMOTE_DIGEST to digest - ) - .where("$ID = ?", attachmentId.id) - .run() - } - /** * As part of the digest backfill process, this updates the (key, IV, digest) tuple for all attachments that share a data file (and are done downloading). */ - fun updateKeyIvDigestByDataFile(dataFile: String, key: ByteArray, iv: ByteArray, digest: ByteArray) { + fun updateRemoteKeyAndDigestByDataFile(dataFile: String, key: ByteArray, digest: ByteArray) { writableDatabase .update(TABLE_NAME) .values( REMOTE_KEY to Base64.encodeWithPadding(key), - REMOTE_IV to iv, REMOTE_DIGEST to digest ) .where("$DATA_FILE = ? AND $TRANSFER_STATE = $TRANSFER_PROGRESS_DONE", dataFile) @@ -1907,37 +1822,6 @@ class AttachmentTable( notifyConversationListeners(threadId) } - /** - * This will ensure that a (key/iv/digest) tuple exists for an attachment, filling each one if necessary. - */ - @Throws(IOException::class) - fun createKeyIvDigestIfNecessary(attachment: DatabaseAttachment) { - if (attachment.remoteKey != null && attachment.remoteIv != null && attachment.remoteDigest != null) { - return - } - - val attachmentId = attachment.attachmentId - - Log.w(TAG, "[createKeyIvDigestIfNecessary][$attachmentId] Missing one of (key, iv, digest). Filling in the gaps.") - - val key = attachment.remoteKey?.let { Base64.decode(it) } ?: Util.getSecretBytes(64) - val iv = attachment.remoteIv ?: Util.getSecretBytes(16) - val digest: ByteArray = run { - val fileInfo = getDataFileInfo(attachmentId) ?: throw IOException("No data file found for $attachmentId!") - calculateDigest(fileInfo, key, iv) - } - - writableDatabase - .update(TABLE_NAME) - .values( - REMOTE_KEY to Base64.encodeWithPadding(key), - REMOTE_IV to iv, - REMOTE_DIGEST to digest - ) - .where("$ID = ?", attachmentId.id) - .run() - } - fun getAttachments(cursor: Cursor): List { return try { if (cursor.getColumnIndex(ATTACHMENT_JSON_ALIAS) != -1) { @@ -1966,7 +1850,6 @@ class AttachmentTable( cdn = Cdn.deserialize(jsonObject.getInt(CDN_NUMBER)), location = jsonObject.getString(REMOTE_LOCATION), key = jsonObject.getString(REMOTE_KEY), - iv = null, digest = null, incrementalDigest = null, incrementalMacChunkSize = 0, @@ -2067,11 +1950,11 @@ class AttachmentTable( /** * Updates all attachments that share the same digest with the given archive CDN. */ - fun setArchiveCdnByDigest(digest: ByteArray, archiveCdn: Int) { + fun setArchiveCdnByPlaintextHashAndRemoteKey(plaintextHash: ByteArray, remoteKey: ByteArray, archiveCdn: Int) { writableDatabase .update(TABLE_NAME) .values(ARCHIVE_CDN to archiveCdn) - .where("$REMOTE_DIGEST = ?", digest) + .where("$DATA_HASH_END= ? AND $REMOTE_KEY = ?", plaintextHash, remoteKey) .run() } @@ -2098,11 +1981,7 @@ class AttachmentTable( .run() } - private fun calculateDigest(fileInfo: DataFileWriteResult, key: ByteArray, iv: ByteArray): ByteArray { - return calculateDigest(file = fileInfo.file, random = fileInfo.random, length = fileInfo.length, key = key, iv = iv) - } - - private fun calculateDigest(fileInfo: DataFileInfo, key: ByteArray, iv: ByteArray): ByteArray { + private fun calculateDigest(fileInfo: DataFileWriteResult, key: ByteArray, iv: ByteArray = Util.getSecretBytes(16)): ByteArray { return calculateDigest(file = fileInfo.file, random = fileInfo.random, length = fileInfo.length, key = key, iv = iv) } @@ -2364,6 +2243,8 @@ class AttachmentTable( Log.d(TAG, "[insertAttachment] Inserting attachment for messageId $messageId.") val attachmentId: AttachmentId = writableDatabase.withinTransaction { db -> + val plaintextHash = attachment.plaintextHash.takeIf { it.isNotEmpty() }?.let { Base64.encodeWithPadding(it) } + val contentValues = ContentValues().apply { put(MESSAGE_ID, messageId) put(CONTENT_TYPE, attachment.contentType) @@ -2389,6 +2270,11 @@ class AttachmentTable( put(ATTACHMENT_UUID, attachment.uuid?.toString()) put(BLUR_HASH, attachment.blurHash?.hash) + if (plaintextHash != null) { + put(DATA_HASH_START, plaintextHash) + put(DATA_HASH_END, plaintextHash) + } + attachment.stickerLocator?.let { sticker -> put(STICKER_PACK_ID, sticker.packId) put(STICKER_PACK_KEY, sticker.packKey) @@ -2525,7 +2411,6 @@ class AttachmentTable( contentValues.put(REMOTE_LOCATION, uploadTemplate?.remoteLocation) contentValues.put(REMOTE_DIGEST, uploadTemplate?.remoteDigest) contentValues.put(REMOTE_KEY, uploadTemplate?.remoteKey) - contentValues.put(REMOTE_IV, uploadTemplate?.remoteIv) contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.fileName)) contentValues.put(FAST_PREFLIGHT_ID, attachment.fastPreflightId) contentValues.put(VOICE_NOTE, if (attachment.voiceNote) 1 else 0) @@ -2576,7 +2461,7 @@ class AttachmentTable( fun insertWallpaper(dataStream: InputStream): AttachmentId { return insertAttachmentWithData(WALLPAPER_MESSAGE_ID, dataStream, WallpaperAttachment(), quote = false).also { id -> - createKeyIvIfNecessary(id) + createRemoteKeyIfNecessary(id) } } @@ -2673,7 +2558,6 @@ class AttachmentTable( cdn = cursor.requireObject(CDN_NUMBER, Cdn.Serializer), location = cursor.requireString(REMOTE_LOCATION), key = cursor.requireString(REMOTE_KEY), - iv = cursor.requireBlob(REMOTE_IV), digest = cursor.requireBlob(REMOTE_DIGEST), incrementalDigest = cursor.requireBlob(REMOTE_INCREMENTAL_DIGEST), incrementalMacChunkSize = cursor.requireInt(REMOTE_INCREMENTAL_DIGEST_CHUNK_SIZE), @@ -3043,16 +2927,15 @@ class AttachmentTable( val file: File, val random: ByteArray, val size: Long, - val remoteDigest: ByteArray, - val remoteKey: ByteArray, - val remoteIv: ByteArray + val plaintextHash: ByteArray, + val remoteKey: ByteArray ) class RestorableAttachment( val attachmentId: AttachmentId, val mmsId: Long, val size: Long, - val remoteDigest: ByteArray?, + val plaintextHash: ByteArray?, val remoteKey: ByteArray? ) { override fun equals(other: Any?): Boolean { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTable.kt index 747f3b7fe9..398e26e057 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/BackupMediaSnapshotTable.kt @@ -91,9 +91,14 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat const val LAST_SEEN_ON_REMOTE_SNAPSHOT_VERSION = "last_seen_on_remote_snapshot_version" /** - * The remote digest for the media object. This is used to find matching attachments in the attachment table when necessary. + * The plaintext hash of the media object. This is used to find matching attachments in the attachment table when necessary. */ - const val REMOTE_DIGEST = "remote_digest" + const val PLAINTEXT_HASH = "plaintext_hash" + + /** + * The remote that was used for encrypting for the media object. This is used to find matching attachments in the attachment table when necessary. + */ + const val REMOTE_KEY = "remote_key" /** Constant representing a [SNAPSHOT_VERSION] version that has not yet been set. */ const val UNKNOWN_VERSION = -1 @@ -111,7 +116,8 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat $SNAPSHOT_VERSION INTEGER NOT NULL DEFAULT $UNKNOWN_VERSION, $IS_PENDING INTEGER NOT NULL DEFAULT 0, $IS_THUMBNAIL INTEGER NOT NULL DEFAULT 0, - $REMOTE_DIGEST BLOB NOT NULL, + $PLAINTEXT_HASH BLOB NOT NULL, + $REMOTE_KEY BLOB NOT NULL, $LAST_SEEN_ON_REMOTE_SNAPSHOT_VERSION INTEGER NOT NULL DEFAULT 0 ) """.trimIndent() @@ -130,11 +136,11 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat .chunked(SqlUtil.MAX_QUERY_ARGS) .forEach { chunk -> writePendingMediaObjectsChunk( - chunk.map { MediaEntry(it.mediaId, it.cdn, it.digest, isThumbnail = false) } + chunk.map { MediaEntry(it.mediaId, it.cdn, it.plaintextHash, it.remoteKey, isThumbnail = false) } ) writePendingMediaObjectsChunk( - chunk.map { MediaEntry(it.thumbnailMediaId, it.cdn, it.digest, isThumbnail = true) } + chunk.map { MediaEntry(it.thumbnailMediaId, it.cdn, it.plaintextHash, it.remoteKey, isThumbnail = true) } ) } } @@ -238,14 +244,15 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat return readableDatabase.rawQuery( """ WITH input_pairs($MEDIA_ID, $CDN) AS (VALUES $inputValues) - SELECT a.$REMOTE_DIGEST, b.$CDN + SELECT a.$PLAINTEXT_HASH, a.$REMOTE_KEY b.$CDN FROM $TABLE_NAME a JOIN input_pairs b ON a.$MEDIA_ID = b.$MEDIA_ID WHERE a.$CDN != b.$CDN AND a.$IS_THUMBNAIL = 0 AND $SNAPSHOT_VERSION = $MAX_VERSION """ ).readToList { cursor -> CdnMismatchResult( - digest = cursor.requireNonNullBlob(REMOTE_DIGEST), + plaintextHash = cursor.requireNonNullBlob(PLAINTEXT_HASH), + remoteKey = cursor.requireNonNullBlob(REMOTE_KEY), cdn = cursor.requireInt(CDN) ) } @@ -277,7 +284,7 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat */ fun getMediaObjectsLastSeenOnCdnBeforeSnapshotVersion(snapshotVersion: Long): Cursor { return readableDatabase - .select(MEDIA_ID, CDN, REMOTE_DIGEST, IS_THUMBNAIL) + .select(MEDIA_ID, CDN, PLAINTEXT_HASH, REMOTE_KEY, IS_THUMBNAIL) .from(TABLE_NAME) .where("$LAST_SEEN_ON_REMOTE_SNAPSHOT_VERSION < $snapshotVersion AND $SNAPSHOT_VERSION = $snapshotVersion") .run() @@ -288,21 +295,23 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat contentValuesOf( MEDIA_ID to it.mediaId, CDN to it.cdn, - REMOTE_DIGEST to it.digest, + PLAINTEXT_HASH to it.plaintextHash, + REMOTE_KEY to it.remoteKey, IS_THUMBNAIL to it.isThumbnail.toInt(), SNAPSHOT_VERSION to UNKNOWN_VERSION, IS_PENDING to 1 ) } - val query = SqlUtil.buildSingleBulkInsert(TABLE_NAME, arrayOf(MEDIA_ID, CDN, REMOTE_DIGEST, IS_THUMBNAIL, SNAPSHOT_VERSION, IS_PENDING), values) + val query = SqlUtil.buildSingleBulkInsert(TABLE_NAME, arrayOf(MEDIA_ID, CDN, PLAINTEXT_HASH, REMOTE_KEY, IS_THUMBNAIL, SNAPSHOT_VERSION, IS_PENDING), values) writableDatabase.execSQL( query.where + """ ON CONFLICT($MEDIA_ID) DO UPDATE SET $CDN = excluded.$CDN, - $REMOTE_DIGEST = excluded.$REMOTE_DIGEST, + $PLAINTEXT_HASH = excluded.$PLAINTEXT_HASH, + $REMOTE_KEY = excluded.$REMOTE_KEY, $IS_THUMBNAIL = excluded.$IS_THUMBNAIL, $IS_PENDING = excluded.$IS_PENDING """, @@ -314,18 +323,21 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat val mediaId: String, val thumbnailMediaId: String, val cdn: Int?, - val digest: ByteArray + val plaintextHash: ByteArray, + val remoteKey: ByteArray ) class CdnMismatchResult( - val digest: ByteArray, + val plaintextHash: ByteArray, + val remoteKey: ByteArray, val cdn: Int ) class MediaEntry( val mediaId: String, val cdn: Int?, - val digest: ByteArray, + val plaintextHash: ByteArray, + val remoteKey: ByteArray, val isThumbnail: Boolean ) { companion object { @@ -333,7 +345,8 @@ class BackupMediaSnapshotTable(context: Context, database: SignalDatabase) : Dat return MediaEntry( mediaId = cursor.requireNonNullString(MEDIA_ID), cdn = cursor.requireIntOrNull(CDN), - digest = cursor.requireNonNullBlob(REMOTE_DIGEST), + plaintextHash = cursor.requireNonNullBlob(PLAINTEXT_HASH), + remoteKey = cursor.requireNonNullBlob(REMOTE_KEY), isThumbnail = cursor.requireBoolean(IS_THUMBNAIL) ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt index a1351ee03d..448852b524 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MediaTable.kt @@ -31,7 +31,6 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD ${AttachmentTable.TABLE_NAME}.${AttachmentTable.CDN_NUMBER}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_LOCATION}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_KEY}, - ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_IV}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.REMOTE_DIGEST}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.FAST_PREFLIGHT_ID}, ${AttachmentTable.TABLE_NAME}.${AttachmentTable.VOICE_NOTE}, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index 3e60dc5019..8e217c13a8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -134,6 +134,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V276_AttachmentCdnD import org.thoughtcrime.securesms.database.helpers.migration.V277_AddNotificationProfileStorageSync import org.thoughtcrime.securesms.database.helpers.migration.V278_BackupSnapshotTableVersions import org.thoughtcrime.securesms.database.helpers.migration.V279_AddNotificationProfileForeignKey +import org.thoughtcrime.securesms.database.helpers.migration.V280_RemoveAttachmentIv import org.thoughtcrime.securesms.database.SQLiteDatabase as SignalSqliteDatabase /** @@ -273,10 +274,11 @@ object SignalDatabaseMigrations { 276 to V276_AttachmentCdnDefaultValueMigration, 277 to V277_AddNotificationProfileStorageSync, 278 to V278_BackupSnapshotTableVersions, - 279 to V279_AddNotificationProfileForeignKey + 279 to V279_AddNotificationProfileForeignKey, + 280 to V280_RemoveAttachmentIv ) - const val DATABASE_VERSION = 279 + const val DATABASE_VERSION = 280 @JvmStatic fun migrate(context: Application, db: SignalSqliteDatabase, oldVersion: Int, newVersion: Int) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V280_RemoveAttachmentIv.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V280_RemoveAttachmentIv.kt new file mode 100644 index 0000000000..aa5a433ab5 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V280_RemoveAttachmentIv.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2025 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.database.helpers.migration + +import android.app.Application +import org.thoughtcrime.securesms.database.SQLiteDatabase + +/** + * We've changed our mediaName calculation to be based on plaintextHash + remoteKey instead of remoteDigest. That means we no longer need to store the IV + * in the database, because the only reason we were storing it before was to have a consistent remoteDigest calculation. + * + * Also, because we're changing the mediaName calculation, we need to reset all of the archive status's. + */ +object V280_RemoveAttachmentIv : SignalDatabaseMigration { + override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + db.execSQL("ALTER TABLE attachment DROP COLUMN remote_iv") + db.execSQL("DROP INDEX attachment_data_hash_end_index") + db.execSQL("CREATE INDEX IF NOT EXISTS attachment_data_hash_end_remote_key_index ON attachment (data_hash_end, remote_key)") + + // Rebuild table to allow us to have new non-null columns + db.execSQL("DROP TABLE backup_media_snapshot") + db.execSQL( + """ + CREATE TABLE backup_media_snapshot ( + _id INTEGER PRIMARY KEY, + media_id TEXT NOT NULL UNIQUE, + cdn INTEGER, + snapshot_version INTEGER NOT NULL DEFAULT -1, + is_pending INTEGER NOT NULL DEFAULT 0, + is_thumbnail INTEGER NOT NULL DEFAULT 0, + plaintext_hash BLOB NOT NULL, + remote_key BLOB NOT NULL, + last_seen_on_remote_snapshot_version INTEGER NOT NULL DEFAULT 0 + ) + """ + ) + db.execSQL("CREATE INDEX IF NOT EXISTS backup_snapshot_version_index ON backup_media_snapshot (snapshot_version DESC) WHERE snapshot_version != -1") + + // Reset archive transfer state + db.execSQL("UPDATE attachment SET archive_transfer_state = 0 WHERE archive_transfer_state != 0") + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentBackfillJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentBackfillJob.kt index 3d89fd3187..047e478562 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentBackfillJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentBackfillJob.kt @@ -45,7 +45,7 @@ class ArchiveAttachmentBackfillJob private constructor(parameters: Parameters) : val jobs = SignalDatabase.attachments.getAttachmentsThatNeedArchiveUpload() .map { attachmentId -> UploadAttachmentToArchiveJob(attachmentId) } - SignalDatabase.attachments.createKeyIvDigestForAttachmentsThatNeedArchiveUpload() + SignalDatabase.attachments.createRemoteKeyForAttachmentsThatNeedArchiveUpload() ArchiveUploadProgress.onAttachmentsStarted(SignalDatabase.attachments.getPendingArchiveUploadBytes()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentReconciliationJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentReconciliationJob.kt index dbc8a9cc16..8470a53ca3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentReconciliationJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveAttachmentReconciliationJob.kt @@ -127,7 +127,7 @@ class ArchiveAttachmentReconciliationJob private constructor( val entry = BackupMediaSnapshotTable.MediaEntry.fromCursor(it) // TODO [backup] Re-enqueue thumbnail uploads if necessary if (!entry.isThumbnail) { - SignalDatabase.attachments.resetArchiveTransferStateByDigest(entry.digest) + SignalDatabase.attachments.resetArchiveTransferStateByPlaintextHashAndRemoteKey(entry.plaintextHash, entry.remoteKey) } } @@ -170,7 +170,7 @@ class ArchiveAttachmentReconciliationJob private constructor( if (cdnMismatches.isNotEmpty()) { Log.w(TAG, "Found ${cdnMismatches.size} items with CDNs that differ from what we have locally. Updating our local store.") for (mismatch in cdnMismatches) { - SignalDatabase.attachments.setArchiveCdnByDigest(mismatch.digest, mismatch.cdn) + SignalDatabase.attachments.setArchiveCdnByPlaintextHashAndRemoteKey(mismatch.plaintextHash, mismatch.remoteKey, mismatch.cdn) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt index feff3df35f..2aadf03c9d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ArchiveThumbnailUploadJob.kt @@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.util.ImageCompressionUtil import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.RemoteConfig +import org.thoughtcrime.securesms.util.Util import org.whispersystems.signalservice.api.NetworkResult import org.whispersystems.signalservice.api.messages.SignalServiceAttachment import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream @@ -105,7 +106,7 @@ class ArchiveThumbnailUploadJob private constructor( .then { form -> SignalNetwork.attachments.getResumableUploadSpec( key = mediaRootBackupKey.deriveThumbnailTransitKey(attachment.requireThumbnailMediaName()), - iv = attachment.remoteIv!!, + iv = Util.getSecretBytes(16), uploadForm = form ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt index daccdf257e..de4a84a565 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt @@ -11,7 +11,6 @@ import org.greenrobot.eventbus.EventBus import org.signal.core.util.Base64 import org.signal.core.util.Hex import org.signal.core.util.logging.Log -import org.signal.core.util.stream.LimitedInputStream import org.signal.libsignal.protocol.InvalidMacException import org.signal.libsignal.protocol.InvalidMessageException import org.thoughtcrime.securesms.attachments.Attachment @@ -214,15 +213,9 @@ class AttachmentDownloadJob private constructor( Log.i(TAG, "Downloading push part $attachmentId") SignalDatabase.attachments.setTransferState(messageId, attachmentId, AttachmentTable.TRANSFER_PROGRESS_STARTED) - val digestChanged = when (attachment.cdn) { - Cdn.S3 -> { - retrieveAttachmentForReleaseChannel(messageId, attachmentId, attachment) - false - } - - else -> { - retrieveAttachment(messageId, attachmentId, attachment) - } + when (attachment.cdn) { + Cdn.S3 -> retrieveAttachmentForReleaseChannel(messageId, attachmentId, attachment) + else -> retrieveAttachment(messageId, attachmentId, attachment) } if (SignalStore.backup.backsUpMedia) { @@ -231,11 +224,6 @@ class AttachmentDownloadJob private constructor( Log.i(TAG, "[$attachmentId] Already archived. Skipping.") } - digestChanged -> { - Log.i(TAG, "[$attachmentId] Digest for attachment changed after download. Re-uploading to archive.") - AppDependencies.jobManager.add(UploadAttachmentToArchiveJob(attachmentId)) - } - attachment.cdn !in CopyAttachmentToArchiveJob.ALLOWED_SOURCE_CDNS -> { Log.i(TAG, "[$attachmentId] Attachment CDN doesn't support copying to archive. Re-uploading to archive.") AppDependencies.jobManager.add(UploadAttachmentToArchiveJob(attachmentId)) @@ -268,7 +256,7 @@ class AttachmentDownloadJob private constructor( messageId: Long, attachmentId: AttachmentId, attachment: DatabaseAttachment - ): Boolean { + ) { val maxReceiveSize: Long = RemoteConfig.maxAttachmentReceiveSizeBytes val attachmentFile: File = SignalDatabase.attachments.getOrCreateTransferFile(attachmentId) @@ -289,7 +277,7 @@ class AttachmentDownloadJob private constructor( } } - val downloadResult = AppDependencies + val decryptingStream = AppDependencies .signalServiceMessageReceiver .retrieveAttachment( pointer, @@ -298,7 +286,7 @@ class AttachmentDownloadJob private constructor( progressListener ) - return SignalDatabase.attachments.finalizeAttachmentAfterDownload(messageId, attachmentId, downloadResult.dataStream, downloadResult.iv) + SignalDatabase.attachments.finalizeAttachmentAfterDownload(messageId, attachmentId, decryptingStream) } catch (e: RangeException) { Log.w(TAG, "Range exception, file size " + attachmentFile.length(), e) if (attachmentFile.delete()) { @@ -314,7 +302,7 @@ class AttachmentDownloadJob private constructor( if (SignalStore.backup.backsUpMedia && e.code == 404 && attachment.archiveTransferState === AttachmentTable.ArchiveTransferState.FINISHED) { Log.i(TAG, "Retrying download from archive CDN") RestoreAttachmentJob.restoreAttachment(attachment) - return false + return } Log.w(TAG, "Experienced exception while trying to download an attachment.", e) @@ -334,8 +322,6 @@ class AttachmentDownloadJob private constructor( markFailed(messageId, attachmentId) } } - - return false } @Throws(InvalidAttachmentException::class) @@ -399,21 +385,17 @@ class AttachmentDownloadJob private constructor( try { S3.getObject(attachment.fileName!!).use { response -> val body = response.body - if (body != null) { - if (body.contentLength() > RemoteConfig.maxAttachmentReceiveSizeBytes) { - throw MmsException("Attachment too large, failing download") - } - - SignalDatabase.attachments.createKeyIvIfNecessary(attachmentId) - val updatedAttachment = SignalDatabase.attachments.getAttachment(attachmentId)!! - - SignalDatabase.attachments.finalizeAttachmentAfterDownload( - messageId, - attachmentId, - LimitedInputStream.withoutLimits((body.source() as Source).buffer().inputStream()), - iv = updatedAttachment.remoteIv!! - ) + if (body.contentLength() > RemoteConfig.maxAttachmentReceiveSizeBytes) { + throw MmsException("Attachment too large, failing download") } + + SignalDatabase.attachments.createRemoteKeyIfNecessary(attachmentId) + + SignalDatabase.attachments.finalizeAttachmentAfterDownload( + messageId, + attachmentId, + (body.source() as Source).buffer().inputStream() + ) } } catch (e: MmsException) { Log.w(TAG, "Experienced exception while trying to download an attachment.", e) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt index 219c2a884d..d477f89d5c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.kt @@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.service.AttachmentProgressService import org.thoughtcrime.securesms.util.RemoteConfig +import org.thoughtcrime.securesms.util.Util import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress @@ -131,7 +132,7 @@ class AttachmentUploadJob private constructor( throw NotPushRegisteredException() } - SignalDatabase.attachments.createKeyIvIfNecessary(attachmentId) + SignalDatabase.attachments.createRemoteKeyIfNecessary(attachmentId) val databaseAttachment = SignalDatabase.attachments.getAttachment(attachmentId) ?: throw InvalidAttachmentException("Cannot find the specified attachment.") @@ -155,7 +156,7 @@ class AttachmentUploadJob private constructor( .then { form -> SignalNetwork.attachments.getResumableUploadSpec( key = Base64.decode(databaseAttachment.remoteKey!!), - iv = databaseAttachment.remoteIv!!, + iv = Util.getSecretBytes(16), uploadForm = form ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestJob.kt deleted file mode 100644 index 1715eb1345..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestJob.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2024 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.thoughtcrime.securesms.jobs - -import org.signal.core.util.Base64 -import org.signal.core.util.copyTo -import org.signal.core.util.logging.Log -import org.signal.core.util.stream.NullOutputStream -import org.signal.core.util.withinTransaction -import org.thoughtcrime.securesms.attachments.AttachmentId -import org.thoughtcrime.securesms.database.SignalDatabase -import org.thoughtcrime.securesms.jobmanager.Job -import org.thoughtcrime.securesms.jobs.protos.BackfillDigestJobData -import org.thoughtcrime.securesms.util.Util -import org.whispersystems.signalservice.api.crypto.AttachmentCipherOutputStream -import org.whispersystems.signalservice.internal.crypto.PaddingInputStream -import java.io.IOException - -/** - * This goes through all attachments with pre-existing data and recalcuates their digests. - * This is important for backupsV2, where we need to know an attachment's digest in advance. - * - * This job needs to be careful to (1) minimize time in the transaction, and (2) never write partial results to disk, i.e. only write the full (key/iv/digest) - * tuple together all at once (partial writes could poison the db, preventing us from retrying properly in the event of a crash or transient error). - */ -class BackfillDigestJob private constructor( - private val attachmentId: AttachmentId, - params: Parameters -) : Job(params) { - - companion object { - private val TAG = Log.tag(BackfillDigestJob::class) - const val KEY = "BackfillDigestJob" - const val QUEUE = "BackfillDigestJob" - } - - constructor(attachmentId: AttachmentId) : this( - attachmentId = attachmentId, - params = Parameters.Builder() - .setQueue(QUEUE) - .setMaxAttempts(3) - .setLifespan(Parameters.IMMORTAL) - .build() - ) - - override fun serialize(): ByteArray { - return BackfillDigestJobData(attachmentId = attachmentId.id).encode() - } - - override fun getFactoryKey(): String = KEY - - override fun run(): Result { - val (originalKey, originalIv, decryptingStream) = SignalDatabase.rawDatabase.withinTransaction { - val attachment = SignalDatabase.attachments.getAttachment(attachmentId) - if (attachment == null) { - Log.w(TAG, "$attachmentId no longer exists! Skipping.") - return Result.success() - } - - if (!attachment.hasData) { - Log.w(TAG, "$attachmentId no longer has any data! Skipping.") - return Result.success() - } - - val stream = try { - SignalDatabase.attachments.getAttachmentStream(attachmentId, offset = 0) - } catch (e: IOException) { - Log.w(TAG, "Could not open a stream for $attachmentId. Assuming that the file no longer exists. Skipping.", e) - return Result.success() - } - - // In order to match the exact digest calculation, we need to use the same padding that we would use when uploading the attachment. - Triple(attachment.remoteKey?.let { Base64.decode(it) }, attachment.remoteIv, PaddingInputStream(stream, attachment.size)) - } - - val key = originalKey ?: Util.getSecretBytes(64) - val iv = originalIv ?: Util.getSecretBytes(16) - - val cipherOutputStream = AttachmentCipherOutputStream(key, iv, NullOutputStream) - decryptingStream.copyTo(cipherOutputStream) - - val digest = cipherOutputStream.transmittedDigest - - SignalDatabase.attachments.updateKeyIvDigest( - attachmentId = attachmentId, - key = key, - iv = iv, - digest = digest - ) - - return Result.success() - } - - override fun onFailure() { - Log.w(TAG, "Failed to backfill digest for $attachmentId!") - } - - class Factory : Job.Factory { - override fun create(parameters: Parameters, serializedData: ByteArray?): BackfillDigestJob { - val attachmentId = AttachmentId(BackfillDigestJobData.ADAPTER.decode(serializedData!!).attachmentId) - return BackfillDigestJob(attachmentId, parameters) - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestsForDataFileJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestsForDataFileJob.kt index e4674f869a..710b6fa0ec 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestsForDataFileJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackfillDigestsForDataFileJob.kt @@ -32,12 +32,13 @@ class BackfillDigestsForDataFileJob private constructor( companion object { private val TAG = Log.tag(BackfillDigestsForDataFileJob::class) const val KEY = "BackfillDigestsForDataFileJob" + const val QUEUE = "BackfillDigestJob" } constructor(dataFile: String) : this( dataFile = dataFile, params = Parameters.Builder() - .setQueue(BackfillDigestJob.QUEUE) + .setQueue(QUEUE) .setMaxAttempts(3) .setLifespan(Parameters.IMMORTAL) .build() @@ -50,7 +51,7 @@ class BackfillDigestsForDataFileJob private constructor( override fun getFactoryKey(): String = KEY override fun run(): Result { - val (originalKey, originalIv, decryptingStream) = SignalDatabase.rawDatabase.withinTransaction { + val (originalKey, decryptingStream) = SignalDatabase.rawDatabase.withinTransaction { val attachment = SignalDatabase.attachments.getMostRecentValidAttachmentUsingDataFile(dataFile) if (attachment == null) { Log.w(TAG, "No attachments using file $dataFile exist anymore! Skipping.") @@ -65,21 +66,19 @@ class BackfillDigestsForDataFileJob private constructor( } // In order to match the exact digest calculation, we need to use the same padding that we would use when uploading the attachment. - Triple(attachment.remoteKey?.let { Base64.decode(it) }, attachment.remoteIv, PaddingInputStream(stream, attachment.size)) + Pair(attachment.remoteKey?.let { Base64.decode(it) }, PaddingInputStream(stream, attachment.size)) } val key = originalKey ?: Util.getSecretBytes(64) - val iv = originalIv ?: Util.getSecretBytes(16) - val cipherOutputStream = AttachmentCipherOutputStream(key, iv, NullOutputStream) + val cipherOutputStream = AttachmentCipherOutputStream(key, iv = null, NullOutputStream) decryptingStream.copyTo(cipherOutputStream) val digest = cipherOutputStream.transmittedDigest - SignalDatabase.attachments.updateKeyIvDigestByDataFile( + SignalDatabase.attachments.updateRemoteKeyAndDigestByDataFile( dataFile = dataFile, key = key, - iv = iv, digest = digest ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt index 96b3128bf7..f20da6c89d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/BackupMessagesJob.kt @@ -100,7 +100,6 @@ class BackupMessagesJob private constructor( .addConstraint(if (SignalStore.backup.backupWithCellular) NetworkConstraint.KEY else WifiConstraint.KEY) .setMaxAttempts(3) .setMaxInstancesForFactory(1) - .setQueue(BackfillDigestJob.QUEUE) // We want to ensure digests have been backfilled before this runs. Could eventually remove this constraint. .build() ) @@ -132,7 +131,7 @@ class BackupMessagesJob private constructor( val stopwatch = Stopwatch("BackupMessagesJob") - SignalDatabase.attachments.createKeyIvDigestForAttachmentsThatNeedArchiveUpload().takeIf { it > 0 }?.let { count -> Log.w(TAG, "Needed to create $count key/iv/digests.") } + SignalDatabase.attachments.createRemoteKeyForAttachmentsThatNeedArchiveUpload().takeIf { it > 0 }?.let { count -> Log.w(TAG, "Needed to create $count key/iv/digests.") } stopwatch.split("key-iv-digest") if (isCanceled) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index ef54421527..47ef188e69 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -50,7 +50,6 @@ import org.thoughtcrime.securesms.migrations.AvatarColorStorageServiceMigrationJ import org.thoughtcrime.securesms.migrations.AvatarIdRemovalMigrationJob; import org.thoughtcrime.securesms.migrations.AvatarMigrationJob; import org.thoughtcrime.securesms.migrations.BackfillDigestsForDuplicatesMigrationJob; -import org.thoughtcrime.securesms.migrations.BackfillDigestsMigrationJob; import org.thoughtcrime.securesms.migrations.BackupJitterMigrationJob; import org.thoughtcrime.securesms.migrations.BackupNotificationMigrationJob; import org.thoughtcrime.securesms.migrations.BadE164MigrationJob; @@ -131,7 +130,6 @@ public final class JobManagerFactories { put(AutomaticSessionResetJob.KEY, new AutomaticSessionResetJob.Factory()); put(AvatarGroupsV1DownloadJob.KEY, new AvatarGroupsV1DownloadJob.Factory()); put(AvatarGroupsV2DownloadJob.KEY, new AvatarGroupsV2DownloadJob.Factory()); - put(BackfillDigestJob.KEY, new BackfillDigestJob.Factory()); put(BackfillDigestsForDataFileJob.KEY, new BackfillDigestsForDataFileJob.Factory()); put(BackupDeleteJob.KEY, new BackupDeleteJob.Factory()); put(BackupMessagesJob.KEY, new BackupMessagesJob.Factory()); @@ -284,7 +282,6 @@ public final class JobManagerFactories { put(AvatarColorStorageServiceMigrationJob.KEY, new AvatarColorStorageServiceMigrationJob.Factory()); put(AvatarIdRemovalMigrationJob.KEY, new AvatarIdRemovalMigrationJob.Factory()); put(AvatarMigrationJob.KEY, new AvatarMigrationJob.Factory()); - put(BackfillDigestsMigrationJob.KEY, new BackfillDigestsMigrationJob.Factory()); put(BackfillDigestsForDuplicatesMigrationJob.KEY, new BackfillDigestsForDuplicatesMigrationJob.Factory()); put(BackupJitterMigrationJob.KEY, new BackupJitterMigrationJob.Factory()); put(BackupNotificationMigrationJob.KEY, new BackupNotificationMigrationJob.Factory()); @@ -394,6 +391,8 @@ public final class JobManagerFactories { put("BackupMediaSnapshotSyncJob", new FailingJob.Factory()); put("PnpInitializeDevicesJob", new FailingJob.Factory()); put("BackupRestoreJob", new FailingJob.Factory()); + put("BackfillDigestsMigrationJob", new PassingMigrationJob.Factory()); + put("BackfillDigestJob", new FailingJob.Factory()); }}; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentJob.kt index e67d8ed795..770450d711 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentJob.kt @@ -256,7 +256,7 @@ class RestoreAttachmentJob private constructor( } } - val downloadResult = if (useArchiveCdn) { + val decryptingStream = if (useArchiveCdn) { archiveFile = SignalDatabase.attachments.getOrCreateArchiveTransferFile(attachmentId) val cdnCredentials = BackupRepository.getCdnReadCredentials(BackupRepository.CredentialType.MEDIA, attachment.archiveCdn ?: RemoteConfig.backupFallbackArchiveCdn).successOrThrow().headers @@ -280,7 +280,7 @@ class RestoreAttachmentJob private constructor( ) } - SignalDatabase.attachments.finalizeAttachmentAfterDownload(messageId, attachmentId, downloadResult.dataStream, downloadResult.iv, if (manual) System.currentTimeMillis().milliseconds else null) + SignalDatabase.attachments.finalizeAttachmentAfterDownload(messageId, attachmentId, decryptingStream, if (manual) System.currentTimeMillis().milliseconds else null) } catch (e: RangeException) { val transferFile = archiveFile ?: attachmentFile Log.w(TAG, "Range exception, file size " + transferFile.length(), e) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentThumbnailJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentThumbnailJob.kt index d4a4d953d6..c8185ef4cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentThumbnailJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreAttachmentThumbnailJob.kt @@ -131,7 +131,7 @@ class RestoreAttachmentThumbnailJob private constructor( val pointer = attachment.createArchiveThumbnailPointer() Log.i(TAG, "Downloading thumbnail for $attachmentId") - val downloadResult = AppDependencies.signalServiceMessageReceiver + val decryptingStream = AppDependencies.signalServiceMessageReceiver .retrieveArchivedThumbnail( SignalStore.backup.mediaRootBackupKey.deriveMediaSecrets(attachment.requireThumbnailMediaName()), cdnCredentials, @@ -142,7 +142,7 @@ class RestoreAttachmentThumbnailJob private constructor( progressListener ) - SignalDatabase.attachments.finalizeAttachmentThumbnailAfterDownload(attachmentId, attachment.remoteDigest, downloadResult.dataStream, thumbnailTransferFile) + SignalDatabase.attachments.finalizeAttachmentThumbnailAfterDownload(attachmentId, attachment.remoteDigest, decryptingStream, thumbnailTransferFile) if (!SignalDatabase.messages.isStory(messageId)) { AppDependencies.messageNotifier.updateNotification(context) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt index 0d37246ceb..badd01a104 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RestoreLocalAttachmentJob.kt @@ -52,8 +52,8 @@ class RestoreLocalAttachmentJob private constructor( possibleRestorableAttachments .forEachIndexed { index, attachment -> - val fileInfo = if (attachment.remoteKey != null && attachment.remoteDigest != null) { - val mediaName = MediaName.fromDigest(attachment.remoteDigest).name + val fileInfo = if (attachment.plaintextHash != null && attachment.remoteKey != null) { + val mediaName = MediaName.fromPlaintextHashAndRemoteKey(attachment.plaintextHash, attachment.remoteKey).name mediaNameToFileInfo[mediaName] } else { null @@ -158,7 +158,7 @@ class RestoreLocalAttachmentJob private constructor( incrementalDigest = null, incrementalMacChunkSize = 0 ).use { input -> - SignalDatabase.attachments.finalizeAttachmentAfterDownload(attachment.mmsId, attachment.attachmentId, input, iv) + SignalDatabase.attachments.finalizeAttachmentAfterDownload(attachment.mmsId, attachment.attachmentId, input) } } catch (e: InvalidMessageException) { Log.w(TAG, "Experienced an InvalidMessageException while trying to read attachment.", e) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt index 352cc76c3c..e9ee4182c4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/UploadAttachmentToArchiveJob.kt @@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.jobs.protos.UploadAttachmentToArchiveJobData import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.service.AttachmentProgressService +import org.thoughtcrime.securesms.util.Util import org.whispersystems.signalservice.api.NetworkResult import org.whispersystems.signalservice.api.archive.ArchiveMediaUploadFormStatusCodes import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult @@ -124,8 +125,8 @@ class UploadAttachmentToArchiveJob private constructor( return Result.success() } - if (attachment.remoteKey == null || attachment.remoteIv == null) { - Log.w(TAG, "[$attachmentId] Attachment is missing remote key or IV! Cannot upload.") + if (attachment.remoteKey == null) { + Log.w(TAG, "[$attachmentId] Attachment is missing remote key! Cannot upload.") return Result.failure() } @@ -144,7 +145,7 @@ class UploadAttachmentToArchiveJob private constructor( if (uploadSpec == null) { Log.d(TAG, "[$attachmentId] Need an upload spec. Fetching...") - val (spec, result) = fetchResumableUploadSpec(key = Base64.decode(attachment.remoteKey), iv = attachment.remoteIv) + val (spec, result) = fetchResumableUploadSpec(key = Base64.decode(attachment.remoteKey), iv = Util.getSecretBytes(16)) if (result != null) { return result } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java index ae213b248b..d5e1879801 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -732,7 +732,7 @@ public class ApplicationMigrations { } if (lastSeenVersion < Version.BACKFILL_DIGESTS_V2) { - jobs.put(Version.BACKFILL_DIGESTS_V2, new BackfillDigestsMigrationJob()); +// jobs.put(Version.BACKFILL_DIGESTS_V2, new BackfillDigestsMigrationJob()); } if (lastSeenVersion < Version.CALL_LINK_STORAGE_SYNC) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/BackfillDigestsMigrationJob.kt b/app/src/main/java/org/thoughtcrime/securesms/migrations/BackfillDigestsMigrationJob.kt deleted file mode 100644 index 94872f40a4..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/BackfillDigestsMigrationJob.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.thoughtcrime.securesms.migrations - -import org.signal.core.util.logging.Log -import org.thoughtcrime.securesms.database.SignalDatabase -import org.thoughtcrime.securesms.dependencies.AppDependencies -import org.thoughtcrime.securesms.jobmanager.Job -import org.thoughtcrime.securesms.jobs.BackfillDigestJob - -/** - * Finds all attachments that need new digests and schedules a [BackfillDigestJob] for each. - */ -internal class BackfillDigestsMigrationJob( - parameters: Parameters = Parameters.Builder().build() -) : MigrationJob(parameters) { - - companion object { - val TAG = Log.tag(BackfillDigestsMigrationJob::class.java) - const val KEY = "BackfillDigestsMigrationJob" - } - - override fun getFactoryKey(): String = KEY - - override fun isUiBlocking(): Boolean = false - - override fun performMigration() { - val jobs = SignalDatabase.attachments.getAttachmentsThatNeedNewDigests() - .map { BackfillDigestJob(it) } - - AppDependencies.jobManager.addAll(jobs) - - Log.i(TAG, "Enqueued ${jobs.size} backfill digest jobs.") - } - - override fun shouldRetry(e: Exception): Boolean = false - - class Factory : Job.Factory { - override fun create(parameters: Parameters, serializedData: ByteArray?): BackfillDigestsMigrationJob { - return BackfillDigestsMigrationJob(parameters) - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java index 3897e0ec68..4011e50dc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/exo/PartDataSource.java @@ -86,7 +86,7 @@ class PartDataSource implements DataSource { throw new InvalidMessageException("Missing digest!"); } - this.inputStream = AttachmentCipherInputStream.createForArchivedMediaOuterAndInnerLayers(mediaKeyMaterial, archiveFile, originalCipherLength, attachment.size, decodedKey, attachment.remoteDigest, attachment.getIncrementalDigest(), attachment.incrementalMacChunkSize); + this.inputStream = AttachmentCipherInputStream.createForArchivedMedia(mediaKeyMaterial, archiveFile, originalCipherLength, attachment.size, decodedKey, attachment.remoteDigest, attachment.getIncrementalDigest(), attachment.incrementalMacChunkSize); } catch (InvalidMessageException e) { throw new IOException("Error decrypting attachment stream!", e); } diff --git a/app/src/main/protowire/Backup.proto b/app/src/main/protowire/Backup.proto index b19ebe330f..c7b3efc37d 100644 --- a/app/src/main/protowire/Backup.proto +++ b/app/src/main/protowire/Backup.proto @@ -749,15 +749,25 @@ message FilePointer { } message LocatorInfo { - // Must be non-empty if transitCdnKey or mediaName are set/nonempty. + // Must be non-empty if transitCdnKey or plaintextHash are set/nonempty. // Otherwise must be empty. bytes key = 1; + // From the sender of the attachment (incl. ourselves) - // Must be non-empty if transitCdnKey or mediaName are set/nonempty. - // Otherwise must be empty. - bytes digest = 2; - // Must be non-zero if transitCdnKey or mediaName are set/nonempty. - // Otherwise must be zero. + // Will be reserved once all clients start reading integrityCheck + bytes legacyDigest = 2; + + oneof integrityCheck { + // Set if file was at one point downloaded and its plaintextHash was calculated + bytes plaintextHash = 10; + + // Set if file has not been downloaded so its integrity has not been verified + // From the sender of the attachment + bytes encryptedDigest = 11; + } + + // NB: This is the plaintext size, and empty content attachments are legal, so this + // may be zero even if transitCdnKey or mediaName are set/nonempty. uint32 size = 3; // Either both transit cdn key and number are set or neither should be set. @@ -775,7 +785,9 @@ message FilePointer { // Nonempty any time the attachment was downloaded and its // digest validated, whether free tier or paid subscription. - string mediaName = 8; + // Will be reserved once all clients start reading integrityCheck, + // when mediaName will be derived from the plaintextHash and encryption key + string legacyMediaName = 8; // Separate key used to encrypt this file for the local backup. // Generally required for local backups. diff --git a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt index 0433f10341..3b03b3589d 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/sms/UploadDependencyGraphTest.kt @@ -234,7 +234,6 @@ class UploadDependencyGraphTest { cdn = attachment.cdn, location = attachment.remoteLocation, key = attachment.remoteKey, - iv = attachment.remoteIv, digest = attachment.remoteDigest, incrementalDigest = attachment.incrementalDigest, incrementalMacChunkSize = attachment.incrementalMacChunkSize, diff --git a/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt b/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt index d73cde1a36..71ffdd3451 100644 --- a/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt +++ b/app/src/testShared/org/thoughtcrime/securesms/database/FakeMessageRecords.kt @@ -79,7 +79,6 @@ object FakeMessageRecords { cdn = Cdn.fromCdnNumber(cdnNumber), location = location, key = key, - iv = iv, digest = digest, incrementalDigest = incrementalDigest, incrementalMacChunkSize = incrementalMacChunkSize, diff --git a/core-util-jvm/src/main/java/org/signal/core/util/Base64.kt b/core-util-jvm/src/main/java/org/signal/core/util/Base64.kt index aeb4bf9a30..e2d9ffe6d3 100644 --- a/core-util-jvm/src/main/java/org/signal/core/util/Base64.kt +++ b/core-util-jvm/src/main/java/org/signal/core/util/Base64.kt @@ -130,4 +130,24 @@ object Base64 { private fun String.stripPadding(): String { return this.replace("=", "") } + + fun String.decodeBase64OrThrow(): ByteArray { + return try { + decode(this) + } catch (e: IOException) { + throw AssertionError("Invalid Base64 string: $this", e) + } + } + + fun String?.decodeBase64(): ByteArray? { + if (this == null) { + return null + } + + return try { + decode(this) + } catch (e: IOException) { + return null + } + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9bcfb0036a..0b79d06e4a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ androidx-window = "1.3.0" glide = "4.15.1" gradle = "8.9.0" kotlin = "2.1.0" -libsignal-client = "0.74.0" +libsignal-client = "0.74.1" mp4parser = "1.9.39" android-gradle-plugin = "8.7.2" accompanist = "0.28.0" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 0b224b0032..1c4d3161cf 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -6769,6 +6769,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -6798,6 +6806,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -6827,6 +6840,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -6864,6 +6885,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -6872,6 +6901,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -6880,6 +6917,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -6888,6 +6933,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + @@ -6904,6 +6954,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -7311,20 +7369,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + - - - + + + - - + + diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java index 6dbc82bb4a..7fa3a2d66f 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java @@ -7,10 +7,8 @@ package org.whispersystems.signalservice.api; import org.signal.core.util.StreamUtil; -import org.signal.core.util.stream.LimitedInputStream; import org.signal.libsignal.protocol.InvalidMessageException; import org.signal.libsignal.zkgroup.profiles.ProfileKey; -import org.whispersystems.signalservice.api.attachment.AttachmentDownloadResult; import org.whispersystems.signalservice.api.backup.MediaRootBackupKey; import org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream; import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil; @@ -27,7 +25,6 @@ import org.whispersystems.signalservice.internal.util.Util; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.time.ZonedDateTime; @@ -68,7 +65,7 @@ public class SignalServiceMessageReceiver { */ public InputStream retrieveAttachment(SignalServiceAttachmentPointer pointer, File destination, long maxSizeBytes) throws IOException, InvalidMessageException, MissingConfigurationException { - return retrieveAttachment(pointer, destination, maxSizeBytes, null).getDataStream(); + return retrieveAttachment(pointer, destination, maxSizeBytes, null); } public InputStream retrieveProfileAvatar(String path, File destination, ProfileKey profileKey, long maxSizeBytes) @@ -99,9 +96,9 @@ public class SignalServiceMessageReceiver { * @throws IOException * @throws InvalidMessageException */ - public AttachmentDownloadResult retrieveAttachment(SignalServiceAttachmentPointer pointer, File destination, long maxSizeBytes, ProgressListener listener) + public InputStream retrieveAttachment(SignalServiceAttachmentPointer pointer, File destination, long maxSizeBytes, ProgressListener listener) throws IOException, InvalidMessageException, MissingConfigurationException { - if (!pointer.getDigest().isPresent()) throw new InvalidMessageException("No attachment digest!"); + if (pointer.getDigest().isEmpty()) throw new InvalidMessageException("No attachment digest!"); if (pointer.getKey() == null) throw new InvalidMessageException("No key!"); socket.retrieveAttachment(pointer.getCdnNumber(), Collections.emptyMap(), pointer.getRemoteId(), destination, maxSizeBytes, listener); @@ -111,16 +108,13 @@ public class SignalServiceMessageReceiver { StreamUtil.readFully(tempStream, iv); } - return new AttachmentDownloadResult( - AttachmentCipherInputStream.createForAttachment( - destination, - pointer.getSize().orElse(0), - pointer.getKey(), - pointer.getDigest().get(), - null, - 0 - ), - iv + return AttachmentCipherInputStream.createForAttachment( + destination, + pointer.getSize().orElse(0), + pointer.getKey(), + pointer.getDigest().get(), + null, + 0 ); } @@ -136,13 +130,13 @@ public class SignalServiceMessageReceiver { * * @return An InputStream that streams the plaintext attachment contents. */ - public AttachmentDownloadResult retrieveArchivedAttachment(@Nonnull MediaRootBackupKey.MediaKeyMaterial archivedMediaKeyMaterial, - @Nonnull Map readCredentialHeaders, - @Nonnull File archiveDestination, - @Nonnull SignalServiceAttachmentPointer pointer, - @Nonnull File attachmentDestination, - long maxSizeBytes, - @Nullable ProgressListener listener) + public InputStream retrieveArchivedAttachment(@Nonnull MediaRootBackupKey.MediaKeyMaterial archivedMediaKeyMaterial, + @Nonnull Map readCredentialHeaders, + @Nonnull File archiveDestination, + @Nonnull SignalServiceAttachmentPointer pointer, + @Nonnull File attachmentDestination, + long maxSizeBytes, + @Nullable ProgressListener listener) throws IOException, InvalidMessageException, MissingConfigurationException { if (pointer.getDigest().isEmpty()) { @@ -160,29 +154,16 @@ public class SignalServiceMessageReceiver { .map(s -> AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(s))) .orElse(0L); - // There's two layers of encryption -- one from the backup, and one from the attachment. This only strips the outermost backup encryption layer. - try (InputStream backupDecrypted = AttachmentCipherInputStream.createForArchivedMediaOuterLayer(archivedMediaKeyMaterial, archiveDestination, originalCipherLength)) { - try (FileOutputStream fos = new FileOutputStream(attachmentDestination)) { - // TODO [backup] I don't think we should be doing the full copy here. This is basically doing the entire download inline in this single line. - StreamUtil.copy(backupDecrypted, fos); - } - } - - byte[] iv = new byte[16]; - try (InputStream tempStream = new FileInputStream(attachmentDestination)) { - StreamUtil.readFully(tempStream, iv); - } - - LimitedInputStream dataStream = AttachmentCipherInputStream.createForAttachment( + return AttachmentCipherInputStream.createForArchivedMedia( + archivedMediaKeyMaterial, attachmentDestination, + originalCipherLength, pointer.getSize().orElse(0), pointer.getKey(), pointer.getDigest().get(), null, 0 ); - - return new AttachmentDownloadResult(dataStream, iv); } /** @@ -197,13 +178,13 @@ public class SignalServiceMessageReceiver { * * @return An InputStream that streams the plaintext attachment contents. */ - public AttachmentDownloadResult retrieveArchivedThumbnail(@Nonnull MediaRootBackupKey.MediaKeyMaterial archivedMediaKeyMaterial, - @Nonnull Map readCredentialHeaders, - @Nonnull File archiveDestination, - @Nonnull SignalServiceAttachmentPointer pointer, - @Nonnull File attachmentDestination, - long maxSizeBytes, - @Nullable ProgressListener listener) + public InputStream retrieveArchivedThumbnail(@Nonnull MediaRootBackupKey.MediaKeyMaterial archivedMediaKeyMaterial, + @Nonnull Map readCredentialHeaders, + @Nonnull File archiveDestination, + @Nonnull SignalServiceAttachmentPointer pointer, + @Nonnull File attachmentDestination, + long maxSizeBytes, + @Nullable ProgressListener listener) throws IOException, InvalidMessageException, MissingConfigurationException { if (pointer.getKey() == null) { @@ -217,26 +198,13 @@ public class SignalServiceMessageReceiver { .map(s -> AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(s))) .orElse(0L); - // There's two layers of encryption -- one from the backup, and one from the attachment. This only strips the outermost backup encryption layer. - try (InputStream backupDecrypted = AttachmentCipherInputStream.createForArchivedMediaOuterLayer(archivedMediaKeyMaterial, archiveDestination, originalCipherLength)) { - try (FileOutputStream fos = new FileOutputStream(attachmentDestination)) { - // TODO [backup] I don't think we should be doing the full copy here. This is basically doing the entire download inline in this single line. - StreamUtil.copy(backupDecrypted, fos); - } - } - - byte[] iv = new byte[16]; - try (InputStream tempStream = new FileInputStream(attachmentDestination)) { - StreamUtil.readFully(tempStream, iv); - } - - LimitedInputStream dataStream = AttachmentCipherInputStream.createForArchiveThumbnailInnerLayer( + return AttachmentCipherInputStream.createForArchivedThumbnail( + archivedMediaKeyMaterial, attachmentDestination, + originalCipherLength, pointer.getSize().orElse(0), pointer.getKey() ); - - return new AttachmentDownloadResult(dataStream, iv); } public void retrieveBackup(int cdnNumber, Map headers, String cdnPath, File destination, ProgressListener listener) throws MissingConfigurationException, IOException { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentApi.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentApi.kt index 1ffedd2ebc..bea50827db 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentApi.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentApi.kt @@ -91,7 +91,6 @@ class AttachmentApi( remoteId = SignalServiceAttachmentRemoteId.V4(attachmentData.resumableUploadSpec.cdnKey), cdnNumber = attachmentData.resumableUploadSpec.cdnNumber, key = resumableUploadSpec.attachmentKey, - iv = resumableUploadSpec.attachmentIv, digest = digestInfo.digest, incrementalDigest = digestInfo.incrementalDigest, incrementalDigestChunkSize = digestInfo.incrementalMacChunkSize, diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentUploadResult.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentUploadResult.kt index 67a27d74da..6acc497336 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentUploadResult.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/attachment/AttachmentUploadResult.kt @@ -14,7 +14,6 @@ class AttachmentUploadResult( val remoteId: SignalServiceAttachmentRemoteId, val cdnNumber: Int, val key: ByteArray, - val iv: ByteArray, val digest: ByteArray, val incrementalDigest: ByteArray?, val incrementalDigestChunkSize: Int, diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/backup/MediaName.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/backup/MediaName.kt index 479225db4f..cd4b5efd7b 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/backup/MediaName.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/backup/MediaName.kt @@ -14,8 +14,8 @@ import org.signal.core.util.Hex value class MediaName(val name: String) { companion object { - fun fromDigest(digest: ByteArray) = MediaName(Hex.toStringCondensed(digest)) - fun fromDigestForThumbnail(digest: ByteArray) = MediaName("${Hex.toStringCondensed(digest)}_thumbnail") + fun fromPlaintextHashAndRemoteKey(plaintextHash: ByteArray, remoteKey: ByteArray) = MediaName(Hex.toStringCondensed(plaintextHash + remoteKey)) + fun fromPlaintextHashAndRemoteKeyForThumbnail(plaintextHash: ByteArray, remoteKey: ByteArray) = MediaName(Hex.toStringCondensed(plaintextHash + remoteKey) + "_thumbnail") fun forThumbnailFromMediaName(mediaName: String) = MediaName("${mediaName}_thumbnail") /** diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.kt index 22e4417169..e97ea7c1ec 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.kt @@ -96,56 +96,6 @@ object AttachmentCipherInputStream { ) } - /** - * After removing the server layer of encryption using [createForArchivedMediaOuterLayer], use this to decrypt the inner layer of the attachment. - * Thumbnails have a special path because we don't do any additional digest/hash validation on them. - */ - @JvmStatic - @Throws(InvalidMessageException::class, IOException::class) - fun createForArchiveThumbnailInnerLayer( - file: File, - plaintextLength: Long, - combinedKeyMaterial: ByteArray - ): LimitedInputStream { - return create( - streamSupplier = { FileInputStream(file) }, - streamLength = file.length(), - plaintextLength = plaintextLength, - combinedKeyMaterial = combinedKeyMaterial, - digest = null, - incrementalDigest = null, - incrementalMacChunkSize = 0, - ignoreDigest = true - ) - } - - /** - * When you archive an attachment, you give the server an encrypted attachment, and the server wraps it in *another* layer of encryption. - * This will return a stream that unwraps the server's layer of encryption, giving you a stream that contains a "normally-encrypted" attachment. - * - * Because we're validating the encryptedDigest/plaintextHash of the inner layer, there's no additional out-of-band validation of this outer layer. - */ - @JvmStatic - @Throws(InvalidMessageException::class, IOException::class) - fun createForArchivedMediaOuterLayer(archivedMediaKeyMaterial: MediaKeyMaterial, file: File, originalCipherTextLength: Long): LimitedInputStream { - val mac = initMac(archivedMediaKeyMaterial.macKey) - - if (file.length() <= BLOCK_SIZE + mac.macLength) { - throw InvalidMessageException("Message shorter than crypto overhead!") - } - - FileInputStream(file).use { macVerificationStream -> - verifyMac(macVerificationStream, file.length(), mac, null) - } - - val encryptedStream = FileInputStream(file) - val encryptedStreamExcludingMac = LimitedInputStream(encryptedStream, file.length() - mac.macLength) - val cipher = createCipher(encryptedStreamExcludingMac, archivedMediaKeyMaterial.aesKey) - val inputStream: InputStream = BetterCipherInputStream(encryptedStreamExcludingMac, cipher) - - return LimitedInputStream(inputStream, originalCipherTextLength) - } - /** * When you archive an attachment, you give the server an encrypted attachment, and the server wraps it in *another* layer of encryption. * @@ -156,7 +106,7 @@ object AttachmentCipherInputStream { */ @JvmStatic @Throws(InvalidMessageException::class, IOException::class) - fun createForArchivedMediaOuterAndInnerLayers( + fun createForArchivedMedia( archivedMediaKeyMaterial: MediaKeyMaterial, file: File, originalCipherTextLength: Long, @@ -185,6 +135,42 @@ object AttachmentCipherInputStream { ) } + /** + * When you archive an attachment, you give the server an encrypted attachment, and the server wraps it in *another* layer of encryption. + * + * This creates a stream decrypt both the inner and outer layers of an archived attachment at the same time by basically double-decrypting it. + * + * @param incrementalDigest If null, incremental mac validation is disabled. + * @param incrementalMacChunkSize If 0, incremental mac validation is disabled. + */ + @JvmStatic + @Throws(InvalidMessageException::class, IOException::class) + fun createForArchivedThumbnail( + archivedMediaKeyMaterial: MediaKeyMaterial, + file: File, + originalCipherTextLength: Long, + plaintextLength: Long, + combinedKeyMaterial: ByteArray + ): LimitedInputStream { + val keyMaterial = CombinedKeyMaterial.from(combinedKeyMaterial) + val mac = initMac(keyMaterial.macKey) + + if (originalCipherTextLength <= BLOCK_SIZE + mac.macLength) { + throw InvalidMessageException("Message shorter than crypto overhead!") + } + + return create( + streamSupplier = { createForArchivedMediaOuterLayer(archivedMediaKeyMaterial, file, originalCipherTextLength) }, + streamLength = originalCipherTextLength, + plaintextLength = plaintextLength, + combinedKeyMaterial = combinedKeyMaterial, + digest = null, + incrementalDigest = null, + incrementalMacChunkSize = 0, + ignoreDigest = true + ) + } + /** * Creates a stream to decrypt sticker data. Stickers have a special path because the key material is derived from the pack key. */ @@ -209,6 +195,33 @@ object AttachmentCipherInputStream { return BetterCipherInputStream(encryptedStreamExcludingMac, cipher) } + /** + * When you archive an attachment, you give the server an encrypted attachment, and the server wraps it in *another* layer of encryption. + * This will return a stream that unwraps the server's layer of encryption, giving you a stream that contains a "normally-encrypted" attachment. + * + * Because we're validating the encryptedDigest/plaintextHash of the inner layer, there's no additional out-of-band validation of this outer layer. + */ + @JvmStatic + @Throws(InvalidMessageException::class, IOException::class) + private fun createForArchivedMediaOuterLayer(archivedMediaKeyMaterial: MediaKeyMaterial, file: File, originalCipherTextLength: Long): LimitedInputStream { + val mac = initMac(archivedMediaKeyMaterial.macKey) + + if (file.length() <= BLOCK_SIZE + mac.macLength) { + throw InvalidMessageException("Message shorter than crypto overhead!") + } + + FileInputStream(file).use { macVerificationStream -> + verifyMac(macVerificationStream, file.length(), mac, null) + } + + val encryptedStream = FileInputStream(file) + val encryptedStreamExcludingMac = LimitedInputStream(encryptedStream, file.length() - mac.macLength) + val cipher = createCipher(encryptedStreamExcludingMac, archivedMediaKeyMaterial.aesKey) + val inputStream: InputStream = BetterCipherInputStream(encryptedStreamExcludingMac, cipher) + + return LimitedInputStream(inputStream, originalCipherTextLength) + } + @JvmStatic @Throws(InvalidMessageException::class, IOException::class) private fun create( diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt index 0ac129f145..cc47e7bed6 100644 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt @@ -9,7 +9,6 @@ import org.junit.Assert import org.junit.Test import org.signal.core.util.StreamUtil import org.signal.core.util.allMatch -import org.signal.core.util.copyTo import org.signal.core.util.readFully import org.signal.core.util.stream.LimitedInputStream import org.signal.libsignal.protocol.InvalidMessageException @@ -224,89 +223,72 @@ class AttachmentCipherTest { } @Test - fun attachment_encryptDecryptPaddedContent() { - val lengths = intArrayOf(531, 600, 724, 1019, 1024) - - for (length in lengths) { - val plaintextInput = ByteArray(length) - - for (i in 0..