Strings work

Squashed commit of the following:

commit 86cab0e11e
Author: ThomasSession <thomas.r@getsession.org>
Date:   Fri Aug 30 10:17:04 2024 +1000

    Bringing my xml dialog styling from my 'Standardise message deletion' branch

commit 706d1aadd8
Author: ThomasSession <thomas.r@getsession.org>
Date:   Fri Aug 30 09:49:48 2024 +1000

    fixing up clear data dialog

    Removing unused code

commit f90599451f
Author: Al Lansley <al@oxen.io>
Date:   Fri Aug 30 09:13:51 2024 +1000

    Replaced 'now' with 12/24 hour time

commit 16b8ad46c0
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 17:34:03 2024 +1000

    Fix two one-liner issues

commit 4c6c450b32
Merge: 052f910d69 beb89d5b74
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 17:07:16 2024 +1000

    Merge branch 'strings-squashed' of https://github.com/oxen-io/session-android into strings-squashed

commit 052f910d69
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 17:06:53 2024 +1000

    More bold fixing

commit beb89d5b74
Author: fanchao <git@fanchao.dev>
Date:   Thu Aug 29 17:00:37 2024 +1000

    Fix incorrect group member left message

commit 5773f05a5c
Merge: d35482daba 1cec477020
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 15:21:44 2024 +1000

    Merge branch 'strings-squashed' of https://github.com/oxen-io/session-android into strings-squashed

commit d35482daba
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 15:20:13 2024 +1000

    More bold fixes and UI tweaks

commit 78a9ab7159
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 14:03:41 2024 +1000

    Making sure we bold appropriately

commit 1cec477020
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 13:33:50 2024 +1000

    Made call to 'getQuantityString' pass the count twice because otherwise it doesn't work correctly

commit 8e80ab08a9
Author: ThomasSession <thomas.r@getsession.org>
Date:   Thu Aug 29 13:28:54 2024 +1000

    Using the existing implementation

commit cb9554ab38
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 12:32:30 2024 +1000

    Merge CrowdIn strings circa 2024-08-29

commit dd57da70f6
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 09:06:22 2024 +1000

    Updated Phrase usage in ConversationAdapter

commit 34b15d7865
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 09:03:55 2024 +1000

    Converted TransferControlView into Kotlin and updated Phrase usage

commit a35a7a6a96
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 08:55:16 2024 +1000

    Converted MessageReceipientNotificationBuilder to Kotlin & updated Phrase usage

commit 6dd93b33f2
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 08:25:24 2024 +1000

    Update MuteDialog, LinkPreviewDialog, and PathActivity

commit e7dd1c582d
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 08:16:09 2024 +1000

    Updated DisappearingMessages.kt and HelpSettingsActivity.kt

commit 5bd55ea993
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 08:01:30 2024 +1000

    Converted SwitchPreferenceCompat to Kotlin and fixed the BlockedDialog using the joinCommunity string for some bizarre reason

commit d3fb440d05
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 07:15:03 2024 +1000

    Removed R.string.gif and replaced with a string constant

commit ace58e3493
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 29 07:11:53 2024 +1000

    getSubbedString correction

commit 2a8f010369
Merge: ce8efd7def 116bef3c71
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 16:31:43 2024 +1000

    Merge branch 'compose-open-url-dialog' into strings-squashed

commit ce8efd7def
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 16:31:11 2024 +1000

    WIP

commit 114066ad5f
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 15:30:02 2024 +1000

    Push before changing over all the Phrase.from to extension method calls

commit 116bef3c71
Author: ThomasSession <thomas.r@getsession.org>
Date:   Wed Aug 28 15:25:03 2024 +1000

    For safety

commit 0b1a71a582
Author: ThomasSession <thomas.r@getsession.org>
Date:   Wed Aug 28 15:23:02 2024 +1000

    Cleaning other use of old url dialog

commit 20abbebf4a
Author: ThomasSession <thomas.r@getsession.org>
Date:   Wed Aug 28 15:19:46 2024 +1000

    Forgot !!

commit 25132c6342
Author: ThomasSession <thomas.r@getsession.org>
Date:   Wed Aug 28 15:13:58 2024 +1000

    Proper set up for the Open URL dialog

commit 1f68791da9
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 14:35:05 2024 +1000

    Replaced placeholder text with new string

commit 8d97f31b4d
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 14:31:52 2024 +1000

    Adjusted comment

commit dfebe6f3f9
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 14:25:23 2024 +1000

    Moved block/unblock string selection logic into ViewModel and fixed a comment

commit 736b5313e6
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 14:02:54 2024 +1000

    Changed toast to warning - although condition to trigger should not be possible

commit 413bc0be4b
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 13:55:04 2024 +1000

    Adjusted EditGroupMembers to match iOS and fixed up save attachment commentary / logic

commit ae7164ecbb
Merge: 5df981bc7a d1c4283f42
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 09:51:58 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 2aa58f4dd6
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 28 08:27:03 2024 +1000

    WIP compose openURL dialog

commit 5df981bc7a
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 15:51:38 2024 +1000

    Adjusted NotificationRadioButton that takes string IDs to act as a pass-through

commit 96453f1f1e
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 15:42:33 2024 +1000

    Added some TODO markers for tomorrow

commit a402a1be79
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 15:33:55 2024 +1000

    Adjusted Landing page string substitutions to cater for emojis

commit 4809b5444b
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 15:12:39 2024 +1000

    Removed unused 'isEmpty' utility methods

