Enable kotlin for libsignal-service project and convert SignalServiceDataMessage.
This commit is contained in:
parent
bcd0360dd0
commit
fc2b67aa0f
8 changed files with 511 additions and 803 deletions
|
@ -79,6 +79,7 @@ task qa {
|
|||
':Signal-Android:lintPlayProdRelease',
|
||||
'Signal-Android:ktlintCheck',
|
||||
':libsignal-service:test',
|
||||
':libsignal-service:ktlintCheck',
|
||||
':Signal-Android:assemblePlayProdRelease'
|
||||
}
|
||||
|
||||
|
|
|
@ -2292,6 +2292,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="82b53ddde2617cbc5402a5b52eb02bc9eff31f6e2c4b535ad8680a8f8b527fb9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest" name="ktlint" version="0.42.1">
|
||||
<artifact name="ktlint-0.42.1.jar">
|
||||
<sha256 value="aafdc2c1e66746a3c383cd6fb94343f0b7a856c2cfbfd40ff4464c726618a9a7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-0.42.1.module">
|
||||
<sha256 value="f06ba76eb422ad7b7da5ccf048d06d54dc5261ef953393a9043abd4f958c6e29" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest" name="ktlint" version="0.43.2">
|
||||
<artifact name="ktlint-0.43.2.jar">
|
||||
<sha256 value="99ec69ef0628695c24dbbc2cc4b8d7c61a754697d624f5233fc65f43faf2d235" origin="Generated by Gradle"/>
|
||||
|
@ -2300,6 +2308,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="8bbdf6bc56cb12aa8ddea097e9ae862cde9a7c11bc32332dedda73241fb220dc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-core" version="0.42.1">
|
||||
<artifact name="ktlint-core-0.42.1.jar">
|
||||
<sha256 value="a7bd968f4f408521e44a781594a2237df0199aab1ad2942c52bf8ad21e15dea4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-core-0.42.1.module">
|
||||
<sha256 value="6b1efb95887d9172d109df25afc2ef89fa0f09e4b230a47f56c57ad53bfb17ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-core" version="0.43.2">
|
||||
<artifact name="ktlint-core-0.43.2.jar">
|
||||
<sha256 value="401515a76b780a32ef9dfeaf69f77316934c4bb90f339488638311789eca7a1a" origin="Generated by Gradle"/>
|
||||
|
@ -2308,6 +2324,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="aa276dfa9dcfab2f0459c81e7f903712058230d0908d545cc4bc8674273a51d7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-baseline" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-baseline-0.42.1.jar">
|
||||
<sha256 value="6a6de6072e3a8b7b96ef9b8486985889977500761ff37f0467689af9fcbc2843" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-baseline-0.42.1.module">
|
||||
<sha256 value="7476d04c105bfec627889c9f2807f524d26ab316dd57d42f7748db7ffbe8ad4f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-baseline" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-baseline-0.43.2.jar">
|
||||
<sha256 value="733ee7e2cadb321d6597b3501c70c7da73117adaa0c6bc084dfc16c455d68806" origin="Generated by Gradle"/>
|
||||
|
@ -2316,6 +2340,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="3b6466c5813d2deb31a534ae694c41c36b93aec787eb2a8aff162a1288c63533" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-checkstyle" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-checkstyle-0.42.1.jar">
|
||||
<sha256 value="dad0e9626f6cbfec9df70eb8100ba5ea62d421e5c179b9b0e1f69586b0ba1fa6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-checkstyle-0.42.1.module">
|
||||
<sha256 value="017768838d4276018aaebe07a271f0022b5f3e66952bc2f0ceae202da4cb66be" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-checkstyle" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-checkstyle-0.43.2.jar">
|
||||
<sha256 value="becafb4006b9f2e82c99749864a1a8de340ee84ac7271631a68981a44f51e808" origin="Generated by Gradle"/>
|
||||
|
@ -2324,6 +2356,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="3937057372b1cab189647a1e2fa25aa19cb5f72168ca663421b9e250b4e77d05" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-html" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-html-0.42.1.jar">
|
||||
<sha256 value="ca2c35bf0f436434a6fd8a95a8e47321b62d02cb242a4989c17a5d5b27ecea74" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-html-0.42.1.module">
|
||||
<sha256 value="61fdc1ded68e730b76f269c94d1024484d565df629bfcd5eb45fd4ce05353def" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-html" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-html-0.43.2.jar">
|
||||
<sha256 value="800392e150d3266e72ca53c6ccca3136d4e26445dd9216c6ac6cfc1ba3afafe5" origin="Generated by Gradle"/>
|
||||
|
@ -2332,6 +2372,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="432a6fbb008f1373d3e8bde4ab9d905620ff87fd9f3b50a5654b7717f0a3eaab" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-json" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-json-0.42.1.jar">
|
||||
<sha256 value="d173003331b292dec16bcd5f898546cfcaf4c61c2214136808e21f222a1afd1c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-json-0.42.1.module">
|
||||
<sha256 value="3cd549d0c0bf07182cfe69bf6f1a7643473ec1669d1fca12194b2586f25525ed" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-json" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-json-0.43.2.jar">
|
||||
<sha256 value="9d4a94190d96d671000a06a50c9d1ce111d0dcf629bef8b4f0221a9e3f3699a0" origin="Generated by Gradle"/>
|
||||
|
@ -2340,6 +2388,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="7e7be45882eb7abc67a62d12980018f2bb067d88d9947395a84ad678099b5179" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-plain" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-plain-0.42.1.jar">
|
||||
<sha256 value="df673cd3e88e330e45dc37d58c2789b37b3ed8c3d2edcc4bd52cf719f2a7ee4c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-plain-0.42.1.module">
|
||||
<sha256 value="2afb405369eee884f7dcc1e17a2c5f37b1836d7de7ac506196c5b325584febe0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-plain" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-plain-0.43.2.jar">
|
||||
<sha256 value="1cab63f431ec4e9463df7a767f131ccfa8d76259c01fecc63a4c000063e8ee43" origin="Generated by Gradle"/>
|
||||
|
@ -2348,6 +2404,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="ea97899a3d8b6f8e18c7ae1a5d2f7147f976844f1bd2a51c27b7d8285d90a5ec" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-sarif" version="0.42.1">
|
||||
<artifact name="ktlint-reporter-sarif-0.42.1.jar">
|
||||
<sha256 value="13723186b353287cbdfd60ede056f25dbfb21a7a398be782ab64c9b4ef0ab593" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-reporter-sarif-0.42.1.module">
|
||||
<sha256 value="d480e84b60a747582cfe4e4b1608806511bc4cebe7c5c394920e842160c5cf7a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-sarif" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-sarif-0.43.2.jar">
|
||||
<sha256 value="ed0046aaa4a2e4544197bfdccf88d472ef413a55ad05b6dc8aae41338e9d3748" origin="Generated by Gradle"/>
|
||||
|
@ -2356,6 +2420,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="7ff665bb3f0f36af38b80087c9a0067a9dff3c89b6a2c1c78a1f6e1455eb1d09" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-experimental" version="0.42.1">
|
||||
<artifact name="ktlint-ruleset-experimental-0.42.1.jar">
|
||||
<sha256 value="9cdc257cba3d0568c553da9ebc90d0d8eda0743f150e2f0f9d3c60626165840d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-ruleset-experimental-0.42.1.module">
|
||||
<sha256 value="a3f839fb54c9443f60bde4518c69c65b3f5fa807deb4104f472c7ee22d6e2ae5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-experimental" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-experimental-0.43.2.jar">
|
||||
<sha256 value="d89e0edcdca0ae375c090565e323520ab5d424d82fd6ac6290ea986d360f0b11" origin="Generated by Gradle"/>
|
||||
|
@ -2364,6 +2436,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="2d85cd883fe88c4b5429f266de027afca9f9c53a4f49bf14822a4fdf4abeb67a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-standard" version="0.42.1">
|
||||
<artifact name="ktlint-ruleset-standard-0.42.1.jar">
|
||||
<sha256 value="cd3a1f034a554a2e1877aead61a252f1eadc9adfed345edec0ce863dcff4e61c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-ruleset-standard-0.42.1.module">
|
||||
<sha256 value="cfb11e428ae3564249b96ebc08e5170596b3b3790250a9133782681f6b56a036" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-standard" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-standard-0.43.2.jar">
|
||||
<sha256 value="6774dc9d42aa7c7fdd4a7f3732b56fdab99ba78ce0c4eb5159036525657d0014" origin="Generated by Gradle"/>
|
||||
|
@ -2372,6 +2452,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="7ce4e3721b8a6a2e0dd9607e8e5e5b337f5be4f9ed3f6a5dde9ff6d189355303" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-test" version="0.42.1">
|
||||
<artifact name="ktlint-ruleset-test-0.42.1.jar">
|
||||
<sha256 value="0e9001347428a5be6b6b3a8bb322204259805e04b0d4bb6ed427d8a451db5097" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ktlint-ruleset-test-0.42.1.module">
|
||||
<sha256 value="c0c9319daa040e6e3c0f4b8503138f9764dfdfc81672f4d2f7f9824cc4d7db39" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-test" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-test-0.43.2.jar">
|
||||
<sha256 value="7270c4d98b2cda268c25397a02b7dea0ab8cb923958cb3853121e0d9366ce797" origin="Generated by Gradle"/>
|
||||
|
@ -3424,6 +3512,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="95d2fbfd7e987ed607fdc9e6d09d4d87a9782a71dceb91c3200ef4f113f2fb04" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-embeddable" version="1.5.20">
|
||||
<artifact name="kotlin-compiler-embeddable-1.5.20.jar">
|
||||
<sha256 value="11d51087eb70b5abbad6fbf459a4349a0335916588000b5ecd990f01482e38ff" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-compiler-embeddable" version="1.5.31">
|
||||
<artifact name="kotlin-compiler-embeddable-1.5.31.jar">
|
||||
<sha256 value="e39811a9e4c102e779c659eefe90b041c66ce87578c1bfdac07cf504d1551745" origin="Generated by Gradle"/>
|
||||
|
@ -3459,6 +3552,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="c9ba3a944b00ae636634ec346239371c9a049727d9a02a8e2125cd231430b878" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-embeddable" version="1.5.20">
|
||||
<artifact name="kotlin-daemon-embeddable-1.5.20.jar">
|
||||
<sha256 value="5a2e1e6869d130d937b39c668ea6bca758ef8960d168847f6e13aa2a2add424a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-embeddable" version="1.5.31">
|
||||
<artifact name="kotlin-daemon-embeddable-1.5.31.jar">
|
||||
<sha256 value="f61eaf89e5e3848631650b25cdfb66fe8cae0281a054d9d986716000a15ba8d6" origin="Generated by Gradle"/>
|
||||
|
@ -3599,6 +3697,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="dbf19e9cdaa9c3c170f3f6f6ce3922f38dfc1d7fa1cab5b7c23a19da8b5eec5b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.5.20">
|
||||
<artifact name="kotlin-reflect-1.5.20.jar">
|
||||
<sha256 value="fd6782d18bcc17ffa98221a1c34e4a42a7e3e6b4a4b72b474b5c82e14c8bab5a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.5.31">
|
||||
<artifact name="kotlin-reflect-1.5.31.jar">
|
||||
<sha256 value="6e0f5490e6b9649ddd2670534e4d3a03bd283c3358b8eef5d1304fd5f8a5a4fb" origin="Generated by Gradle"/>
|
||||
|
@ -3619,6 +3722,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="afe70b6faf6c23f6fedcb0cf88b07cb1778139f4b744ae13b23eb8bbc4ee09f8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-script-runtime" version="1.5.20">
|
||||
<artifact name="kotlin-script-runtime-1.5.20.jar">
|
||||
<sha256 value="e8a44d7195dc7ee4abb5cda5791e37aacd20b1b76378b13da109dd626536380f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-script-runtime" version="1.5.31">
|
||||
<artifact name="kotlin-script-runtime-1.5.31.jar">
|
||||
<sha256 value="24e450fee7645ed3590981dddccf397c0d9ebb725815c94c4f555cc3db2f9f96" origin="Generated by Gradle"/>
|
||||
|
@ -3699,6 +3807,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="13e9fd3e69dc7230ce0fc873a92a4e5d521d179bcf1bef75a6705baac3bfecba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.5.20">
|
||||
<artifact name="kotlin-stdlib-1.5.20.jar">
|
||||
<sha256 value="80cd79c26aac46d72d782de1ecb326061e93c6e688d994b48627ffd668ba63a8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.5.31">
|
||||
<artifact name="kotlin-stdlib-1.5.31.jar">
|
||||
<sha256 value="4800ceacb2ec0bb9959a087154b8e35318ead1ea4eba32d4bb1b9734222a7e68" origin="Generated by Gradle"/>
|
||||
|
@ -3749,6 +3862,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="e1ff6f55ee9e7591dcc633f7757bac25a7edb1cc7f738b37ec652f10f66a4145" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="1.5.20">
|
||||
<artifact name="kotlin-stdlib-common-1.5.20.jar">
|
||||
<sha256 value="9819529804bf9296e3853acd5ae824df95d8f8c61309e7768b7cae5ca1361d36" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-common" version="1.5.31">
|
||||
<artifact name="kotlin-stdlib-common-1.5.31.jar">
|
||||
<sha256 value="dfa2a18e26b028388ee1968d199bf6f166f737ab7049c25a5e2da614404e22ad" origin="Generated by Gradle"/>
|
||||
|
@ -3784,6 +3902,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="5f801e75ca27d8791c14b07943c608da27620d910a8093022af57f543d5d98b6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.5.20">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.5.20.jar">
|
||||
<sha256 value="b110f6d20204303099af0d5f2c846ac60bc6ae5663ef5f22e726ca4627359d06" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.5.31">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.5.31.jar">
|
||||
<sha256 value="a25bf47353ce899d843cbddee516d621a73473e7fba97f8d0301e7b4aed7c15f" origin="Generated by Gradle"/>
|
||||
|
@ -3824,6 +3947,11 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
|||
<sha256 value="adc43e54757b106e0cd7b3b7aa257dff471b61efdabe067fc02b2f57e2396262" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk8" version="1.5.20">
|
||||
<artifact name="kotlin-stdlib-jdk8-1.5.20.jar">
|
||||
<sha256 value="a7e9cffe569c43eb8f0fe3139978b0943fe92abcc513f7cf04544f2797f8d38a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk8" version="1.5.31">
|
||||
<artifact name="kotlin-stdlib-jdk8-1.5.31.jar">
|
||||
<sha256 value="b548f7767aacf029d2417e47440742bd6d3ebede19b60386e23554ce5c4c5fdc" origin="Generated by Gradle"/>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
apply plugin: 'java-library'
|
||||
apply plugin: 'org.jetbrains.kotlin.jvm'
|
||||
apply plugin: 'java-test-fixtures'
|
||||
apply plugin: 'com.google.protobuf'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'org.jlleitschuh.gradle.ktlint'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
archivesBaseName = "signal-service-java"
|
||||
|
@ -41,6 +43,8 @@ dependencies {
|
|||
|
||||
api libs.rxjava3.rxjava
|
||||
|
||||
implementation libs.kotlin.stdlib.jdk8
|
||||
|
||||
testImplementation testLibs.junit.junit
|
||||
testImplementation testLibs.assertj.core
|
||||
testImplementation testLibs.conscrypt.openjdk.uber
|
||||
|
|
|
@ -721,27 +721,29 @@ public final class SignalServiceContent {
|
|||
metadata.getSenderDevice());
|
||||
}
|
||||
|
||||
return new SignalServiceDataMessage(metadata.getTimestamp(),
|
||||
groupInfoV2,
|
||||
attachments,
|
||||
content.hasBody() ? content.getBody() : null,
|
||||
endSession,
|
||||
content.getExpireTimer(),
|
||||
expirationUpdate,
|
||||
content.hasProfileKey() ? content.getProfileKey().toByteArray() : null,
|
||||
profileKeyUpdate,
|
||||
quote,
|
||||
sharedContacts,
|
||||
previews,
|
||||
mentions,
|
||||
sticker,
|
||||
content.getIsViewOnce(),
|
||||
reaction,
|
||||
remoteDelete,
|
||||
groupCallUpdate,
|
||||
payment,
|
||||
storyContext,
|
||||
giftBadge);
|
||||
return SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(metadata.getTimestamp())
|
||||
.asGroupMessage(groupInfoV2)
|
||||
.withAttachments(attachments)
|
||||
.withBody(content.hasBody() ? content.getBody() : null)
|
||||
.asEndSessionMessage(endSession)
|
||||
.withExpiration(content.getExpireTimer())
|
||||
.asExpirationUpdate(expirationUpdate)
|
||||
.withProfileKey(content.hasProfileKey() ? content.getProfileKey().toByteArray() : null)
|
||||
.asProfileKeyUpdate(profileKeyUpdate)
|
||||
.withQuote(quote)
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews)
|
||||
.withMentions(mentions)
|
||||
.withSticker(sticker)
|
||||
.withViewOnce(content.getIsViewOnce())
|
||||
.withReaction(reaction)
|
||||
.withRemoteDelete(remoteDelete)
|
||||
.withGroupCallUpdate(groupCallUpdate)
|
||||
.withPayment(payment)
|
||||
.withStoryContext(storyContext)
|
||||
.withGiftBadge(giftBadge)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static SignalServiceSyncMessage createSynchronizeMessage(SignalServiceMetadata metadata,
|
||||
|
|
|
@ -1,729 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2016 Open Whisper Systems
|
||||
*
|
||||
* Licensed according to the LICENSE file in this repository.
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.api.messages;
|
||||
|
||||
import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation;
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a decrypted Signal Service data message.
|
||||
*/
|
||||
public class SignalServiceDataMessage {
|
||||
|
||||
private final long timestamp;
|
||||
private final Optional<List<SignalServiceAttachment>> attachments;
|
||||
private final Optional<String> body;
|
||||
private final Optional<SignalServiceGroupV2> group;
|
||||
private final Optional<byte[]> profileKey;
|
||||
private final boolean endSession;
|
||||
private final boolean expirationUpdate;
|
||||
private final int expiresInSeconds;
|
||||
private final boolean profileKeyUpdate;
|
||||
private final Optional<Quote> quote;
|
||||
private final Optional<List<SharedContact>> contacts;
|
||||
private final Optional<List<SignalServicePreview>> previews;
|
||||
private final Optional<List<Mention>> mentions;
|
||||
private final Optional<Sticker> sticker;
|
||||
private final boolean viewOnce;
|
||||
private final Optional<Reaction> reaction;
|
||||
private final Optional<RemoteDelete> remoteDelete;
|
||||
private final Optional<GroupCallUpdate> groupCallUpdate;
|
||||
private final Optional<Payment> payment;
|
||||
private final Optional<StoryContext> storyContext;
|
||||
private final Optional<GiftBadge> giftBadge;
|
||||
|
||||
/**
|
||||
* Construct a SignalServiceDataMessage.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param groupV2 The group information (or null if none).
|
||||
* @param attachments The attachments (or null if none).
|
||||
* @param body The message contents.
|
||||
* @param endSession Flag indicating whether this message should close a session.
|
||||
* @param expiresInSeconds Number of seconds in which the message should disappear after being seen.
|
||||
*/
|
||||
SignalServiceDataMessage(long timestamp,
|
||||
SignalServiceGroupV2 groupV2,
|
||||
List<SignalServiceAttachment> attachments,
|
||||
String body,
|
||||
boolean endSession,
|
||||
int expiresInSeconds,
|
||||
boolean expirationUpdate,
|
||||
byte[] profileKey,
|
||||
boolean profileKeyUpdate,
|
||||
Quote quote,
|
||||
List<SharedContact> sharedContacts,
|
||||
List<SignalServicePreview> previews,
|
||||
List<Mention> mentions,
|
||||
Sticker sticker,
|
||||
boolean viewOnce,
|
||||
Reaction reaction,
|
||||
RemoteDelete remoteDelete,
|
||||
GroupCallUpdate groupCallUpdate,
|
||||
Payment payment,
|
||||
StoryContext storyContext,
|
||||
GiftBadge giftBadge)
|
||||
{
|
||||
this.group = Optional.ofNullable(groupV2);
|
||||
this.timestamp = timestamp;
|
||||
this.body = OptionalUtil.absentIfEmpty(body);
|
||||
this.endSession = endSession;
|
||||
this.expiresInSeconds = expiresInSeconds;
|
||||
this.expirationUpdate = expirationUpdate;
|
||||
this.profileKey = Optional.ofNullable(profileKey);
|
||||
this.profileKeyUpdate = profileKeyUpdate;
|
||||
this.quote = Optional.ofNullable(quote);
|
||||
this.sticker = Optional.ofNullable(sticker);
|
||||
this.viewOnce = viewOnce;
|
||||
this.reaction = Optional.ofNullable(reaction);
|
||||
this.remoteDelete = Optional.ofNullable(remoteDelete);
|
||||
this.groupCallUpdate = Optional.ofNullable(groupCallUpdate);
|
||||
this.payment = Optional.ofNullable(payment);
|
||||
this.storyContext = Optional.ofNullable(storyContext);
|
||||
this.giftBadge = Optional.ofNullable(giftBadge);
|
||||
|
||||
if (attachments != null && !attachments.isEmpty()) {
|
||||
this.attachments = Optional.of(attachments);
|
||||
} else {
|
||||
this.attachments = Optional.empty();
|
||||
}
|
||||
|
||||
if (sharedContacts != null && !sharedContacts.isEmpty()) {
|
||||
this.contacts = Optional.of(sharedContacts);
|
||||
} else {
|
||||
this.contacts = Optional.empty();
|
||||
}
|
||||
|
||||
if (previews != null && !previews.isEmpty()) {
|
||||
this.previews = Optional.of(previews);
|
||||
} else {
|
||||
this.previews = Optional.empty();
|
||||
}
|
||||
|
||||
if (mentions != null && !mentions.isEmpty()) {
|
||||
this.mentions = Optional.of(mentions);
|
||||
} else {
|
||||
this.mentions = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The message timestamp.
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The message attachments (if any).
|
||||
*/
|
||||
public Optional<List<SignalServiceAttachment>> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The message body (if any).
|
||||
*/
|
||||
public Optional<String> getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The message group context (if any).
|
||||
*/
|
||||
public Optional<SignalServiceGroupV2> getGroupContext() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public boolean isEndSession() {
|
||||
return endSession;
|
||||
}
|
||||
|
||||
public boolean isExpirationUpdate() {
|
||||
return expirationUpdate;
|
||||
}
|
||||
|
||||
public boolean isActivatePaymentsRequest() {
|
||||
return getPayment().isPresent() &&
|
||||
getPayment().get().getPaymentActivation().isPresent() &&
|
||||
getPayment().get().getPaymentActivation().get().getType().equals(SignalServiceProtos.DataMessage.Payment.Activation.Type.REQUEST);
|
||||
}
|
||||
|
||||
public boolean isPaymentsActivated() {
|
||||
return getPayment().isPresent() &&
|
||||
getPayment().get().getPaymentActivation().isPresent() &&
|
||||
getPayment().get().getPaymentActivation().get().getType().equals(SignalServiceProtos.DataMessage.Payment.Activation.Type.ACTIVATED);
|
||||
}
|
||||
|
||||
public boolean isProfileKeyUpdate() {
|
||||
return profileKeyUpdate;
|
||||
}
|
||||
|
||||
public boolean isGroupV2Message() {
|
||||
return group.isPresent();
|
||||
}
|
||||
|
||||
public boolean isGroupV2Update() {
|
||||
return group.isPresent() &&
|
||||
group.get().hasSignedGroupChange() &&
|
||||
!hasRenderableContent();
|
||||
}
|
||||
|
||||
public boolean isEmptyGroupV2Message() {
|
||||
return isGroupV2Message() && !isGroupV2Update() && !hasRenderableContent();
|
||||
}
|
||||
|
||||
/** Contains some user data that affects the conversation */
|
||||
public boolean hasRenderableContent() {
|
||||
return attachments.isPresent() ||
|
||||
body.isPresent() ||
|
||||
quote.isPresent() ||
|
||||
contacts.isPresent() ||
|
||||
previews.isPresent() ||
|
||||
mentions.isPresent() ||
|
||||
sticker.isPresent() ||
|
||||
reaction.isPresent() ||
|
||||
remoteDelete.isPresent();
|
||||
}
|
||||
|
||||
public int getExpiresInSeconds() {
|
||||
return expiresInSeconds;
|
||||
}
|
||||
|
||||
public Optional<byte[]> getProfileKey() {
|
||||
return profileKey;
|
||||
}
|
||||
|
||||
public Optional<Quote> getQuote() {
|
||||
return quote;
|
||||
}
|
||||
|
||||
public Optional<List<SharedContact>> getSharedContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public Optional<List<SignalServicePreview>> getPreviews() {
|
||||
return previews;
|
||||
}
|
||||
|
||||
public Optional<List<Mention>> getMentions() {
|
||||
return mentions;
|
||||
}
|
||||
|
||||
public Optional<Sticker> getSticker() {
|
||||
return sticker;
|
||||
}
|
||||
|
||||
public boolean isViewOnce() {
|
||||
return viewOnce;
|
||||
}
|
||||
|
||||
public Optional<Reaction> getReaction() {
|
||||
return reaction;
|
||||
}
|
||||
|
||||
public Optional<RemoteDelete> getRemoteDelete() {
|
||||
return remoteDelete;
|
||||
}
|
||||
|
||||
public Optional<GroupCallUpdate> getGroupCallUpdate() {
|
||||
return groupCallUpdate;
|
||||
}
|
||||
|
||||
public Optional<Payment> getPayment() {
|
||||
return payment;
|
||||
}
|
||||
|
||||
public Optional<StoryContext> getStoryContext() {
|
||||
return storyContext;
|
||||
}
|
||||
|
||||
public Optional<GiftBadge> getGiftBadge() {
|
||||
return giftBadge;
|
||||
}
|
||||
|
||||
public Optional<byte[]> getGroupId() {
|
||||
byte[] groupId = null;
|
||||
|
||||
if (getGroupContext().isPresent() && getGroupContext().isPresent()) {
|
||||
SignalServiceGroupV2 gv2 = getGroupContext().get();
|
||||
groupId = GroupSecretParams.deriveFromMasterKey(gv2.getMasterKey())
|
||||
.getPublicParams()
|
||||
.getGroupIdentifier()
|
||||
.serialize();
|
||||
}
|
||||
|
||||
return Optional.ofNullable(groupId);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private List<SignalServiceAttachment> attachments = new LinkedList<>();
|
||||
private List<SharedContact> sharedContacts = new LinkedList<>();
|
||||
private List<SignalServicePreview> previews = new LinkedList<>();
|
||||
private List<Mention> mentions = new LinkedList<>();
|
||||
|
||||
private long timestamp;
|
||||
private SignalServiceGroupV2 groupV2;
|
||||
private String body;
|
||||
private boolean endSession;
|
||||
private int expiresInSeconds;
|
||||
private boolean expirationUpdate;
|
||||
private byte[] profileKey;
|
||||
private boolean profileKeyUpdate;
|
||||
private Quote quote;
|
||||
private Sticker sticker;
|
||||
private boolean viewOnce;
|
||||
private Reaction reaction;
|
||||
private RemoteDelete remoteDelete;
|
||||
private GroupCallUpdate groupCallUpdate;
|
||||
private Payment payment;
|
||||
private StoryContext storyContext;
|
||||
private GiftBadge giftBadge;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
public Builder withTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder asGroupMessage(SignalServiceGroupV2 group) {
|
||||
this.groupV2 = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAttachment(SignalServiceAttachment attachment) {
|
||||
this.attachments.add(attachment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAttachments(List<SignalServiceAttachment> attachments) {
|
||||
this.attachments.addAll(attachments);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withBody(String body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder asEndSessionMessage() {
|
||||
return asEndSessionMessage(true);
|
||||
}
|
||||
|
||||
public Builder asEndSessionMessage(boolean endSession) {
|
||||
this.endSession = endSession;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder asExpirationUpdate() {
|
||||
return asExpirationUpdate(true);
|
||||
}
|
||||
|
||||
public Builder asExpirationUpdate(boolean expirationUpdate) {
|
||||
this.expirationUpdate = expirationUpdate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withExpiration(int expiresInSeconds) {
|
||||
this.expiresInSeconds = expiresInSeconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withProfileKey(byte[] profileKey) {
|
||||
this.profileKey = profileKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder asProfileKeyUpdate(boolean profileKeyUpdate) {
|
||||
this.profileKeyUpdate = profileKeyUpdate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withQuote(Quote quote) {
|
||||
this.quote = quote;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withSharedContact(SharedContact contact) {
|
||||
this.sharedContacts.add(contact);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withSharedContacts(List<SharedContact> contacts) {
|
||||
this.sharedContacts.addAll(contacts);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPreviews(List<SignalServicePreview> previews) {
|
||||
this.previews.addAll(previews);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withMentions(List<Mention> mentions) {
|
||||
this.mentions.addAll(mentions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withSticker(Sticker sticker) {
|
||||
this.sticker = sticker;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withViewOnce(boolean viewOnce) {
|
||||
this.viewOnce = viewOnce;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withReaction(Reaction reaction) {
|
||||
this.reaction = reaction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withRemoteDelete(RemoteDelete remoteDelete) {
|
||||
this.remoteDelete = remoteDelete;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withGroupCallUpdate(GroupCallUpdate groupCallUpdate) {
|
||||
this.groupCallUpdate = groupCallUpdate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPayment(Payment payment) {
|
||||
this.payment = payment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withStoryContext(StoryContext storyContext) {
|
||||
this.storyContext = storyContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withGiftBadge(GiftBadge giftBadge) {
|
||||
this.giftBadge = giftBadge;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalServiceDataMessage build() {
|
||||
if (timestamp == 0) timestamp = System.currentTimeMillis();
|
||||
return new SignalServiceDataMessage(timestamp, groupV2, attachments, body, endSession,
|
||||
expiresInSeconds, expirationUpdate, profileKey,
|
||||
profileKeyUpdate, quote, sharedContacts, previews,
|
||||
mentions, sticker, viewOnce, reaction, remoteDelete,
|
||||
groupCallUpdate,
|
||||
payment,
|
||||
storyContext,
|
||||
giftBadge);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Quote {
|
||||
private final long id;
|
||||
private final ServiceId author;
|
||||
private final String text;
|
||||
private final List<QuotedAttachment> attachments;
|
||||
private final List<Mention> mentions;
|
||||
private final Type type;
|
||||
|
||||
public Quote(long id,
|
||||
ServiceId author,
|
||||
String text,
|
||||
List<QuotedAttachment> attachments,
|
||||
List<Mention> mentions,
|
||||
Type type)
|
||||
{
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
this.attachments = attachments;
|
||||
this.mentions = mentions;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public ServiceId getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public List<QuotedAttachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
public List<Mention> getMentions() {
|
||||
return mentions;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
NORMAL(SignalServiceProtos.DataMessage.Quote.Type.NORMAL),
|
||||
GIFT_BADGE(SignalServiceProtos.DataMessage.Quote.Type.GIFT_BADGE);
|
||||
|
||||
private final SignalServiceProtos.DataMessage.Quote.Type protoType;
|
||||
|
||||
Type(SignalServiceProtos.DataMessage.Quote.Type protoType) {
|
||||
this.protoType = protoType;
|
||||
}
|
||||
|
||||
public SignalServiceProtos.DataMessage.Quote.Type getProtoType() {
|
||||
return protoType;
|
||||
}
|
||||
|
||||
public static Type fromProto(SignalServiceProtos.DataMessage.Quote.Type protoType) {
|
||||
for (final Type value : values()) {
|
||||
if (value.protoType == protoType) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QuotedAttachment {
|
||||
private final String contentType;
|
||||
private final String fileName;
|
||||
private final SignalServiceAttachment thumbnail;
|
||||
|
||||
public QuotedAttachment(String contentType, String fileName, SignalServiceAttachment thumbnail) {
|
||||
this.contentType = contentType;
|
||||
this.fileName = fileName;
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public SignalServiceAttachment getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Sticker {
|
||||
private final byte[] packId;
|
||||
private final byte[] packKey;
|
||||
private final int stickerId;
|
||||
private final String emoji;
|
||||
private final SignalServiceAttachment attachment;
|
||||
|
||||
public Sticker(byte[] packId, byte[] packKey, int stickerId, String emoji, SignalServiceAttachment attachment) {
|
||||
this.packId = packId;
|
||||
this.packKey = packKey;
|
||||
this.stickerId = stickerId;
|
||||
this.emoji = emoji;
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
public byte[] getPackId() {
|
||||
return packId;
|
||||
}
|
||||
|
||||
public byte[] getPackKey() {
|
||||
return packKey;
|
||||
}
|
||||
|
||||
public int getStickerId() {
|
||||
return stickerId;
|
||||
}
|
||||
|
||||
public String getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
public SignalServiceAttachment getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reaction {
|
||||
private final String emoji;
|
||||
private final boolean remove;
|
||||
private final ServiceId targetAuthor;
|
||||
private final long targetSentTimestamp;
|
||||
|
||||
public Reaction(String emoji, boolean remove, ServiceId targetAuthor, long targetSentTimestamp) {
|
||||
this.emoji = emoji;
|
||||
this.remove = remove;
|
||||
this.targetAuthor = targetAuthor;
|
||||
this.targetSentTimestamp = targetSentTimestamp;
|
||||
}
|
||||
|
||||
public String getEmoji() {
|
||||
return emoji;
|
||||
}
|
||||
|
||||
public boolean isRemove() {
|
||||
return remove;
|
||||
}
|
||||
|
||||
public ServiceId getTargetAuthor() {
|
||||
return targetAuthor;
|
||||
}
|
||||
|
||||
public long getTargetSentTimestamp() {
|
||||
return targetSentTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RemoteDelete {
|
||||
private final long targetSentTimestamp;
|
||||
|
||||
public RemoteDelete(long targetSentTimestamp) {
|
||||
this.targetSentTimestamp = targetSentTimestamp;
|
||||
}
|
||||
|
||||
public long getTargetSentTimestamp() {
|
||||
return targetSentTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Mention {
|
||||
private final ServiceId serviceId;
|
||||
private final int start;
|
||||
private final int length;
|
||||
|
||||
public Mention(ServiceId serviceId, int start, int length) {
|
||||
this.serviceId = serviceId;
|
||||
this.start = start;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public ServiceId getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GroupCallUpdate {
|
||||
private final String eraId;
|
||||
|
||||
public GroupCallUpdate(String eraId) {
|
||||
this.eraId = eraId;
|
||||
}
|
||||
|
||||
public String getEraId() {
|
||||
return eraId;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PaymentNotification {
|
||||
|
||||
private final byte[] receipt;
|
||||
private final String note;
|
||||
|
||||
public PaymentNotification(byte[] receipt, String note) {
|
||||
this.receipt = receipt;
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public byte[] getReceipt() {
|
||||
return receipt;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PaymentActivation {
|
||||
private final SignalServiceProtos.DataMessage.Payment.Activation.Type type;
|
||||
|
||||
public PaymentActivation(SignalServiceProtos.DataMessage.Payment.Activation.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public SignalServiceProtos.DataMessage.Payment.Activation.Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Payment {
|
||||
private final Optional<PaymentNotification> paymentNotification;
|
||||
private final Optional<PaymentActivation> paymentActivation;
|
||||
|
||||
public Payment(PaymentNotification paymentNotification, PaymentActivation paymentActivation) {
|
||||
this.paymentNotification = Optional.ofNullable(paymentNotification);
|
||||
this.paymentActivation = Optional.ofNullable(paymentActivation);
|
||||
}
|
||||
|
||||
public Optional<PaymentNotification> getPaymentNotification() {
|
||||
return paymentNotification;
|
||||
}
|
||||
|
||||
public Optional<PaymentActivation> getPaymentActivation() {
|
||||
return paymentActivation;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StoryContext {
|
||||
private final ServiceId authorServiceId;
|
||||
private final long sentTimestamp;
|
||||
|
||||
public StoryContext(ServiceId authorServiceId, long sentTimestamp) {
|
||||
this.authorServiceId = authorServiceId;
|
||||
this.sentTimestamp = sentTimestamp;
|
||||
}
|
||||
|
||||
public ServiceId getAuthorServiceId() {
|
||||
return authorServiceId;
|
||||
}
|
||||
|
||||
public long getSentTimestamp() {
|
||||
return sentTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GiftBadge {
|
||||
private final ReceiptCredentialPresentation receiptCredentialPresentation;
|
||||
|
||||
public GiftBadge(ReceiptCredentialPresentation receiptCredentialPresentation) {
|
||||
this.receiptCredentialPresentation = receiptCredentialPresentation;
|
||||
}
|
||||
|
||||
public ReceiptCredentialPresentation getReceiptCredentialPresentation() {
|
||||
return receiptCredentialPresentation;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2016 Open Whisper Systems
|
||||
*
|
||||
* Licensed according to the LICENSE file in this repository.
|
||||
*/
|
||||
package org.whispersystems.signalservice.api.messages
|
||||
|
||||
import org.signal.libsignal.zkgroup.groups.GroupSecretParams
|
||||
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil.asOptional
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil.emptyIfStringEmpty
|
||||
import java.util.LinkedList
|
||||
import java.util.Optional
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage.Payment as PaymentProto
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage.Quote as QuoteProto
|
||||
|
||||
/**
|
||||
* Represents a decrypted Signal Service data message.
|
||||
*
|
||||
* @param timestamp The sent timestamp.
|
||||
* @param groupContext The group information (or null if none).
|
||||
* @param attachments The attachments (or null if none).
|
||||
* @param body The message contents.
|
||||
* @param isEndSession Flag indicating whether this message should close a session.
|
||||
* @param expiresInSeconds Number of seconds in which the message should disappear after being seen.
|
||||
*/
|
||||
class SignalServiceDataMessage private constructor(
|
||||
val timestamp: Long,
|
||||
val groupContext: Optional<SignalServiceGroupV2>,
|
||||
val attachments: Optional<List<SignalServiceAttachment>>,
|
||||
val body: Optional<String>,
|
||||
val isEndSession: Boolean,
|
||||
val expiresInSeconds: Int,
|
||||
val isExpirationUpdate: Boolean,
|
||||
val profileKey: Optional<ByteArray>,
|
||||
val isProfileKeyUpdate: Boolean,
|
||||
val quote: Optional<Quote>,
|
||||
val sharedContacts: Optional<List<SharedContact>>,
|
||||
val previews: Optional<List<SignalServicePreview>>,
|
||||
val mentions: Optional<List<Mention>>,
|
||||
val sticker: Optional<Sticker>,
|
||||
val isViewOnce: Boolean,
|
||||
val reaction: Optional<Reaction>,
|
||||
val remoteDelete: Optional<RemoteDelete>,
|
||||
val groupCallUpdate: Optional<GroupCallUpdate>,
|
||||
val payment: Optional<Payment>,
|
||||
val storyContext: Optional<StoryContext>,
|
||||
val giftBadge: Optional<GiftBadge>
|
||||
) {
|
||||
val isActivatePaymentsRequest: Boolean = payment.map { it.isActivationRequest }.orElse(false)
|
||||
val isPaymentsActivated: Boolean = payment.map { it.isActivation }.orElse(false)
|
||||
|
||||
val groupId: Optional<ByteArray> = groupContext.map { GroupSecretParams.deriveFromMasterKey(it.masterKey).publicParams.groupIdentifier.serialize() }
|
||||
val isGroupV2Message: Boolean = groupContext.isPresent
|
||||
|
||||
/** Contains some user data that affects the conversation */
|
||||
private val hasRenderableContent: Boolean =
|
||||
this.attachments.isPresent ||
|
||||
this.body.isPresent ||
|
||||
this.quote.isPresent ||
|
||||
this.sharedContacts.isPresent ||
|
||||
this.previews.isPresent ||
|
||||
this.mentions.isPresent ||
|
||||
this.sticker.isPresent ||
|
||||
this.reaction.isPresent ||
|
||||
this.remoteDelete.isPresent
|
||||
|
||||
val isGroupV2Update: Boolean = groupContext.isPresent && groupContext.get().hasSignedGroupChange() && !hasRenderableContent
|
||||
val isEmptyGroupV2Message: Boolean = isGroupV2Message && !isGroupV2Update && !hasRenderableContent
|
||||
|
||||
class Builder {
|
||||
private var timestamp: Long = 0
|
||||
private var groupV2: SignalServiceGroupV2? = null
|
||||
private val attachments: MutableList<SignalServiceAttachment> = LinkedList<SignalServiceAttachment>()
|
||||
private var body: String? = null
|
||||
private var endSession: Boolean = false
|
||||
private var expiresInSeconds: Int = 0
|
||||
private var expirationUpdate: Boolean = false
|
||||
private var profileKey: ByteArray? = null
|
||||
private var profileKeyUpdate: Boolean = false
|
||||
private var quote: Quote? = null
|
||||
private val sharedContacts: MutableList<SharedContact> = LinkedList<SharedContact>()
|
||||
private val previews: MutableList<SignalServicePreview> = LinkedList<SignalServicePreview>()
|
||||
private val mentions: MutableList<Mention> = LinkedList<Mention>()
|
||||
private var sticker: Sticker? = null
|
||||
private var viewOnce: Boolean = false
|
||||
private var reaction: Reaction? = null
|
||||
private var remoteDelete: RemoteDelete? = null
|
||||
private var groupCallUpdate: GroupCallUpdate? = null
|
||||
private var payment: Payment? = null
|
||||
private var storyContext: StoryContext? = null
|
||||
private var giftBadge: GiftBadge? = null
|
||||
|
||||
fun withTimestamp(timestamp: Long): Builder {
|
||||
this.timestamp = timestamp
|
||||
return this
|
||||
}
|
||||
|
||||
fun asGroupMessage(group: SignalServiceGroupV2?): Builder {
|
||||
groupV2 = group
|
||||
return this
|
||||
}
|
||||
|
||||
fun withAttachment(attachment: SignalServiceAttachment?): Builder {
|
||||
attachment?.let { attachments.add(attachment) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withAttachments(attachments: List<SignalServiceAttachment>?): Builder {
|
||||
attachments?.let { this.attachments.addAll(attachments) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withBody(body: String?): Builder {
|
||||
this.body = body
|
||||
return this
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun asEndSessionMessage(endSession: Boolean = true): Builder {
|
||||
this.endSession = endSession
|
||||
return this
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun asExpirationUpdate(expirationUpdate: Boolean = true): Builder {
|
||||
this.expirationUpdate = expirationUpdate
|
||||
return this
|
||||
}
|
||||
|
||||
fun withExpiration(expiresInSeconds: Int): Builder {
|
||||
this.expiresInSeconds = expiresInSeconds
|
||||
return this
|
||||
}
|
||||
|
||||
fun withProfileKey(profileKey: ByteArray?): Builder {
|
||||
this.profileKey = profileKey
|
||||
return this
|
||||
}
|
||||
|
||||
fun asProfileKeyUpdate(profileKeyUpdate: Boolean): Builder {
|
||||
this.profileKeyUpdate = profileKeyUpdate
|
||||
return this
|
||||
}
|
||||
|
||||
fun withQuote(quote: Quote?): Builder {
|
||||
this.quote = quote
|
||||
return this
|
||||
}
|
||||
|
||||
fun withSharedContact(contact: SharedContact?): Builder {
|
||||
contact?.let { sharedContacts.add(contact) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withSharedContacts(contacts: List<SharedContact>?): Builder {
|
||||
contacts?.let { sharedContacts.addAll(contacts) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withPreviews(previews: List<SignalServicePreview>?): Builder {
|
||||
previews?.let { this.previews.addAll(previews) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withMentions(mentions: List<Mention>?): Builder {
|
||||
mentions?.let { this.mentions.addAll(mentions) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun withSticker(sticker: Sticker?): Builder {
|
||||
this.sticker = sticker
|
||||
return this
|
||||
}
|
||||
|
||||
fun withViewOnce(viewOnce: Boolean): Builder {
|
||||
this.viewOnce = viewOnce
|
||||
return this
|
||||
}
|
||||
|
||||
fun withReaction(reaction: Reaction?): Builder {
|
||||
this.reaction = reaction
|
||||
return this
|
||||
}
|
||||
|
||||
fun withRemoteDelete(remoteDelete: RemoteDelete?): Builder {
|
||||
this.remoteDelete = remoteDelete
|
||||
return this
|
||||
}
|
||||
|
||||
fun withGroupCallUpdate(groupCallUpdate: GroupCallUpdate?): Builder {
|
||||
this.groupCallUpdate = groupCallUpdate
|
||||
return this
|
||||
}
|
||||
|
||||
fun withPayment(payment: Payment?): Builder {
|
||||
this.payment = payment
|
||||
return this
|
||||
}
|
||||
|
||||
fun withStoryContext(storyContext: StoryContext?): Builder {
|
||||
this.storyContext = storyContext
|
||||
return this
|
||||
}
|
||||
|
||||
fun withGiftBadge(giftBadge: GiftBadge?): Builder {
|
||||
this.giftBadge = giftBadge
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): SignalServiceDataMessage {
|
||||
if (timestamp == 0L) {
|
||||
timestamp = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
return SignalServiceDataMessage(
|
||||
timestamp = timestamp,
|
||||
groupContext = groupV2.asOptional(),
|
||||
attachments = attachments.asOptional(),
|
||||
body = body.emptyIfStringEmpty(),
|
||||
isEndSession = endSession,
|
||||
expiresInSeconds = expiresInSeconds,
|
||||
isExpirationUpdate = expirationUpdate,
|
||||
profileKey = profileKey.asOptional(),
|
||||
isProfileKeyUpdate = profileKeyUpdate,
|
||||
quote = quote.asOptional(),
|
||||
sharedContacts = sharedContacts.asOptional(),
|
||||
previews = previews.asOptional(),
|
||||
mentions = mentions.asOptional(),
|
||||
sticker = sticker.asOptional(),
|
||||
isViewOnce = viewOnce,
|
||||
reaction = reaction.asOptional(),
|
||||
remoteDelete = remoteDelete.asOptional(),
|
||||
groupCallUpdate = groupCallUpdate.asOptional(),
|
||||
payment = payment.asOptional(),
|
||||
storyContext = storyContext.asOptional(),
|
||||
giftBadge = giftBadge.asOptional()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Quote(
|
||||
val id: Long,
|
||||
val author: ServiceId,
|
||||
val text: String,
|
||||
val attachments: List<QuotedAttachment>,
|
||||
val mentions: List<Mention>,
|
||||
val type: Type
|
||||
) {
|
||||
enum class Type(val protoType: QuoteProto.Type) {
|
||||
NORMAL(QuoteProto.Type.NORMAL),
|
||||
GIFT_BADGE(QuoteProto.Type.GIFT_BADGE);
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromProto(protoType: QuoteProto.Type): Type {
|
||||
return values().firstOrNull { it.protoType == protoType } ?: NORMAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class QuotedAttachment(val contentType: String, val fileName: String, val thumbnail: SignalServiceAttachment)
|
||||
}
|
||||
class Sticker(val packId: ByteArray, val packKey: ByteArray, val stickerId: Int, val emoji: String, val attachment: SignalServiceAttachment)
|
||||
data class Reaction(val emoji: String, val isRemove: Boolean, val targetAuthor: ServiceId, val targetSentTimestamp: Long)
|
||||
data class RemoteDelete(val targetSentTimestamp: Long)
|
||||
data class Mention(val serviceId: ServiceId, val start: Int, val length: Int)
|
||||
data class GroupCallUpdate(val eraId: String)
|
||||
class PaymentNotification(val receipt: ByteArray, val note: String)
|
||||
data class PaymentActivation(val type: PaymentProto.Activation.Type)
|
||||
class Payment(paymentNotification: PaymentNotification?, paymentActivation: PaymentActivation?) {
|
||||
val paymentNotification: Optional<PaymentNotification> = Optional.ofNullable(paymentNotification)
|
||||
val paymentActivation: Optional<PaymentActivation> = Optional.ofNullable(paymentActivation)
|
||||
val isActivationRequest: Boolean = paymentActivation != null && paymentActivation.type == PaymentProto.Activation.Type.REQUEST
|
||||
val isActivation: Boolean = paymentActivation != null && paymentActivation.type == PaymentProto.Activation.Type.ACTIVATED
|
||||
}
|
||||
data class StoryContext(val authorServiceId: ServiceId, val sentTimestamp: Long)
|
||||
data class GiftBadge(val receiptCredentialPresentation: ReceiptCredentialPresentation)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newBuilder(): Builder {
|
||||
return Builder()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package org.whispersystems.signalservice.api.util;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class OptionalUtil {
|
||||
|
||||
private OptionalUtil() { }
|
||||
|
||||
@SafeVarargs
|
||||
public static <E> Optional<E> or(Optional<E>... optionals) {
|
||||
return Arrays.stream(optionals)
|
||||
.filter(Optional::isPresent)
|
||||
.findFirst()
|
||||
.orElse(Optional.empty());
|
||||
}
|
||||
|
||||
public static boolean byteArrayEquals(Optional<byte[]> a, Optional<byte[]> b) {
|
||||
if (a.isPresent() != b.isPresent()) {
|
||||
return false;
|
||||
} else if (a.isPresent()) {
|
||||
return Arrays.equals(a.get(), b.get());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static int byteArrayHashCode(Optional<byte[]> bytes) {
|
||||
if (bytes.isPresent()) {
|
||||
return Arrays.hashCode(bytes.get());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<String> absentIfEmpty(String value) {
|
||||
if (value == null || value.length() == 0) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<byte[]> absentIfEmpty(ByteString value) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(value.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.whispersystems.signalservice.api.util
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import java.util.Optional
|
||||
|
||||
object OptionalUtil {
|
||||
@JvmStatic
|
||||
@SafeVarargs
|
||||
fun <E : Any> or(vararg optionals: Optional<E>): Optional<E> {
|
||||
return optionals.firstOrNull { it.isPresent } ?: Optional.empty()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun byteArrayEquals(a: Optional<ByteArray>, b: Optional<ByteArray>): Boolean {
|
||||
return if (a.isPresent != b.isPresent) {
|
||||
false
|
||||
} else if (a.isPresent) {
|
||||
a.get().contentEquals(b.get())
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun byteArrayHashCode(bytes: Optional<ByteArray>): Int {
|
||||
return if (bytes.isPresent) {
|
||||
bytes.get().contentHashCode()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun absentIfEmpty(value: String?): Optional<String> {
|
||||
return if (value == null || value.isEmpty()) {
|
||||
Optional.empty()
|
||||
} else {
|
||||
Optional.of(value)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun absentIfEmpty(value: ByteString?): Optional<ByteArray> {
|
||||
return if (value == null || value.isEmpty) {
|
||||
Optional.empty()
|
||||
} else {
|
||||
Optional.of(value.toByteArray())
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <E : Any> emptyIfListEmpty(list: List<E>?): Optional<List<E>> {
|
||||
return list.asOptional()
|
||||
}
|
||||
|
||||
fun <E : Any> E?.asOptional(): Optional<E> {
|
||||
return Optional.ofNullable(this)
|
||||
}
|
||||
|
||||
fun <E : Any> List<E>?.asOptional(): Optional<List<E>> {
|
||||
return Optional.ofNullable(this?.takeIf { it.isNotEmpty() })
|
||||
}
|
||||
|
||||
fun String?.emptyIfStringEmpty(): Optional<String> {
|
||||
return absentIfEmpty(this)
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue