Compare commits

...

190 commits
master ... c3

Author SHA1 Message Date
Daniel Gultsch 69866e591c
include mediaType and size in message content 2023-04-19 08:11:39 +02:00
Daniel Gultsch 506e4e1d0c
add index on disco.feature coloum 2023-04-02 09:53:35 +02:00
Daniel Gultsch c858b5346f
clean up references in ChatFragment 2023-04-01 13:59:48 +02:00
Daniel Gultsch e6bf595388
do not restrain embedded message size to outer message size 2023-04-01 11:39:30 +02:00
Daniel Gultsch 9127d68197
render reactions 2023-04-01 11:01:10 +02:00
Daniel Gultsch 340bf45095
do not show fallback in embedded message 2023-03-31 15:36:57 +02:00
Daniel Gultsch acfcde8416
flash background after scrolling to message 2023-03-31 14:14:20 +02:00
Daniel Gultsch 4f654044b4
remove fallback body when rendering 2023-03-30 18:49:04 +02:00
Daniel Gultsch 1b3c7b6a42
render inReplyTo message 2023-03-30 17:47:00 +02:00
Daniel Gultsch a4fe60dece
add image preview to message bubbles 2023-03-30 16:36:16 +02:00
Daniel Gultsch 03cf48f4c1
set avatar invisible when message is null 2023-03-28 23:14:05 +02:00
Daniel Gultsch 4d5445d123
jump to message id 2023-03-28 17:15:35 +02:00
Daniel Gultsch 4bfcf209d7
add date separators 2023-03-27 16:48:35 +02:00
Daniel Gultsch 5b777ef657
display outgoing messages 2023-03-27 14:41:23 +02:00
Daniel Gultsch d52cbb8e8c
fix message comparator 2023-03-27 11:18:29 +02:00
Daniel Gultsch cc07f86bf4
use occupantResource for sender name 2023-03-27 10:41:46 +02:00
Daniel Gultsch f13f15cc91
include occupant resource 2023-03-24 17:51:29 +01:00
Daniel Gultsch 405eeadd95
show sender and display correct encryption icon 2023-03-24 16:11:55 +01:00
Daniel Gultsch 75a4008aee
use resource for consistent color gen (as per modernxmpp) 2023-03-24 15:07:24 +01:00
Daniel Gultsch 4fae8d4e11
show avatars in chat 2023-03-24 12:21:19 +01:00
Daniel Gultsch 805d0db486
show time underneath bubble 2023-03-23 19:08:09 +01:00
Daniel Gultsch 779e6fa61e
rudimentary MessageAdapter 2023-03-23 12:36:59 +01:00
Daniel Gultsch da528776db
include membersOnlyNonAnonymous in chat info 2023-03-23 12:36:33 +01:00
Daniel Gultsch 4fd96e740f
do not start inner transaction for transformation
throwing in an inner transaction will fail the entire transaction even if the
exception is caught in the outer transaction
2023-03-21 22:01:39 +01:00
Daniel Gultsch 4139c11771
add test for multi page result 2023-03-21 18:21:56 +01:00
Daniel Gultsch 1e884ec435
display title in chat fragment 2023-03-21 16:08:05 +01:00
Daniel Gultsch 86d9264ee5
create stub chat fragment 2023-03-21 11:03:50 +01:00
Daniel Gultsch 0f6f9b0001
do not reload chat filter when correct one is already set 2023-03-12 21:18:13 +01:00
Daniel Gultsch e22fcab844
set up back press action for search view 2023-03-12 21:15:13 +01:00
Daniel Gultsch e3f5f6404b
add unit test for archive dao 2023-03-11 23:16:55 +01:00
Daniel Gultsch 7c820f7b32
create stub message contents for encryption failures 2023-03-11 15:56:17 +01:00
Daniel Gultsch ee1c938f2a
look up sender in group chats 2023-03-11 12:10:26 +01:00
Daniel Gultsch d9e8918727
add TODO on how to use RangeAfter 2023-03-11 09:57:51 +01:00
Daniel Gultsch 97f54b6673
bump annotation processors to java 17 2023-03-10 20:03:32 +01:00
Daniel Gultsch 58c5bd0f1b
fetch MAM messages 2023-03-10 20:03:02 +01:00
Daniel Gultsch bb2d077b7c
warn user when lacking internet connnection 2023-03-09 08:14:30 +01:00
Daniel Gultsch b2c348a1df
delete unused disco info on bind 2023-03-08 16:04:18 +01:00
Daniel Gultsch 9a0c2226c1
fix hashCode and equals in account 2023-03-08 12:57:24 +01:00
Daniel Gultsch e971b77539
fix sentAt not always being properly end aligned 2023-03-08 12:17:25 +01:00
Daniel Gultsch c1ef2ac628
submit empty page when changing filter 2023-03-08 09:52:57 +01:00
Daniel Gultsch eb15dc1260
make avatar shape configurable (in code) 2023-03-08 09:52:01 +01:00
Daniel Gultsch 26d856e91f
support chat filters 2023-03-07 20:43:16 +01:00
Daniel Gultsch 9819ef7d05
fetch vcard avatars 2023-03-07 20:05:20 +01:00
Daniel Gultsch 417e801811
unarchive chat when receiving message 2023-03-07 16:13:25 +01:00
Daniel Gultsch 0d134a919e
add avatar image to chat overview item 2023-03-07 16:04:32 +01:00
Daniel Gultsch 260654f171
rudimentary ChatOverviewAdapter 2023-03-06 18:55:02 +01:00
Daniel Gultsch cfaf6162e6
use Java 17 2023-03-05 15:23:46 +01:00
Daniel Gultsch e4fb793769
use transaction for complex model 2023-03-05 15:15:57 +01:00
Daniel Gultsch f1fbf15fea
add HttpUploadManager slot request 2023-03-05 12:09:56 +01:00
Daniel Gultsch f9b3d42a8a
bump agp 2023-03-05 08:38:49 +01:00
Daniel Gultsch a67979adf8
join MultiUserChats on bind 2023-03-05 08:38:12 +01:00
Daniel Gultsch 8be8d7df8f
parse more presence metadata 2023-03-03 12:05:20 +01:00
Daniel Gultsch 2e5e2ff6fe
cache last used service record in DB 2023-03-03 10:14:02 +01:00
Daniel Gultsch 807078b24f
remove unused 'service' from resolver 2023-03-02 19:45:45 +01:00
Daniel Gultsch 4addeaa356
use futures in DNS resolver 2023-03-02 18:44:27 +01:00
Daniel Gultsch 100c735636
use guavas utiltiy equals+hash in resolver result 2023-03-02 16:12:07 +01:00
Daniel Gultsch b2414434dc
fix connection pool not handling removes 2023-03-02 15:43:56 +01:00
Daniel Gultsch 0c4771e2a8
persist certificate trust to disk 2023-03-02 13:44:29 +01:00
Daniel Gultsch 177320d8fe
use scopes for trust 2023-03-02 10:10:12 +01:00
Daniel Gultsch 9c64f9c24c
add UI for certificate trust 2023-03-01 22:05:46 +01:00
Daniel Gultsch 786a6c4c2a
put trust manager framework in place 2023-03-01 22:05:46 +01:00
Daniel Gultsch be6f4300da
include sender id in tests 2023-03-01 22:05:46 +01:00
Daniel Gultsch c2bf9d0413
store senderIdentity in message 2023-03-01 22:05:46 +01:00
Daniel Gultsch 303f14200f
take btbv setting into account when deciding default trust 2023-03-01 22:05:46 +01:00
Daniel Gultsch 1a924d3efd
introduce AppSettings for easier access to preferences 2023-03-01 22:05:45 +01:00
Daniel Gultsch 86ef179c42
use empty message (not key transport) to finish sessions 2023-03-01 22:05:45 +01:00
Daniel Gultsch 5e79dd8b68
left join trust into MessageWithContentReactions 2023-03-01 22:05:45 +01:00
Daniel Gultsch 3c207c28b4
fix drawer layout reacting to back press after rotation 2023-03-01 22:05:45 +01:00
Daniel Gultsch 9c95554782
add trust to identity table 2023-03-01 22:05:45 +01:00
Daniel Gultsch ac2866a682
add automatic session completion 2023-03-01 22:05:45 +01:00
Daniel Gultsch cf17a2ac6d
request device list when encountering unknown device 2023-03-01 22:05:45 +01:00
Daniel Gultsch c3f5273813
close drawer on back press 2023-03-01 22:05:45 +01:00
Daniel Gultsch 6ef2997b5e
add some menu items to setup screen 2023-03-01 22:05:45 +01:00
Daniel Gultsch b8f3472af0
remember chat filter selection across rotations 2023-03-01 22:05:45 +01:00
Daniel Gultsch d54978f593
store connection settings after pressing submit in hostname fragment 2023-03-01 22:05:45 +01:00
Daniel Gultsch 99c11fba17
add stub hostname fragment 2023-03-01 22:05:45 +01:00
Daniel Gultsch cf5910e96e
add 'encryption' and 'identityKey' to message version entity 2023-03-01 22:05:44 +01:00
Daniel Gultsch 677cfcd34c
generate prekeys on cpu executor 2023-03-01 22:05:44 +01:00
Daniel Gultsch 2abcb1b4e4
decrypt omemo messages 2023-03-01 22:05:44 +01:00
Daniel Gultsch 49b4f54285
run RtpSessionService during phone calls 2023-03-01 22:05:44 +01:00
Daniel Gultsch 1be1334794
fix memory leak in local video track 2023-03-01 22:05:44 +01:00
Daniel Gultsch 63df518c19
include PartType in CallLog 2023-03-01 22:05:44 +01:00
Daniel Gultsch 63bfbfb40a
create transformation for call log 2023-03-01 22:05:44 +01:00
Daniel Gultsch 44ac7190a9
add notifications and attachments settings screens 2023-03-01 22:05:44 +01:00
Daniel Gultsch bfafad6c65
use icons in security preferences 2023-03-01 22:05:44 +01:00
Daniel Gultsch f5203b082b
calculate switch to video cap on jingle connection startup 2023-03-01 22:05:44 +01:00
Daniel Gultsch eafa93d132
port jingle rtp connection 2023-03-01 22:05:44 +01:00
Daniel Gultsch d7ab5e1a4b
add http upload manager 2023-03-01 22:05:44 +01:00
Daniel Gultsch d136928322
redirect from main to setup on zero accounts 2023-03-01 22:05:43 +01:00
Daniel Gultsch 0727b0aba6
add 'security' settings 2023-03-01 22:05:43 +01:00
Daniel Gultsch 1f22c5f534
show dynamic colors setting only if available 2023-03-01 22:05:43 +01:00
Daniel Gultsch 7d42da8c34
Android 7+: do not repeat app name in notification 2023-03-01 22:05:43 +01:00
Daniel Gultsch 09b28358ab
add more sample settings 2023-03-01 22:05:43 +01:00
Daniel Gultsch 7567dcff5e
add settings for dynamic colors and dark theme 2023-03-01 22:05:43 +01:00
Daniel Gultsch b80fe9802a
try to fix SearchBar disappearing 2023-03-01 22:05:43 +01:00
Daniel Gultsch fe9b3b8ed9
introduce settings activity 2023-03-01 22:05:43 +01:00
Daniel Gultsch cdcd323c36
stick intent into menu items to know which one was clicked 2023-03-01 22:05:43 +01:00
Daniel Gultsch 867db9d54c
toggle between 'chats' and 'all chats' 2023-03-01 22:05:43 +01:00
Daniel Gultsch 87e33a779f
add stub MainActivity 2023-03-01 22:05:43 +01:00
Daniel Gultsch c105c3420e
store roster groups and bookmark groups in one table 2023-03-01 22:05:43 +01:00
Daniel Gultsch 2212c63810
add basic foreground service and event receiver 2023-03-01 22:05:42 +01:00
Daniel Gultsch d6edea8ddf
avoid accounts being connected multiple times
the pool should not be asked to connect a specific account
it should only be called to do a full reconfiguration
2023-03-01 22:05:42 +01:00
Daniel Gultsch bca253faa4
navigate from start to password to done in Setup 2023-03-01 22:05:42 +01:00
Daniel Gultsch 68e9f25da2
add leak canary 2023-03-01 22:05:42 +01:00
Daniel Gultsch a1e97461f9
do not parse presences from account 2023-03-01 22:05:42 +01:00
Daniel Gultsch bf9b0b18f9
restructure build setup 2023-03-01 22:05:42 +01:00
Daniel Gultsch a09cc126ea
use logging framework in more places 2023-03-01 22:05:42 +01:00
Daniel Gultsch b0010307c0
move Domain Verifier to im.conversations 2023-03-01 22:05:42 +01:00
Daniel Gultsch b5a47000c9
get rid of payment required account state 2023-03-01 22:05:42 +01:00
Daniel Gultsch 7d34c894d0
move SSLSockets helper library into im.conversations package 2023-03-01 22:05:41 +01:00
Daniel Gultsch 5866974eff
wire up SetupViewModel with account repo 2023-03-01 22:05:41 +01:00
Daniel Gultsch 3c42066a7c
get rid of legacy Jid wrapper around jxmpp 2023-03-01 22:05:41 +01:00
Daniel Gultsch 6845380be5
move Element, Tag etc into im.conversations package 2023-03-01 22:05:41 +01:00
Daniel Gultsch eeac779e25
introduce SetupActiviy 2023-03-01 22:05:41 +01:00
Daniel Gultsch 35360fde91
modify XmppConnection to change status to online for unbound cons 2023-03-01 22:05:41 +01:00
Daniel Gultsch a204bf9ec1
add support to retrieve registration 2023-03-01 22:05:41 +01:00
Daniel Gultsch 79eebe68e2
add registration manager (change password + delete account) 2023-03-01 22:05:41 +01:00
Daniel Gultsch 268bef4433
verify we set occupantId on modifcations in group chat 2023-03-01 22:05:41 +01:00
Daniel Gultsch 69d212141b
parse message retractions 2023-03-01 22:05:41 +01:00
Daniel Gultsch 94c8b9ed04
add models for retraction 2023-03-01 22:05:41 +01:00
Daniel Gultsch 2d10a561e4
rename EmbeddedMessage to MessageEmbedded 2023-03-01 22:05:41 +01:00
Daniel Gultsch acb297ac96
store roster groups in DB 2023-03-01 22:05:41 +01:00
Daniel Gultsch 405445afbe
store reference to inReplyTo in database 2023-03-01 22:05:40 +01:00
Daniel Gultsch 56a462833e
in group chats corrections and reactions use different ids. we need to merge stubs 2023-03-01 22:05:40 +01:00
Daniel Gultsch 2728a96ab9
add helper method to count reactions 2023-03-01 22:05:40 +01:00
Daniel Gultsch 7e2bff9d03
test message correction 2023-03-01 22:05:40 +01:00
Daniel Gultsch 4c09b20aa4
support reaction arriving before message 2023-03-01 22:05:40 +01:00
Daniel Gultsch fbb900d4ad
make transformer testable
note that the test will currently fail because the implemtation isnt complete
2023-03-01 22:05:40 +01:00
Daniel Gultsch 6c24cb12dd
store reactions in database 2023-03-01 22:05:40 +01:00
Daniel Gultsch a69b4b14a5
apply message corrections 2023-03-01 22:05:40 +01:00
Daniel Gultsch be3a8dc5e1
insert message states (displayed, received, error) into DB 2023-03-01 22:05:40 +01:00
Daniel Gultsch 9b62861a64
store messages in database 2023-03-01 22:05:40 +01:00
Daniel Gultsch dc371d7017
add models for Displayed and replace 2023-03-01 22:05:40 +01:00
Daniel Gultsch a43160b13d
setup stub transformer 2023-03-01 22:05:40 +01:00
Daniel Gultsch 458f0ef280
parse and validate stanza-id 2023-03-01 22:05:40 +01:00
Daniel Gultsch 3f59dd2688
add model for MAM result + MAM manager 2023-03-01 22:05:39 +01:00
Daniel Gultsch ca0a0c07fc
add models for Chat States + manager 2023-03-01 22:05:39 +01:00
Daniel Gultsch bed6b07bdd
add receipt manager and process receipt requests 2023-03-01 22:05:39 +01:00
Daniel Gultsch 870393df8e
introduce 'PepManager' to unify what pubsub service we talk to 2023-03-01 22:05:39 +01:00
Daniel Gultsch e2ea1f9437
fix device list publication. boomarks add + retract 2023-03-01 22:05:39 +01:00
Daniel Gultsch 3be56b6775
reconfigure node when precondition is not met 2023-03-01 22:05:39 +01:00
Daniel Gultsch 58b1e26367
include publish-options. prepare code for reconfiguration 2023-03-01 22:05:39 +01:00
Daniel Gultsch c077e4e8da
add PubSubManager, AvatarManager and AxolotlManager 2023-03-01 22:05:39 +01:00
Daniel Gultsch f1e1cf9653
respond to software version requests 2023-03-01 22:05:39 +01:00
Daniel Gultsch e073f22ec0
respond to disco#info queries 2023-03-01 22:05:39 +01:00
Daniel Gultsch 57d264d72e
include caps in outgoing presence 2023-03-01 22:05:39 +01:00
Daniel Gultsch 9a855a57ac
add models for Error conditions 2023-03-01 22:05:39 +01:00
Daniel Gultsch ddcab5fb58
add message carbon processing 2023-03-01 22:05:38 +01:00
Daniel Gultsch fe32526de8
parse blocking command pushes 2023-03-01 22:05:38 +01:00
Daniel Gultsch 164ac450d4
introduce CarbonsManager to enable and maintain carbon state 2023-03-01 22:05:38 +01:00
Daniel Gultsch d2794ccf32
create new models for IQ, Message & Presence 2023-03-01 22:05:38 +01:00
Daniel Gultsch f16603742f
make authentications work with null password 2023-03-01 22:05:38 +01:00
Daniel Gultsch f982885d2e
fix regression in ping strategy 2023-03-01 22:05:38 +01:00
Daniel Gultsch 8df97067bb
discover commands on domain 2023-03-01 22:05:38 +01:00
Daniel Gultsch bd343eafa0
add async variant for createAccount 2023-03-01 22:05:38 +01:00
Daniel Gultsch c31fa7ed2b
include parentNode in disco items table 2023-03-01 22:05:38 +01:00
Daniel Gultsch d25cc059c5
add AccountRepository 2023-03-01 22:05:38 +01:00
Daniel Gultsch 359ef330df
get rid of upsert in favor of update and insert
upsert seems to only work with primary keys and not other
unique constraints.
2023-03-01 22:05:38 +01:00
Daniel Gultsch de06bfb8f0
retrieve Extensions not Elements from extension map 2023-03-01 22:05:38 +01:00
Daniel Gultsch 1e6aed759b
check caps hash after retrieving them 2023-03-01 22:05:37 +01:00
Daniel Gultsch 1a09b3ed05
use empty string instead of null for 'no node' and 'no resource' 2023-03-01 22:05:37 +01:00
Daniel Gultsch 90e613f94e
fix parsing error in Legacy caps 2023-03-01 22:05:37 +01:00
Daniel Gultsch 09db9e574b
do not return NodeHash if no valid hash mech is found 2023-03-01 22:05:37 +01:00
Daniel Gultsch f5faa8fc4d
try with resources in CredentialStore 2023-03-01 22:05:37 +01:00
Daniel Gultsch bfa61d56af
use annotations processor to create extensions 2023-03-01 22:05:37 +01:00
Daniel Gultsch da65960fd1
reconnect account after adding to ConnectionPool 2023-03-01 22:05:37 +01:00
Daniel Gultsch 6983aedddc
add IDs.seed() method for random account seed 2023-03-01 22:05:37 +01:00
Daniel Gultsch 27952c00ed
flush credential store file 2023-03-01 22:05:37 +01:00
Daniel Gultsch 944c48e00b
store presence in DB 2023-03-01 22:05:37 +01:00
Daniel Gultsch 26bff8028a
check disco feature on entity 2023-03-01 22:05:37 +01:00
Daniel Gultsch 873644f528
remove XmppConnection.Features helper class in favor of DiscoManager 2023-03-01 22:05:37 +01:00
Daniel Gultsch 199a1cdc64
add code to fetch items and their infos in one go 2023-03-01 22:05:37 +01:00
Daniel Gultsch 43a82e504b
parse caps from presence 2023-03-01 22:05:37 +01:00
Daniel Gultsch a2b21d97eb
use dedicated hash object instead of byte[] for caps
this way we can store the algo alongside the object
2023-03-01 22:05:36 +01:00
Daniel Gultsch 6458c6e9f9
store disco features after fetching them 2023-03-01 22:05:36 +01:00
Daniel Gultsch 1b438117a3
add Entity Caps 2 hash calculation 2023-03-01 22:05:36 +01:00
Daniel Gultsch 78af8cbd87
migrate entity caps 1 calculation to new code 2023-03-01 22:05:36 +01:00
Daniel Gultsch 482dc8cfe9
insert disco items into db 2023-03-01 22:05:36 +01:00
Daniel Gultsch 3e9029dc8f
bump targetSdk; bump room version 2023-03-01 22:05:36 +01:00
Daniel Gultsch 38c612d35d
make name+namespace assignment in xmpp less error prone 2023-03-01 22:05:36 +01:00
Daniel Gultsch 07c1669813
introduce Manager concept to bundle functionality like roster, blocking, … 2023-03-01 22:05:36 +01:00
Daniel Gultsch 20962554a4
retrieve blocklist on bind 2023-03-01 22:05:36 +01:00
Daniel Gultsch 6b232f7a5a
fetch roster. process result 2023-03-01 22:05:36 +01:00
Daniel Gultsch 9e7bbcc272
offer alternative access to elements and children
instead of Element.findChild(name, namespace) we can now use
Element.getExtension(Extension.class) for registered extensions
2023-03-01 22:05:36 +01:00
Daniel Gultsch 49bf92f7ca
wire up MessageAckProcessor with DB 2023-03-01 22:05:35 +01:00
Daniel Gultsch 2c32f9738c
homogenize ID generation 2023-03-01 22:05:35 +01:00
Daniel Gultsch 7ee3e07946
Introduce XmppConnection v3
The various layers of the app are too intertwined to refactor them in place.