commit b52048a080
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 14:42:57 2024 +1000

    Addressed many aspects of PR feedback + misc. strings issues

commit 9cdbc4b80b
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 09:50:51 2024 +1000

    Adjusted strings as per Rebecca's 'String Changes' spreadsheet

commit 4d7e4b9e2c
Merge: 3c576053a3 1393335121
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 27 08:19:53 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 3c576053a3
Author: alansley <aclansley@gmail.com>
Date:   Mon Aug 26 17:11:45 2024 +1000

    Moved  into libsession for ease of access to control message view creation

commit b908a54a44
Merge: 404fb8001c bfbe4a8fd2
Author: alansley <aclansley@gmail.com>
Date:   Mon Aug 26 11:54:09 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 404fb8001c
Author: alansley <aclansley@gmail.com>
Date:   Mon Aug 26 11:52:41 2024 +1000

    Performed a PR pass to fix up anything obvious - there's still a few things left TODO

commit 53978f818d
Author: Al Lansley <al@oxen.io>
Date:   Fri Aug 23 14:13:11 2024 +1000

    Cleaned up HomeActivityTests.kt

commit 5f82571bef
Merge: 69b8bd7396 8deb21c0c6
Author: Al Lansley <al@oxen.io>
Date:   Fri Aug 23 08:59:21 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 69b8bd7396
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 16:20:17 2024 +1000

    Added back app_name string so app names properly, fixed API 28 save issue, made some buttons display as red if they should

commit e3cab9c0d9
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 14:26:48 2024 +1000

    SS-75 Prevented ScrollView vertical scroll bar from fading out

commit b0b835092d
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 14:07:49 2024 +1000

    SS-64 Removed all 'Unblocked {name}' toasts as per instructions

commit c3c35de408
Merge: efc2ee2824 8e10e1abf4
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 13:43:00 2024 +1000

    Merge branch 'dev' into strings-squashed

commit efc2ee2824
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 13:40:59 2024 +1000

    Added some comments about the new CrowdIn strings

commit 7a03fb37ef
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 13:08:03 2024 +1000

    Initial integration of CrowdIn strings (English only)

commit 9766c3fd0b
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 09:55:14 2024 +1000

    SS-75 Added 'Copied' toast when the user copies a URL in the Open URL dialog

commit 59b4805b8b
Author: alansley <aclansley@gmail.com>
Date:   Thu Aug 22 09:51:01 2024 +1000

    SS-75 Prevent 'Are you sure you want to open this URL?' dialog from being excessively tall when given a very long URL

commit b7f627f03c
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 21 14:54:17 2024 +1000

    Made closed group deleting-someone-elses msgs use 'Delete message' or 'Delete Messages' appropriately

commit 69f6818f99
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 21 13:53:58 2024 +1000

    Adjusted SS-64 so that all Block / Unblock buttons now use that text and are displayed in red

commit 2192c2c007
Merge: 2338bb47ca eea54d1a17
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 21 13:28:16 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 2338bb47ca
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 19:11:40 2024 +1000

    Converted DefaultMessageNotifier to Kotlin because it needs adjustment & that Java is nasty

commit 6b29e4d8ce
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 17:53:27 2024 +1000

    Added a note about the plurals for search results

commit f7748a0c05
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 16:06:24 2024 +1000

    Corrected text on storage permission dialog

commit f6b6256598
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 14:44:25 2024 +1000

    Minor cleanup of BlockedContactsActivity

commit e3d4870d81
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 14:41:14 2024 +1000

    Addressed changes to fix SS-64 / QA-146 - unblocking contacts modal & toast adjustments

commit e812527358
Merge: 5e02e1ef5c 9919f716a7
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 13:27:35 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 5e02e1ef5c
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 09:39:16 2024 +1000

    Added 'NonTranslatableStringConstants' file

commit 816f21bb29
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 20 09:30:30 2024 +1000

    Addressed commit feedback & removed desktop string 'attachmentsClickToDownload' as we use 'attachmentsTapToDownload'

commit acc8d47c68
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 19 16:22:08 2024 +1000

    SES-1571 Large messages show warning toast

commit 27ca77d5c4
Merge: 27bc90bf1f f379604c54
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 19 11:19:27 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 27bc90bf1f
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 19 08:59:38 2024 +1000

    Cleaned up some comments and content description

commit 558684a56d
Merge: 90d7064c18 93a28906fb
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 19 08:41:47 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 90d7064c18
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 15 12:13:30 2024 +1000

    Fixed issue where new closed groups would display a timestamp instead of the 'groupNoMessages' text

commit 51ef0ec81c
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 15 09:45:28 2024 +1000

    Replaced string 'CreateProfileActivity_profile_photo' with the string 'photo' which has the same text ('Photo')

commit eecce08c25
Merge: 01009cf521 5a248da445
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 15 09:38:10 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 01009cf521
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 15 08:37:19 2024 +1000

    Changed allowed emoji reactions per minute from 5 (which I used for testing) to 20 (production)

commit 9441d1e08d
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 15 08:34:16 2024 +1000

    Refactored emoji rate limiter to use a timestamp mechanism rather than removing queue items after a delay

commit 6cd6cc3e26
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 14 16:48:07 2024 +1000

    Adjusted emoji rate limit to 20 reactions per minute to match acceptance criteria

commit edd154d8e1
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 14 16:02:16 2024 +1000

    SS-78 / SES-199 Mechanism required to limit emoji reaction rate

commit a8ee5c9f3b
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 14 14:51:40 2024 +1000

    Replaced hard-coded 'Session' with '{app_name}' in 'callsSessionCall'

commit 621094ebe4
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 14 13:40:01 2024 +1000

    SS-72 Update save attachment models + add one-time warning that other apps can access saved attachments

commit 0c83606539
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 13 15:50:35 2024 +1000

    SS-75 Open URL modal change

commit 802cf19598
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 12 16:42:15 2024 +1000

    Open or copy URL WIP

commit ea84aa1478
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 12 14:17:04 2024 +1000

    Tied in bandDeleteAll string

commit 93b8e74f2d
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 12 11:34:03 2024 +1000

    Job done! All Accessibility ID strings mapped and/or dealt with appropriately!

commit fc3b4ad367
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 12 09:49:57 2024 +1000

    Further AccessibilityId mapping & fixed group members counts to display correct details

commit 558d6741b1
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 9 17:24:44 2024 +1000

    End of day push

commit 73fdb16214
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 9 15:57:06 2024 +1000

    Localised time strings working - even if the unit tests aren't

commit 436175d146
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 9 13:54:09 2024 +1000

    Relative time string WIP

commit f309263e39
Merge: 45c4118d52 007e705cd9
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 9 11:39:13 2024 +1000

    Merge dev

commit 45c4118d52
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 8 16:43:02 2024 +1000

    Further AccessibilityId mapping WIP

commit 31bac8e30e
Author: Al Lansley <al@oxen.io>
Date:   Thu Aug 8 10:53:30 2024 +1000

    Further accessibility ID changes & removed fragment_new_conversation_home.xml

commit 9c2111e66e
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 7 13:13:52 2024 +1000

    AccessibilityId WIP

commit 1e9eeff86a
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 7 11:06:39 2024 +1000

    AccessibilityId adjustments & removed some unused XML layouts

commit e5fd2c8cc0
Author: alansley <aclansley@gmail.com>
Date:   Wed Aug 7 09:22:14 2024 +1000

    AccessibilityId refactor WIP

commit 399796bac3
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 6 15:51:53 2024 +1000

    AccessibilityId WIP - up to AccessibilityId_reveal_recovery_phrase_button

commit a8d72dfcc0
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 6 14:12:10 2024 +1000

    Cleaned up a few comments and fixed some plurals logic

commit be400d8f4f
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 6 11:32:08 2024 +1000

    Removed commented out merge conflict marker

commit 5cbe289a8d
Merge: 5fe123e7b5 d6c5ab2b18
Author: alansley <aclansley@gmail.com>
Date:   Tue Aug 6 11:30:50 2024 +1000

    Merge dev and cleanup

commit 5fe123e7b5
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 14:37:47 2024 +1000

    Adjusted sending of mms messages to show 'Uploading' rather than 'Sending' as per SES-1721

commit d3f8e928b6
Merge: 00552930e6 cd1a0643e3
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 13:30:03 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 00552930e6
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 13:28:55 2024 +1000

    Removed unused helpReportABugDesktop strings

commit 6c0450b487
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 12:59:15 2024 +1000

    Renamed 'quitButton' string to just 'quit'

commit 284c485903
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 12:00:35 2024 +1000

    Replaced 'screenSecurity' with 'screenshotNotifications' as the title of the notifications toggle

commit 6948d64fa8
Author: Al Lansley <al@oxen.io>
Date:   Mon Aug 5 10:45:05 2024 +1000

    WIP

commit bc94cb78db
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 16:21:16 2024 +1000

    End of day push

commit 1a2df3798a
Merge: c7fdb6aed9 a56e1d0b91
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 15:20:19 2024 +1000

    Merged dev

commit c7fdb6aed9
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 14:21:11 2024 +1000

    Replaced string 'dialog_disappearing_messages_follow_setting_confirm' with 'confirm'

commit 2992d590d9
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 14:01:00 2024 +1000

    Removed string 'attachment_type_selector__gallery' and associated / un-used 'attachment_type_selector.xml' layout

commit 4218663c95
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 13:39:54 2024 +1000

    Removed 'message_details_header__disappears' and the unused 'activity_message_detail.xml' which was the only reference to it

commit ba2d0275e4
Author: alansley <aclansley@gmail.com>
Date:   Fri Aug 2 12:15:42 2024 +1000

    Implemented task SS-79 to only provide a save attachment menu option when the attachment download is complete

commit 20662c8222
Merge: 608c984a6b fbbef4898a
Author: alansley <aclansley@gmail.com>
Date:   Wed Jul 31 13:08:04 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 608c984a6b
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 16:58:08 2024 +1000

    Actually remove the 4 specific time period mute strings

commit 006a4e8bad
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 16:43:54 2024 +1000

    Cleaned up MuteDialog.kt

commit d3177f9f1a
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 16:27:06 2024 +1000

    Added a 1 second kludge to the mute for subtitle so that it initially shows 1 hour not 59 minutes etc.

commit d568a86649
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 16:20:20 2024 +1000

    Removed 'Muted for' strings and fixed it up to use 'Mute for {large_time_unit}' across the board

commit 84f6f19cf4
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 11:03:46 2024 +1000

    Changed some hard-coded 'Session' text in strings and renamed another

commit bc90d18c91
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 10:27:55 2024 +1000

    Cleaned up a leftover plural & changed 'app_name' to use 'sessionMessenger' string

commit 79cd87878c
Merge: 3b62e474b3 dec02cef5a
Author: alansley <aclansley@gmail.com>
Date:   Tue Jul 30 08:16:02 2024 +1000

    Merge branch 'dev' into strings-squashed