The C3 refactor is going to create a parallel architecture for all classes that
have too strong of a connection to other parts of the app.

This commit introduces XmppConnection v3 that keeps a lot of the logic of the
privous XmppConnection but cuts ties to XmppConnectionService and the very
stateful `entites.Account`. The latter is replaced by a lightweight immutable
account model.

The reconnection logic has been kept but was moved from XmppConnectionService
to a singleton ConnectionPool.
2023-03-01 22:05:35 +01:00
Daniel Gultsch 94dde9f433
initial set of Room entities 2023-03-01 22:05:35 +01:00
Daniel Gultsch 5d79cfbf0d
add spotless plugin 2023-03-01 22:05:35 +01:00
Daniel Gultsch 80d97c3fcc
bump version to 3.0.0-alpha. modify appId 2023-03-01 22:05:35 +01:00
2376 changed files with 34194 additions and 84282 deletions

View file

@ -0,0 +1,15 @@
apply plugin: "java-library"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
implementation project(':annotation')
annotationProcessor 'com.google.auto.service:auto-service:1.0.1'
api 'com.google.auto.service:auto-service-annotations:1.0.1'
implementation 'com.google.guava:guava:31.1-jre'
}

View file

@ -0,0 +1,160 @@
package im.conversations.android.annotation.processor;
import com.google.auto.service.AutoService;
import com.google.common.base.CaseFormat;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.annotation.XmlPackage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_17)
@SupportedAnnotationTypes("im.conversations.android.annotation.XmlElement")
public class XmlElementProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
final Set<? extends Element> elements =
roundEnvironment.getElementsAnnotatedWith(XmlElement.class);
final ImmutableMap.Builder<Id, String> builder = ImmutableMap.builder();
for (final Element element : elements) {
if (element instanceof final TypeElement typeElement) {
final Id id = of(typeElement);
builder.put(id, typeElement.getQualifiedName().toString());
}
}
final ImmutableMap<Id, String> maps = builder.build();
if (maps.isEmpty()) {
return false;
}
final JavaFileObject extensionFile;
try {
extensionFile =
processingEnv
.getFiler()
.createSourceFile("im.conversations.android.xmpp.Extensions");
} catch (final IOException e) {
throw new RuntimeException(e);
}
try (final PrintWriter out = new PrintWriter(extensionFile.openWriter())) {
out.println("package im.conversations.android.xmpp;");
out.println("import com.google.common.collect.BiMap;");
out.println("import com.google.common.collect.ImmutableBiMap;");
out.println("import im.conversations.android.xmpp.ExtensionFactory;");
out.println("import im.conversations.android.xmpp.model.Extension;");
out.print("\n");
out.println("public final class Extensions {");
out.println(
"public static final BiMap<ExtensionFactory.Id, Class<? extends Extension>>"
+ " EXTENSION_CLASS_MAP;");
out.println("static {");
out.println(
"final var builder = new ImmutableBiMap.Builder<ExtensionFactory.Id, Class<?"
+ " extends Extension>>();");
for (final Map.Entry<Id, String> entry : maps.entrySet()) {
Id id = entry.getKey();
String clazz = entry.getValue();
out.format(
"builder.put(new ExtensionFactory.Id(\"%s\",\"%s\"),%s.class);",
id.name, id.namespace, clazz);
out.print("\n");
}
out.println("EXTENSION_CLASS_MAP = builder.build();");
out.println("}");
out.println(" private Extensions() {}");
out.println("}");
// writing generated file to out …
} catch (IOException e) {
throw new RuntimeException(e);
}
return true;
}
private static Id of(final TypeElement typeElement) {
final XmlElement xmlElement = typeElement.getAnnotation(XmlElement.class);
PackageElement packageElement = getPackageElement(typeElement);
XmlPackage xmlPackage =
packageElement == null ? null : packageElement.getAnnotation(XmlPackage.class);
if (xmlElement == null) {
throw new IllegalStateException(
String.format(
"%s is not annotated as @XmlElement",
typeElement.getQualifiedName().toString()));
}
final String packageNamespace = xmlPackage == null ? null : xmlPackage.namespace();
final String elementName = xmlElement.name();
final String elementNamespace = xmlElement.namespace();
final String namespace;
if (!Strings.isNullOrEmpty(elementNamespace)) {
namespace = elementNamespace;
} else if (!Strings.isNullOrEmpty(packageNamespace)) {
namespace = packageNamespace;
} else {
throw new IllegalStateException(
String.format(
"%s does not declare a namespace",
typeElement.getQualifiedName().toString()));
}
final String name;
if (Strings.isNullOrEmpty(elementName)) {
name =
CaseFormat.UPPER_CAMEL.to(
CaseFormat.LOWER_HYPHEN, typeElement.getSimpleName().toString());
} else {
name = elementName;
}
return new Id(name, namespace);
}
private static PackageElement getPackageElement(final TypeElement typeElement) {
final Element parent = typeElement.getEnclosingElement();
if (parent instanceof PackageElement) {
return (PackageElement) parent;
} else {
final Element nextParent = parent.getEnclosingElement();
if (nextParent instanceof PackageElement) {
return (PackageElement) nextParent;
} else {
return null;
}
}
}
public static class Id {
public final String name;
public final String namespace;
public Id(String name, String namespace) {
this.name = name;
this.namespace = namespace;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Id id = (Id) o;
return Objects.equal(name, id.name) && Objects.equal(namespace, id.namespace);
}
@Override
public int hashCode() {
return Objects.hashCode(name, namespace);
}
}
}