commit 3b62e474b3
Author: Al Lansley <al@oxen.io>
Date:   Mon Jul 29 16:33:21 2024 +1000

    Down to just the final few straggler strings

commit 13e81f046b
Author: Al Lansley <al@oxen.io>
Date:   Mon Jul 29 13:13:54 2024 +1000

    WIP

commit 2d9961d5c0
Author: Al Lansley <al@oxen.io>
Date:   Mon Jul 29 08:58:01 2024 +1000

    Further cleanup of stragglers

commit 08b8a84309
Author: Al Lansley <al@oxen.io>
Date:   Mon Jul 29 08:29:12 2024 +1000

    Cleaning up straggler strings

commit d0e87c64b5
Author: alansley <aclansley@gmail.com>
Date:   Fri Jul 26 17:07:46 2024 +1000

    WIP

commit 4bc9d09be2
Author: alansley <aclansley@gmail.com>
Date:   Fri Jul 26 16:30:28 2024 +1000

    WIP

commit 3cee4bc12f
Merge: aa1db13e3a a495ec232a
Author: alansley <aclansley@gmail.com>
Date:   Fri Jul 26 13:57:09 2024 +1000

    Removed some legacy strings & substituted others

commit aa1db13e3a
Author: fanchao <git@fanchao.dev>
Date:   Fri Jul 26 11:34:05 2024 +1000

    Initial squash merge for strings
This commit is contained in:
fanchao
2024-09-06 11:21:03 +10:00
parent 67bcc937ce
commit d41496a997
279 changed files with 37625 additions and 16137 deletions

View File

@@ -1,5 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdkVersion androidCompileSdkVersion
@@ -25,7 +27,6 @@ dependencies {
implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonDatabindVersion"
implementation "com.github.oxen-io.session-android-curve-25519:curve25519-java:$curve25519Version"
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
implementation "nl.komponents.kovenant:kovenant:$kovenantVersion"

View File

@@ -1,3 +1,3 @@
all:
protoc25 --java_out=../src/main/java/ SignalService.proto WebSocketResources.proto Utils.proto
protoc --java_out=../src/main/java/ SignalService.proto WebSocketResources.proto Utils.proto

View File

@@ -129,15 +129,109 @@ message DataMessage {
required string name = 3;
}
// New closed group update messages
message GroupUpdateMessage {
optional GroupUpdateInviteMessage inviteMessage = 1;
optional GroupUpdateInfoChangeMessage infoChangeMessage = 2;
optional GroupUpdateMemberChangeMessage memberChangeMessage = 3;
optional GroupUpdatePromoteMessage promoteMessage = 4;
optional GroupUpdateMemberLeftMessage memberLeftMessage = 5;
optional GroupUpdateInviteResponseMessage inviteResponse = 6;
optional GroupUpdateDeleteMemberContentMessage deleteMemberContent = 7;
optional GroupUpdateMemberLeftNotificationMessage memberLeftNotificationMessage = 8;
}
// New closed groups
message GroupUpdateInviteMessage {
// @required
required string groupSessionId = 1; // The `groupIdentityPublicKey` with a `03` prefix
// @required
required string name = 2;
// @required
required bytes memberAuthData = 3;
// @required
required bytes adminSignature = 4;
}
message GroupUpdateDeleteMessage {
repeated string memberSessionIds = 1;
// @required
// signature of "DELETE" || timestamp || sessionId[0] || ... || sessionId[n]
required bytes adminSignature = 2;
}
message GroupUpdatePromoteMessage {
// @required
required bytes groupIdentitySeed = 1;
// @required
required string name = 2;
}
message GroupUpdateInfoChangeMessage {
enum Type {
NAME = 1;
AVATAR = 2;
DISAPPEARING_MESSAGES = 3;
}
// @required
required Type type = 1;
optional string updatedName = 2;
optional uint32 updatedExpiration = 3;
// @required
// "INFO_CHANGE" || type || timestamp
required bytes adminSignature = 4;
}
message GroupUpdateMemberChangeMessage {
enum Type {
ADDED = 1;
REMOVED = 2;
PROMOTED = 3;
}
// @required
required Type type = 1;
repeated string memberSessionIds = 2;
optional bool historyShared = 3;
// @required
// "MEMBER_CHANGE" || type || timestamp
required bytes adminSignature = 4;
}
message GroupUpdateMemberLeftMessage {
// the pubkey of the member left is included as part of the closed group encryption logic (senderIdentity on desktop)
}
message GroupUpdateInviteResponseMessage {
// @required
required bool isApproved = 1; // Whether the request was approved
}
message GroupUpdateDeleteMemberContentMessage {
repeated string memberSessionIds = 1;
repeated string messageHashes = 2;
optional bytes adminSignature = 3;
}
message GroupUpdateMemberLeftNotificationMessage {
// the pubkey of the member left is included as part of the closed group encryption logic (senderIdentity on desktop)
}
message ClosedGroupControlMessage {
enum Type {
NEW = 1; // publicKey, name, encryptionKeyPair, members, admins, expireTimer
ENCRYPTION_KEY_PAIR = 3; // publicKey, wrappers
NAME_CHANGE = 4; // name
MEMBERS_ADDED = 5; // members
MEMBERS_REMOVED = 6; // members
NEW = 1; // publicKey, name, encryptionKeyPair, members, admins, expireTimer
ENCRYPTION_KEY_PAIR = 3; // publicKey, wrappers
NAME_CHANGE = 4; // name
MEMBERS_ADDED = 5; // members
MEMBERS_REMOVED = 6; // members
MEMBER_LEFT = 7;
INVITE = 9; // publicKey, name, memberPrivateKey
PROMOTE = 10; // publicKey, privateKey
DELETE_GROUP = 11; // publicKey, members
DELETE_MESSAGES = 12; // publicKey
DELETE_ATTACHMENTS = 13; // publicKey
}
message KeyPairWrapper {
@@ -156,6 +250,8 @@ message DataMessage {
repeated bytes admins = 6;
repeated KeyPairWrapper wrappers = 7;
optional uint32 expirationTimer = 8;
optional bytes memberPrivateKey = 9;
optional bytes privateKey = 10;
}
message Reaction {
@@ -174,7 +270,6 @@ message DataMessage {
optional string body = 1;
repeated AttachmentPointer attachments = 2;
optional GroupContext group = 3;
optional uint32 flags = 4;
optional uint32 expireTimer = 5;
optional bytes profileKey = 6;
@@ -187,6 +282,34 @@ message DataMessage {
optional ClosedGroupControlMessage closedGroupControlMessage = 104;
optional string syncTarget = 105;
optional bool blocksCommunityMessageRequests = 106;
optional GroupUpdateMessage groupUpdateMessage = 120;
}
message GroupDeleteMessage {
// @required
required bytes publicKey = 1; // the identity public key of the group to be deleted
// @required
required bytes lastEncryptionKey = 2; // used by members to make sure incoming admin action can be trusted
}
message GroupMemberLeftMessage {
// the pubkey of the member left is included as part of the closed group encryption logic (senderIdentity on desktop)
}
message GroupInviteMessage {
// @required
required bytes publicKey = 1; // this is the group public key
// @required
required string name = 2;
// @required
required bytes memberPrivateKey = 3;
}
message GroupPromoteMessage {
// @required
required bytes publicKey = 1; // this is the session id for the user that should be promoted
// @required
required bytes encryptedPrivateKey = 2; // this is the group admins key
}
message CallMessage {
@@ -299,24 +422,4 @@ message AttachmentPointer {
optional uint32 height = 10;
optional string caption = 11;
optional string url = 101;
}
message GroupContext {
enum Type {
UNKNOWN = 0;
UPDATE = 1;
DELIVER = 2;
QUIT = 3;
REQUEST_INFO = 4;
}
// @required
optional bytes id = 1;
// @required
optional Type type = 2;
optional string name = 3;
repeated string members = 4;
optional AttachmentPointer avatar = 5;
repeated string admins = 6;
}
}

View File

@@ -35,12 +35,15 @@ public class SignalServiceGroup {
UNKNOWN,
UPDATE,
DELIVER,
MEMBER_LEFT,
QUIT,
REQUEST_INFO,
CREATION,
NAME_CHANGE,
MEMBER_ADDED,
MEMBER_REMOVED
MEMBER_REMOVED,
LEAVING,
ERROR_QUIT,
KICKED,
}
private final byte[] groupId;
@@ -86,6 +89,10 @@ public class SignalServiceGroup {
return groupId;
}
public boolean isNewClosedGroup() {
return groupId.length == 33 && groupId[0] == 0x03;
}
public GroupType getGroupType() { return groupType; }
public Type getType() {

View File

@@ -1,27 +1,48 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: Utils.proto
// Protobuf Java Version: 4.27.1
package org.session.libsignal.protos;
public final class UtilProtos {
private UtilProtos() {}
static {
com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
/* major= */ 4,
/* minor= */ 27,
/* patch= */ 1,
/* suffix= */ "",
UtilProtos.class.getName());
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
public interface ByteArrayListOrBuilder
extends com.google.protobuf.MessageOrBuilder {
public interface ByteArrayListOrBuilder extends
// @@protoc_insertion_point(interface_extends:signalservice.ByteArrayList)
com.google.protobuf.MessageOrBuilder {
// repeated bytes content = 1;
/**
* <code>repeated bytes content = 1;</code>
* @return A list containing the content.
*/
java.util.List<com.google.protobuf.ByteString> getContentList();
/**
* <code>repeated bytes content = 1;</code>
* @return The count of content.
*/
int getContentCount();
/**
* <code>repeated bytes content = 1;</code>
* @param index The index of the element to return.
* @return The content at the given index.
*/
com.google.protobuf.ByteString getContent(int index);
}
@@ -29,81 +50,33 @@ public final class UtilProtos {
* Protobuf type {@code signalservice.ByteArrayList}
*/
public static final class ByteArrayList extends
com.google.protobuf.GeneratedMessage
implements ByteArrayListOrBuilder {
com.google.protobuf.GeneratedMessage implements
// @@protoc_insertion_point(message_implements:signalservice.ByteArrayList)
ByteArrayListOrBuilder {
private static final long serialVersionUID = 0L;
static {
com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
/* major= */ 4,
/* minor= */ 27,
/* patch= */ 1,
/* suffix= */ "",
ByteArrayList.class.getName());
}
// Use ByteArrayList.newBuilder() to construct.
private ByteArrayList(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder);
this.unknownFields = builder.getUnknownFields();
}
private ByteArrayList(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final ByteArrayList defaultInstance;
public static ByteArrayList getDefaultInstance() {
return defaultInstance;
private ByteArrayList() {
content_ = emptyList(com.google.protobuf.ByteString.class);
}
public ByteArrayList getDefaultInstanceForType() {
return defaultInstance;
}
private final com.google.protobuf.UnknownFieldSet unknownFields;
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private ByteArrayList(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
initFields();
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
default: {
if (!parseUnknownField(input, unknownFields,
extensionRegistry, tag)) {
done = true;
}
break;
}
case 10: {
if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
content_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
mutable_bitField0_ |= 0x00000001;
}
content_.add(input.readBytes());
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
content_ = java.util.Collections.unmodifiableList(content_);
}
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_fieldAccessorTable
@@ -111,68 +84,58 @@ public final class UtilProtos {
org.session.libsignal.protos.UtilProtos.ByteArrayList.class, org.session.libsignal.protos.UtilProtos.ByteArrayList.Builder.class);
}
public static com.google.protobuf.Parser<ByteArrayList> PARSER =
new com.google.protobuf.AbstractParser<ByteArrayList>() {
public ByteArrayList parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new ByteArrayList(input, extensionRegistry);
}
};
@java.lang.Override
public com.google.protobuf.Parser<ByteArrayList> getParserForType() {
return PARSER;
}
// repeated bytes content = 1;
public static final int CONTENT_FIELD_NUMBER = 1;
private java.util.List<com.google.protobuf.ByteString> content_;
@SuppressWarnings("serial")
private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> content_ =
emptyList(com.google.protobuf.ByteString.class);
/**
* <code>repeated bytes content = 1;</code>
* @return A list containing the content.
*/
@java.lang.Override
public java.util.List<com.google.protobuf.ByteString>
getContentList() {
return content_;
}
/**
* <code>repeated bytes content = 1;</code>
* @return The count of content.
*/
public int getContentCount() {
return content_.size();
}
/**
* <code>repeated bytes content = 1;</code>
* @param index The index of the element to return.
* @return The content at the given index.
*/
public com.google.protobuf.ByteString getContent(int index) {
return content_.get(index);
}
private void initFields() {
content_ = java.util.Collections.emptyList();
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized != -1) return isInitialized == 1;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
for (int i = 0; i < content_.size(); i++) {
output.writeBytes(1, content_.get(i));
}
getUnknownFields().writeTo(output);
}
private int memoizedSerializedSize = -1;
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSerializedSize;
int size = memoizedSize;
if (size != -1) return size;
size = 0;
@@ -186,17 +149,53 @@ public final class UtilProtos {
size += 1 * getContentList().size();
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
memoizedSize = size;
return size;
}
private static final long serialVersionUID = 0L;
@java.lang.Override
protected java.lang.Object writeReplace()
throws java.io.ObjectStreamException {
return super.writeReplace();
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof org.session.libsignal.protos.UtilProtos.ByteArrayList)) {
return super.equals(obj);
}
org.session.libsignal.protos.UtilProtos.ByteArrayList other = (org.session.libsignal.protos.UtilProtos.ByteArrayList) obj;
if (!getContentList()
.equals(other.getContentList())) return false;
if (!getUnknownFields().equals(other.getUnknownFields())) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
if (getContentCount() > 0) {
hash = (37 * hash) + CONTENT_FIELD_NUMBER;
hash = (53 * hash) + getContentList().hashCode();
}
hash = (29 * hash) + getUnknownFields().hashCode();
memoizedHashCode = hash;
return hash;
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
@@ -220,42 +219,57 @@ public final class UtilProtos {
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
return com.google.protobuf.GeneratedMessage
.parseWithIOException(PARSER, input);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
return com.google.protobuf.GeneratedMessage
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input);
return com.google.protobuf.GeneratedMessage
.parseDelimitedWithIOException(PARSER, input);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry);
return com.google.protobuf.GeneratedMessage
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return PARSER.parseFrom(input);
return com.google.protobuf.GeneratedMessage
.parseWithIOException(PARSER, input);
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry);
return com.google.protobuf.GeneratedMessage
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static Builder newBuilder() { return Builder.create(); }
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.session.libsignal.protos.UtilProtos.ByteArrayList prototype) {
return newBuilder().mergeFrom(prototype);
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(org.session.libsignal.protos.UtilProtos.ByteArrayList prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
public Builder toBuilder() { return newBuilder(this); }
@java.lang.Override
protected Builder newBuilderForType(
@@ -267,13 +281,15 @@ public final class UtilProtos {
* Protobuf type {@code signalservice.ByteArrayList}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder>
implements org.session.libsignal.protos.UtilProtos.ByteArrayListOrBuilder {
com.google.protobuf.GeneratedMessage.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:signalservice.ByteArrayList)
org.session.libsignal.protos.UtilProtos.ByteArrayListOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_fieldAccessorTable
@@ -283,42 +299,34 @@ public final class UtilProtos {
// Construct using org.session.libsignal.protos.UtilProtos.ByteArrayList.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
}
}
private static Builder create() {
return new Builder();
}
}
@java.lang.Override
public Builder clear() {
super.clear();
content_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000001);
bitField0_ = 0;
content_ = emptyList(com.google.protobuf.ByteString.class);
return this;
}
public Builder clone() {
return create().mergeFrom(buildPartial());
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
}
@java.lang.Override
public org.session.libsignal.protos.UtilProtos.ByteArrayList getDefaultInstanceForType() {
return org.session.libsignal.protos.UtilProtos.ByteArrayList.getDefaultInstance();
}
@java.lang.Override
public org.session.libsignal.protos.UtilProtos.ByteArrayList build() {
org.session.libsignal.protos.UtilProtos.ByteArrayList result = buildPartial();
if (!result.isInitialized()) {
@@ -327,18 +335,23 @@ public final class UtilProtos {
return result;
}
@java.lang.Override
public org.session.libsignal.protos.UtilProtos.ByteArrayList buildPartial() {
org.session.libsignal.protos.UtilProtos.ByteArrayList result = new org.session.libsignal.protos.UtilProtos.ByteArrayList(this);
int from_bitField0_ = bitField0_;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
content_ = java.util.Collections.unmodifiableList(content_);
bitField0_ = (bitField0_ & ~0x00000001);
}
result.content_ = content_;
if (bitField0_ != 0) { buildPartial0(result); }
onBuilt();
return result;
}
private void buildPartial0(org.session.libsignal.protos.UtilProtos.ByteArrayList result) {
int from_bitField0_ = bitField0_;
if (((from_bitField0_ & 0x00000001) != 0)) {
content_.makeImmutable();
result.content_ = content_;
}
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.session.libsignal.protos.UtilProtos.ByteArrayList) {
return mergeFrom((org.session.libsignal.protos.UtilProtos.ByteArrayList)other);
@@ -353,7 +366,8 @@ public final class UtilProtos {
if (!other.content_.isEmpty()) {
if (content_.isEmpty()) {
content_ = other.content_;
bitField0_ = (bitField0_ & ~0x00000001);
content_.makeImmutable();
bitField0_ |= 0x00000001;
} else {
ensureContentIsMutable();
content_.addAll(other.content_);
@@ -361,99 +375,133 @@ public final class UtilProtos {
onChanged();
}
this.mergeUnknownFields(other.getUnknownFields());
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.session.libsignal.protos.UtilProtos.ByteArrayList parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.session.libsignal.protos.UtilProtos.ByteArrayList) e.getUnfinishedMessage();
throw e;
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 10: {
com.google.protobuf.ByteString v = input.readBytes();
ensureContentIsMutable();
content_.add(v);
break;
} // case 10
default: {
if (!super.parseUnknownField(input, extensionRegistry, tag)) {
done = true; // was an endgroup tag
}
break;
} // default:
} // switch (tag)
} // while (!done)
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.unwrapIOException();
} finally {
onChanged();
} // finally
return this;
}
private int bitField0_;
// repeated bytes content = 1;
private java.util.List<com.google.protobuf.ByteString> content_ = java.util.Collections.emptyList();
private com.google.protobuf.Internal.ProtobufList<com.google.protobuf.ByteString> content_ = emptyList(com.google.protobuf.ByteString.class);
private void ensureContentIsMutable() {
if (!((bitField0_ & 0x00000001) == 0x00000001)) {
content_ = new java.util.ArrayList<com.google.protobuf.ByteString>(content_);
bitField0_ |= 0x00000001;
}
if (!content_.isModifiable()) {
content_ = makeMutableCopy(content_);
}
bitField0_ |= 0x00000001;
}
/**
* <code>repeated bytes content = 1;</code>
* @return A list containing the content.
*/
public java.util.List<com.google.protobuf.ByteString>
getContentList() {
return java.util.Collections.unmodifiableList(content_);
content_.makeImmutable();
return content_;
}
/**
* <code>repeated bytes content = 1;</code>
* @return The count of content.
*/
public int getContentCount() {
return content_.size();
}
/**
* <code>repeated bytes content = 1;</code>
* @param index The index of the element to return.
* @return The content at the given index.
*/
public com.google.protobuf.ByteString getContent(int index) {
return content_.get(index);
}
/**
* <code>repeated bytes content = 1;</code>
* @param index The index to set the value at.
* @param value The content to set.
* @return This builder for chaining.
*/
public Builder setContent(
int index, com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
ensureContentIsMutable();
if (value == null) { throw new NullPointerException(); }
ensureContentIsMutable();
content_.set(index, value);
bitField0_ |= 0x00000001;
onChanged();
return this;
}
/**
* <code>repeated bytes content = 1;</code>
* @param value The content to add.
* @return This builder for chaining.
*/
public Builder addContent(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
ensureContentIsMutable();
if (value == null) { throw new NullPointerException(); }
ensureContentIsMutable();
content_.add(value);
bitField0_ |= 0x00000001;
onChanged();
return this;
}
/**
* <code>repeated bytes content = 1;</code>
* @param values The content to add.
* @return This builder for chaining.
*/
public Builder addAllContent(
java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
ensureContentIsMutable();
super.addAll(values, content_);
com.google.protobuf.AbstractMessageLite.Builder.addAll(
values, content_);
bitField0_ |= 0x00000001;
onChanged();
return this;
}
/**
* <code>repeated bytes content = 1;</code>
* @return This builder for chaining.
*/
public Builder clearContent() {
content_ = java.util.Collections.emptyList();
content_ = emptyList(com.google.protobuf.ByteString.class);
bitField0_ = (bitField0_ & ~0x00000001);
onChanged();
return this;
@@ -462,17 +510,57 @@ public final class UtilProtos {
// @@protoc_insertion_point(builder_scope:signalservice.ByteArrayList)
}
// @@protoc_insertion_point(class_scope:signalservice.ByteArrayList)
private static final org.session.libsignal.protos.UtilProtos.ByteArrayList DEFAULT_INSTANCE;
static {
defaultInstance = new ByteArrayList(true);
defaultInstance.initFields();
DEFAULT_INSTANCE = new org.session.libsignal.protos.UtilProtos.ByteArrayList();
}
public static org.session.libsignal.protos.UtilProtos.ByteArrayList getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<ByteArrayList>
PARSER = new com.google.protobuf.AbstractParser<ByteArrayList>() {
@java.lang.Override
public ByteArrayList parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
Builder builder = newBuilder();
try {
builder.mergeFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(builder.buildPartial());
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(e)
.setUnfinishedMessage(builder.buildPartial());
}
return builder.buildPartial();
}
};
public static com.google.protobuf.Parser<ByteArrayList> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<ByteArrayList> getParserForType() {
return PARSER;
}
@java.lang.Override
public org.session.libsignal.protos.UtilProtos.ByteArrayList getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
// @@protoc_insertion_point(class_scope:signalservice.ByteArrayList)
}
private static com.google.protobuf.Descriptors.Descriptor
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_signalservice_ByteArrayList_descriptor;
private static
private static final
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_signalservice_ByteArrayList_fieldAccessorTable;
@@ -480,7 +568,7 @@ public final class UtilProtos {
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
@@ -488,24 +576,17 @@ public final class UtilProtos {
"yList\022\017\n\007content\030\001 \003(\014B*\n\034org.session.li" +
"bsignal.protosB\nUtilProtos"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
public com.google.protobuf.ExtensionRegistry assignDescriptors(
com.google.protobuf.Descriptors.FileDescriptor root) {
descriptor = root;
internal_static_signalservice_ByteArrayList_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_signalservice_ByteArrayList_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_signalservice_ByteArrayList_descriptor,
new java.lang.String[] { "Content", });
return null;
}
};
com.google.protobuf.Descriptors.FileDescriptor
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
}, assigner);
});
internal_static_signalservice_ByteArrayList_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_signalservice_ByteArrayList_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_signalservice_ByteArrayList_descriptor,
new java.lang.String[] { "Content", });
descriptor.resolveAllFeaturesImmutable();
}
// @@protoc_insertion_point(outer_class_scope)