6
annotation/build.gradle Normal file
View file

@ -0,0 +1,6 @@
apply plugin: "java-library"
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

View file

@ -0,0 +1,15 @@
package im.conversations.android.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface XmlElement {
String name() default "";
String namespace() default "";
}

View file

@ -0,0 +1,12 @@
package im.conversations.android.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PACKAGE)
public @interface XmlPackage {
String namespace();
}

147
app/build.gradle Normal file
View file

@ -0,0 +1,147 @@
apply plugin: "com.android.application"
apply plugin: "androidx.navigation.safeargs"
apply plugin: "com.diffplug.spotless"
android {
namespace 'im.conversations.android'
compileSdk 33
defaultConfig {
minSdk 23
targetSdk 33
versionCode 1
versionName "3.0.0-alpha"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
buildFeatures {
dataBinding true
}
flavorDimensions "product"
productFlavors {
quicksy {
dimension "product"
applicationId = "im.quicksy.client"
def appName = "Quicksy"
resValue "string", "applicationId", applicationId
resValue "string", "app_name", appName
buildConfigField "String", "APP_NAME", "\"$appName\""
}
conversations {
dimension "product"
applicationId "im.conversations.android"
def appName = "Conversations"
resValue "string", "applicationId", applicationId
resValue "string", "app_name", appName
buildConfigField "String", "APP_NAME", "\"$appName\""
}
}
}
spotless {
java {
target '**/*.java'
googleJavaFormat().aosp().reflowLongStrings()
}
}
dependencies {
implementation project(':annotation')
annotationProcessor project(':annotation-processor')
// make Java 8 API available
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
// Jetpack / AndroidX libraries
implementation "androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.ext.lifecycleVersion"
implementation "androidx.navigation:navigation-fragment:$rootProject.ext.navVersion"
implementation "androidx.navigation:navigation-ui:$rootProject.ext.navVersion"
implementation "androidx.room:room-runtime:$rootProject.ext.roomVersion"
implementation "androidx.room:room-guava:$rootProject.ext.roomVersion"
implementation "androidx.room:room-paging:$rootProject.ext.roomVersion"
annotationProcessor "androidx.room:room-compiler:$rootProject.ext.roomVersion"
implementation "androidx.paging:paging-runtime:$rootProject.ext.pagingVersion"
implementation "androidx.preference:preference:$rootProject.ext.preferenceVersion"
implementation "androidx.security:security-crypto:1.0.0"
// Google material design libraries
implementation "com.google.android.material:material:$rootProject.ext.material"
// LeakCanary to detect memory leaks in debug builds
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
// crypto libraries
implementation 'org.whispersystems:signal-protocol-java:2.6.2'
implementation 'org.conscrypt:conscrypt-android:2.5.2'
implementation 'org.bouncycastle:bcmail-jdk15on:1.64'
// XMPP Address library
implementation 'org.jxmpp:jxmpp-jid:1.0.3'
// WebRTC
implementation 'im.conversations.webrtc:webrtc-android:104.0.0'
// Consistent Color Generation
implementation 'org.hsluv:hsluv:0.2'
// DNS library (XMPP needs to resolve SRV records)
implementation 'de.measite.minidns:minidns-hla:0.2.4'
// Guava
implementation 'com.google.guava:guava:31.1-android'
// HTTP library
implementation "com.squareup.okhttp3:okhttp:4.10.0"
// JSON parser
implementation 'com.google.code.gson:gson:2.10.1'
// logging framework + logging api
implementation 'org.slf4j:slf4j-api:1.7.36'
implementation 'com.github.tony19:logback-android:2.0.1'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.9.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.espressoVersion"
}

21
app/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,214 @@
package im.conversations.android.xmpp;
import static org.hamcrest.Matchers.*;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.StanzaId;
import im.conversations.android.transformer.MessageTransformation;
import im.conversations.android.transformer.Transformer;
import im.conversations.android.xmpp.manager.ArchiveManager;
import im.conversations.android.xmpp.model.jabber.Body;
import im.conversations.android.xmpp.model.stanza.Message;
import java.time.Instant;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class ArchivePagingTest extends BaseTransformationTest {
@Test
public void initialQuery() throws ExecutionException, InterruptedException {
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
final Range range = Iterables.getOnlyElement(ranges);
Assert.assertNull(range.id);
Assert.assertEquals(Range.Order.REVERSE, range.order);
}
@Test
public void queryAfterSingleLiveMessage() throws ExecutionException, InterruptedException {
final var stub = new StubMessage(2);
transformer.transform(stub.messageTransformation(), stub.stanzaId());
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
Assert.assertEquals(2, ranges.size());
MatcherAssert.assertThat(
ranges,
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "2")));
}
@Test
public void twoLiveMessageQueryNoSubmitAndQuery()
throws ExecutionException, InterruptedException {
final var stub2 = new StubMessage(2);
transformer.transform(stub2.messageTransformation(), stub2.stanzaId());
final var stub3 = new StubMessage(3);
transformer.transform(stub3.messageTransformation(), stub3.stanzaId());
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
Assert.assertEquals(2, ranges.size());
MatcherAssert.assertThat(
ranges,
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "3")));
final var stub4 = new StubMessage(4);
transformer.transform(stub4.messageTransformation(), stub4.stanzaId());
final var rangesSecondAttempt = database.archiveDao().resetLivePage(account(), ACCOUNT);
Assert.assertEquals(2, rangesSecondAttempt.size());
MatcherAssert.assertThat(
rangesSecondAttempt,
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "3")));
}
@Test
public void liveMessageQuerySubmitAndQuery(