View File

@@ -0,0 +1,28 @@
package org.session.libsignal.utilities
private val VALID_ACCOUNT_ID_PATTERN = Regex("[0-9]{2}[0-9a-fA-F]{64}")
data class AccountId(
val hexString: String,
): Comparable<AccountId> {
constructor(prefix: IdPrefix, publicKey: ByteArray):
this(
hexString = prefix.value + publicKey.toHexString()
)
init {
check(VALID_ACCOUNT_ID_PATTERN.matches(hexString)) {
"Invalid account ID: $hexString"
}
}
val prefix: IdPrefix? get() = IdPrefix.fromValue(hexString)
val pubKeyBytes: ByteArray by lazy {
Hex.fromStringCondensed(hexString.drop(2))
}
override fun compareTo(other: AccountId): Int {
return hexString.compareTo(other.hexString)
}
}

View File

@@ -1,7 +1,7 @@
package org.session.libsignal.utilities
enum class IdPrefix(val value: String) {
STANDARD("05"), BLINDED("15"), UN_BLINDED("00"), BLINDEDV2("25"), GROUP("03");
STANDARD("05"), BLINDED("15"), UN_BLINDED("00"), GROUP("03"), BLINDEDV2("25");
fun isBlinded() = value == BLINDED.value || value == BLINDEDV2.value

View File

@@ -1,7 +1,16 @@
package org.session.libsignal.utilities
object Namespace {
const val ALL = "all"
const val DEFAULT = 0
const val UNAUTHENTICATED_CLOSED_GROUP = -10
fun ALL() = "all"
fun UNAUTHENTICATED_CLOSED_GROUP() = -10
external fun DEFAULT(): Int
external fun USER_PROFILE(): Int
external fun CONTACTS(): Int
external fun CONVO_INFO_VOLATILE(): Int
external fun GROUPS(): Int
external fun CLOSED_GROUP_INFO(): Int
external fun CLOSED_GROUP_MEMBERS(): Int
external fun ENCRYPTION_KEYS(): Int
external fun CLOSED_GROUP_MESSAGES(): Int
external fun REVOKED_GROUP_MESSAGES(): Int
}

View File

@@ -1,9 +1,12 @@
package org.session.libsignal.utilities
import kotlinx.coroutines.delay
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import java.util.*
import kotlin.coroutines.cancellation.CancellationException
@Deprecated("Use retrySuspendAsPromise instead")
fun <V, T : Promise<V, Exception>> retryIfNeeded(maxRetryCount: Int, retryInterval: Long = 1000L, body: () -> T): Promise<V, Exception> {
var retryCount = 0
val deferred = deferred<V, Exception>()
@@ -28,3 +31,21 @@ fun <V, T : Promise<V, Exception>> retryIfNeeded(maxRetryCount: Int, retryInterv
retryIfNeeded()
return deferred.promise
}
suspend fun <T> retryWithUniformInterval(maxRetryCount: Int = 3, retryIntervalMills: Long = 1000L, body: suspend () -> T): T {
var retryCount = 0
while (true) {
try {
return body()
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
if (retryCount == maxRetryCount) {
throw e
} else {
retryCount += 1
delay(retryIntervalMills)
}
}
}
}

View File

@@ -30,7 +30,9 @@ class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val v
Batch("batch"),
Sequence("sequence"),
Expire("expire"),
GetExpiries("get_expiries")
GetExpiries("get_expiries"),
RevokeSubAccount("revoke_subaccount"),
UnrevokeSubAccount("unrevoke_subaccount"),
}
data class KeySet(val ed25519Key: String, val x25519Key: String)