Compare commits
383 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1043851423 | ||
|
|
9bcbacc3d8 | ||
|
|
c2d7ee6926 | ||
|
|
ceecacb47e | ||
|
|
f4986273e4 | ||
|
|
5f60adbe69 | ||
|
|
db6efeaf3d | ||
|
|
9b98b03971 | ||
|
|
dfbdf30535 | ||
|
|
d567555047 | ||
|
|
7658f6c36c | ||
|
|
51bd2d51c6 | ||
|
|
a00978d96e | ||
|
|
b700529c3b | ||
|
|
4051cf739c | ||
|
|
6031fc9113 | ||
|
|
454fe86dda | ||
|
|
92927ec69b | ||
|
|
9fa587b7e4 | ||
|
|
552361dff4 | ||
|
|
78a25a6186 | ||
|
|
58fcc07578 | ||
|
|
8cd92a400c | ||
|
|
5d207932c9 | ||
|
|
7c147982c4 | ||
|
|
bde1a94122 | ||
|
|
2b66d7485a | ||
|
|
017b902c3c | ||
|
|
357fbfa8aa | ||
|
|
0ce667f4af | ||
|
|
c4d78243c8 | ||
|
|
51e12b2c76 | ||
|
|
4dea1d8aa1 | ||
|
|
89c645dea3 | ||
|
|
cd01d5f0b7 | ||
|
|
8730e28282 | ||
|
|
82046dd55f | ||
|
|
76e30ab09f | ||
|
|
f680256f1d | ||
|
|
da590a3241 | ||
|
|
91f73b473f | ||
|
|
53023517b3 | ||
|
|
7f831e6806 | ||
|
|
77a18111e1 | ||
|
|
2a699a23dd | ||
|
|
5643ffc1a9 | ||
|
|
90207b7dd7 | ||
|
|
5b7f668251 | ||
|
|
798bf3ec3e | ||
|
|
1c77c9d3fb | ||
|
|
dd52d78ee0 | ||
|
|
4b1acca119 | ||
|
|
195fe60927 | ||
|
|
f427f31303 | ||
|
|
fa19ed7ffc | ||
|
|
e5e99d4e03 | ||
|
|
26d1a7ada7 | ||
|
|
5dd11e26e4 | ||
|
|
9877b13c6e | ||
|
|
d7d0fd3622 | ||
|
|
2439506c05 | ||
|
|
6088024f76 | ||
|
|
9decd81cfc | ||
|
|
f27773a4e3 | ||
|
|
8d8c974a19 | ||
|
|
1a3e81dcb0 | ||
|
|
d5f85c0661 | ||
|
|
91458f2702 | ||
|
|
6650ffc2c6 | ||
|
|
ab0102a372 | ||
|
|
a797bbf850 | ||
|
|
3804890265 | ||
|
|
fcdbf93626 | ||
|
|
f1b61f8f7e | ||
|
|
ce582249ec | ||
|
|
b21a72153a | ||
|
|
2a8bd20bb0 | ||
|
|
c30e3cc1b7 | ||
|
|
5fedd81921 | ||
|
|
24069dc42e | ||
|
|
ff15c8417a | ||
|
|
cbf770d3ea | ||
|
|
676ab1ab6f | ||
|
|
9cc47942f2 | ||
|
|
45e6e06c01 | ||
|
|
d2243707b5 | ||
|
|
48cd1c1da0 | ||
|
|
330a5aece2 | ||
|
|
8c4f614d17 | ||
|
|
f40bcb73fa | ||
|
|
905a6f1a6b | ||
|
|
8f78471849 | ||
|
|
82df20190d | ||
|
|
7f6e96a522 | ||
|
|
eded335766 | ||
|
|
7e4736969c | ||
|
|
78940ffc17 | ||
|
|
086883e565 | ||
|
|
e9cdf0368e | ||
|
|
7be273f461 | ||
|
|
e6cbb0073c | ||
|
|
469421fcf3 | ||
|
|
6d6d277277 | ||
|
|
8a5faba985 | ||
|
|
7aadc208e1 | ||
|
|
3c68e29679 | ||
|
|
4756b8d70b | ||
|
|
c2d927029a | ||
|
|
629b96dd20 | ||
|
|
01705459cf | ||
|
|
c449f72786 | ||
|
|
773d6c36dc | ||
|
|
b4bfb67a44 | ||
|
|
3165c854df | ||
|
|
f5cb1b0efa | ||
|
|
179908fba6 | ||
|
|
d6ec4bfbd3 | ||
|
|
237ac9f94a | ||
|
|
66f69854cf | ||
|
|
8f47592fc0 | ||
|
|
3ea7bf77e0 | ||
|
|
2b67b1c44f | ||
|
|
ebccc6db30 | ||
|
|
98d9b12438 | ||
|
|
5db8463c70 | ||
|
|
813252989b | ||
|
|
0319adbce4 | ||
|
|
de584ccb7d | ||
|
|
bd89c7fc39 | ||
|
|
bef4bb40ca | ||
|
|
b57d922cdf | ||
|
|
8c1cc03c6f | ||
|
|
f0109f3e6b | ||
|
|
ed89f3a78e | ||
|
|
faa6a1d3f0 | ||
|
|
969635d942 | ||
|
|
7665ae1464 | ||
|
|
9c18e3698e | ||
|
|
df406633ff | ||
|
|
d121f9402b | ||
|
|
5310c19b99 | ||
|
|
cd92feb2b7 | ||
|
|
3b603f08ed | ||
|
|
281f062b29 | ||
|
|
b054a7eb76 | ||
|
|
33b9c88ecd | ||
|
|
253d36ae13 | ||
|
|
8306f8ec5b | ||
|
|
69b6d7ef9a | ||
|
|
aeeba3d2df | ||
|
|
dfd2f7baf9 | ||
|
|
5de17a971d | ||
|
|
001896d244 | ||
|
|
1844b128e1 | ||
|
|
08623cc0c4 | ||
|
|
f93a948169 | ||
|
|
76476191be | ||
|
|
d00bb28ee4 | ||
|
|
453e5bede7 | ||
|
|
c7c108bd77 | ||
|
|
fb81574d35 | ||
|
|
e6d3de091c | ||
|
|
99b8a6020d | ||
|
|
88b21b6113 | ||
|
|
256ee9b1aa | ||
|
|
e2feaaf74c | ||
|
|
17def87c17 | ||
|
|
d90e9919ae | ||
|
|
38baf17938 | ||
|
|
3f7707985f | ||
|
|
a61072b249 | ||
|
|
80ff64ddd3 | ||
|
|
95c0467bda | ||
|
|
ff88d259fd | ||
|
|
6e747019d4 | ||
|
|
9e7a40a63d | ||
|
|
38eed43046 | ||
|
|
4c76cb682e | ||
|
|
c47adb7482 | ||
|
|
3c2ccef9a8 | ||
|
|
fb0c4757f2 | ||
|
|
b8b9a632b5 | ||
|
|
9b4a13a491 | ||
|
|
1cdd49721d | ||
|
|
8b895738c0 | ||
|
|
6ab3cd3390 | ||
|
|
11c8a726ec | ||
|
|
264447a6d9 | ||
|
|
a7bb2831f8 | ||
|
|
e05586a1c9 | ||
|
|
0e8dedf4d0 | ||
|
|
0e11a1fe3e | ||
|
|
f1ebd2dc81 | ||
|
|
8ea90c8a43 | ||
|
|
6456dcf657 | ||
|
|
bb151c91e9 | ||
|
|
ce6f39ae68 | ||
|
|
58e8ea08c2 | ||
|
|
4dd74d9ab4 | ||
|
|
3ef3a516b3 | ||
|
|
518a81c7fa | ||
|
|
f81325e7ca | ||
|
|
cc847cb229 | ||
|
|
7320a0ef46 | ||
|
|
7c45686440 | ||
|
|
8b5b83e974 | ||
|
|
a4a3861398 | ||
|
|
01bdaaea84 | ||
|
|
1f02fba696 | ||
|
|
aeb9054a63 | ||
|
|
bb33945a93 | ||
|
|
3d2ceef47f | ||
|
|
892e6bd853 | ||
|
|
78e1a407a6 | ||
|
|
48d766ecff | ||
|
|
d6d3226fcd | ||
|
|
ed4944f806 | ||
|
|
eb2dfb3fb6 | ||
|
|
265f71dff3 | ||
|
|
01d1769e4c | ||
|
|
97d099c7f1 | ||
|
|
0a957bc97c | ||
|
|
5df7552506 | ||
|
|
75334abe0f | ||
|
|
8524d20de5 | ||
|
|
495e2e043e | ||
|
|
dec9eb613e | ||
|
|
d6e7030dd0 | ||
|
|
6e43e931b2 | ||
|
|
430a55f89f | ||
|
|
d717aad03d | ||
|
|
efd86ad2fc | ||
|
|
b284835545 | ||
|
|
4dd30f4ec3 | ||
|
|
a48938f3d8 | ||
|
|
01989ad6e7 | ||
|
|
f37f67c6c0 | ||
|
|
36f7c60a99 | ||
|
|
3f067654d9 | ||
|
|
0ce3eab3cd | ||
|
|
b0f7c36cc2 | ||
|
|
966e208be5 | ||
|
|
a80d353e04 | ||
|
|
080fa88bfb | ||
|
|
172e3d129e | ||
|
|
52d5947c0a | ||
|
|
7334ebfce1 | ||
|
|
2c98bbaf7e | ||
|
|
5a91dba56e | ||
|
|
535c5a1574 | ||
|
|
b61c54c0e2 | ||
|
|
5ac5d45fc6 | ||
|
|
79ba929e70 | ||
|
|
3e9146a6f5 | ||
|
|
0c4c280a50 | ||
|
|
ebea499a5a | ||
|
|
d6b39e9f0a | ||
|
|
787eaee6a0 | ||
|
|
5ecb3d8832 | ||
|
|
b2e8666c9f | ||
|
|
8af41e4b2c | ||
|
|
5eaf1000c8 | ||
|
|
4ed6773983 | ||
|
|
0de0441f65 | ||
|
|
9e1b4a9a8c | ||
|
|
bf28b90e89 | ||
|
|
a0a962a94f | ||
|
|
abe0b2ebca | ||
|
|
7b4fe7ff40 | ||
|
|
1ba9793943 | ||
|
|
14d4228e86 | ||
|
|
3d2c51c14b | ||
|
|
72d75e9cd5 | ||
|
|
e125fa6bfb | ||
|
|
57574126bb | ||
|
|
833c81a99e | ||
|
|
5ca17dfe52 | ||
|
|
5e058bb655 | ||
|
|
ce87b50a07 | ||
|
|
2ad14800d1 | ||
|
|
f04a0533cb | ||
|
|
5ae51f844e | ||
|
|
4ce2c6ef73 | ||
|
|
4442f26f53 | ||
|
|
849fce5a89 | ||
|
|
482fce6a25 | ||
|
|
e7e69ab064 | ||
|
|
4b768419da | ||
|
|
2cca01d30f | ||
|
|
e0c69dc485 | ||
|
|
1dd79efdb2 | ||
|
|
dbb3c8def9 | ||
|
|
562185f46d | ||
|
|
f6c7c6de73 | ||
|
|
1ca3a9ca73 | ||
|
|
c76c3f65f2 | ||
|
|
59c27797d6 | ||
|
|
c5c720b1c9 | ||
|
|
caa09c82d0 | ||
|
|
d45f80f25d | ||
|
|
6a248f617a | ||
|
|
2959e05ea7 | ||
|
|
17faf56388 | ||
|
|
f533ad1533 | ||
|
|
25452fefa5 | ||
|
|
9702728c19 | ||
|
|
43f19d14d8 | ||
|
|
467c154ea6 | ||
|
|
d72c742ab6 | ||
|
|
567bf0facc | ||
|
|
d5329d0794 | ||
|
|
ff04e5c5c3 | ||
|
|
e529fbd1bc | ||
|
|
068eaff801 | ||
|
|
e0bb3a48c2 | ||
|
|
f2e4881026 | ||
|
|
b605148ac4 | ||
|
|
2b9126d74b | ||
|
|
206f6d84e7 | ||
|
|
01836b3a7c | ||
|
|
e68691c966 | ||
|
|
957f473e77 | ||
|
|
8a023100ea | ||
|
|
5bfdca509c | ||
|
|
9a837254ec | ||
|
|
3f27769d20 | ||
|
|
4f260c2063 | ||
|
|
75df16e842 | ||
|
|
fce6651e26 | ||
|
|
b06783bc90 | ||
|
|
72a1a9b0ff | ||
|
|
5568a14490 | ||
|
|
378ebb00c4 | ||
|
|
c81f40eb74 | ||
|
|
d97bde3959 | ||
|
|
4d301a4f66 | ||
|
|
9941b2d123 | ||
|
|
089d8a50b2 | ||
|
|
eb8ad5218d | ||
|
|
21b1401fc4 | ||
|
|
58ea9a1f48 | ||
|
|
2bb9578ef9 | ||
|
|
c3b8768570 | ||
|
|
94e3dabc20 | ||
|
|
542a820e22 | ||
|
|
8f7cc52255 | ||
|
|
63888f1c99 | ||
|
|
a588522c9b | ||
|
|
7a2eca3bd5 | ||
|
|
a8ba0dccca | ||
|
|
782c83cc4e | ||
|
|
46e6ae915c | ||
|
|
8a887b65a1 | ||
|
|
08491579dd | ||
|
|
25b01a30be | ||
|
|
48374e6950 | ||
|
|
6496f236ea | ||
|
|
e767434c2b | ||
|
|
bb6507a456 | ||
|
|
c3f9e5d972 | ||
|
|
34d87cf6e1 | ||
|
|
e657a4adf3 | ||
|
|
9594599d60 | ||
|
|
a0c0acb8fc | ||
|
|
0896718e5c | ||
|
|
be4bf27ede | ||
|
|
7253aaaa14 | ||
|
|
72cbe61f6c | ||
|
|
78d3db319c | ||
|
|
c7a6c7ad9e | ||
|
|
8bc183b994 | ||
|
|
ef6e5abc17 | ||
|
|
e96e6e8d18 | ||
|
|
cee33a23ac | ||
|
|
c5de7581ee | ||
|
|
5dc626078f | ||
|
|
9de75b3e1f | ||
|
|
f09bf5b14c | ||
|
|
c7ec3ab837 | ||
|
|
2a7b58bf46 | ||
|
|
7d5b0b1565 | ||
|
|
3620db3a92 | ||
|
|
69cad04875 |
@@ -20,6 +20,7 @@ ktlint_standard_unnecessary-parentheses-before-trailing-lambda = disabled
|
|||||||
ktlint_standard_value-parameter-comment = disabled
|
ktlint_standard_value-parameter-comment = disabled
|
||||||
ktlint_standard_class-signature = disabled
|
ktlint_standard_class-signature = disabled
|
||||||
ktlint_standard_function-expression-body = disabled
|
ktlint_standard_function-expression-body = disabled
|
||||||
|
ktlint_standard_blank-line-between-when-conditions = disabled
|
||||||
|
|
||||||
# Disable ktlint on generated source code, see
|
# Disable ktlint on generated source code, see
|
||||||
# https://github.com/JLLeitschuh/ktlint-gradle/issues/746
|
# https://github.com/JLLeitschuh/ktlint-gradle/issues/746
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -17,7 +17,7 @@ body:
|
|||||||
label: "Guidelines"
|
label: "Guidelines"
|
||||||
description: "Search issues here: https://github.com/signalapp/Signal-Android/issues/?q=is%3Aissue+"
|
description: "Search issues here: https://github.com/signalapp/Signal-Android/issues/?q=is%3Aissue+"
|
||||||
options:
|
options:
|
||||||
- label: I have searched searched open and closed issues for duplicates
|
- label: I have searched open and closed issues for duplicates
|
||||||
required: true
|
required: true
|
||||||
- label: I am submitting a bug report for existing functionality that does not work as intended
|
- label: I am submitting a bug report for existing functionality that does not work as intended
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
27
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
# Automatically keep GitHub Actions SHA-pinned to the latest commit SHAs.
|
||||||
|
# Dependabot will update both the SHA and the inline version comment (e.g. # v6)
|
||||||
|
# while leaving any extra documentation comments intact.
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "monday"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci"
|
||||||
|
groups:
|
||||||
|
actions:
|
||||||
|
patterns:
|
||||||
|
- "actions/*"
|
||||||
|
gradle-actions:
|
||||||
|
patterns:
|
||||||
|
- "gradle/*"
|
||||||
|
peter-evans:
|
||||||
|
patterns:
|
||||||
|
- "peter-evans/*"
|
||||||
|
usefulness:
|
||||||
|
patterns:
|
||||||
|
- "usefulness/*"
|
||||||
23
.github/stale.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
|
||||||
daysUntilStale: 60
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
|
||||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
|
||||||
daysUntilClose: 7
|
|
||||||
|
|
||||||
issues:
|
|
||||||
exemptLabels:
|
|
||||||
- acknowledged
|
|
||||||
|
|
||||||
# Comment to post when marking as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
for your contributions.
|
|
||||||
|
|
||||||
# Comment to post when closing a stale Issue or Pull Request.
|
|
||||||
closeComment: >
|
|
||||||
This issue has been closed due to inactivity.
|
|
||||||
|
|
||||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
|
||||||
limitPerRun: 1
|
|
||||||
12
.github/workflows/android.yml
vendored
@@ -16,26 +16,30 @@ jobs:
|
|||||||
runs-on: ubuntu-latest-8-cores
|
runs-on: ubuntu-latest-8-cores
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
# gh api repos/actions/checkout/commits/v6 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
|
||||||
|
# gh api repos/actions/setup-java/commits/v5 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 17
|
java-version: 17
|
||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/actions/wrapper-validation@v5
|
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6
|
||||||
|
# gh api repos/gradle/actions/commits/v6 --jq '.sha'
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew qa
|
run: ./gradlew qa
|
||||||
|
|
||||||
- name: Archive reports for failed build
|
- name: Archive reports for failed build
|
||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||||
|
# gh api repos/actions/upload-artifact/commits/v7 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
name: reports
|
name: reports
|
||||||
path: '*/build/reports'
|
path: '*/build/reports'
|
||||||
|
|||||||
27
.github/workflows/diffuse.yml
vendored
@@ -16,13 +16,15 @@ jobs:
|
|||||||
runs-on: ubuntu-latest-8-cores
|
runs-on: ubuntu-latest-8-cores
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
# gh api repos/actions/checkout/commits/v6 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
ref: ${{ github.event.pull_request.base.sha }}
|
ref: ${{ github.event.pull_request.base.sha }}
|
||||||
|
|
||||||
- name: set up JDK 17
|
- name: set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
|
||||||
|
# gh api repos/actions/setup-java/commits/v5 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 17
|
java-version: 17
|
||||||
@@ -32,11 +34,13 @@ jobs:
|
|||||||
run: echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
|
run: echo "y" | ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "ndk;${{ env.NDK_VERSION }}"
|
||||||
|
|
||||||
- name: Validate Gradle Wrapper
|
- name: Validate Gradle Wrapper
|
||||||
uses: gradle/actions/wrapper-validation@v5
|
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6
|
||||||
|
# gh api repos/gradle/actions/commits/v6 --jq '.sha'
|
||||||
|
|
||||||
- name: Cache base apk
|
- name: Cache base apk
|
||||||
id: cache-base
|
id: cache-base
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||||
|
# gh api repos/actions/cache/commits/v5 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
path: diffuse-base.apk
|
path: diffuse-base.apk
|
||||||
key: diffuse-${{ github.event.pull_request.base.sha }}
|
key: diffuse-${{ github.event.pull_request.base.sha }}
|
||||||
@@ -49,7 +53,8 @@ jobs:
|
|||||||
if: steps.cache-base.outputs.cache-hit != 'true'
|
if: steps.cache-base.outputs.cache-hit != 'true'
|
||||||
run: mv app/build/outputs/apk/playProd/release/*arm64*.apk diffuse-base.apk
|
run: mv app/build/outputs/apk/playProd/release/*arm64*.apk diffuse-base.apk
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
# gh api repos/actions/checkout/commits/v6 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
clean: 'false'
|
clean: 'false'
|
||||||
@@ -61,18 +66,21 @@ jobs:
|
|||||||
run: mv app/build/outputs/apk/playProd/release/*arm64*.apk diffuse-new.apk
|
run: mv app/build/outputs/apk/playProd/release/*arm64*.apk diffuse-new.apk
|
||||||
|
|
||||||
- id: diffuse
|
- id: diffuse
|
||||||
uses: usefulness/diffuse-action@v1
|
uses: usefulness/diffuse-action@41995fe8ff6be0a8847e63bdc5a4679c704b455c # v1
|
||||||
|
# gh api repos/usefulness/diffuse-action/commits/v1 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
old-file-path: diffuse-base.apk
|
old-file-path: diffuse-base.apk
|
||||||
new-file-path: diffuse-new.apk
|
new-file-path: diffuse-new.apk
|
||||||
|
|
||||||
- uses: peter-evans/find-comment@v2
|
- uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4
|
||||||
|
# gh api repos/peter-evans/find-comment/commits/v4 --jq '.sha'
|
||||||
id: find-comment
|
id: find-comment
|
||||||
with:
|
with:
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
body-includes: Diffuse output
|
body-includes: Diffuse output
|
||||||
|
|
||||||
- uses: peter-evans/create-or-update-comment@v3
|
- uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5
|
||||||
|
# gh api repos/peter-evans/create-or-update-comment/commits/v5 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
body: |
|
body: |
|
||||||
Diffuse output:
|
Diffuse output:
|
||||||
@@ -83,7 +91,8 @@ jobs:
|
|||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||||
|
# gh api repos/actions/upload-artifact/commits/v7 --jq '.sha'
|
||||||
with:
|
with:
|
||||||
name: diffuse-output
|
name: diffuse-output
|
||||||
path: ${{ steps.diffuse.outputs.diff-file }}
|
path: ${{ steps.diffuse.outputs.diff-file }}
|
||||||
|
|||||||
3
.github/workflows/docker.yml
vendored
@@ -11,7 +11,8 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
# gh api repos/actions/checkout/commits/v6 --jq '.sha'
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: |
|
run: |
|
||||||
cd reproducible-builds
|
cd reproducible-builds
|
||||||
|
|||||||
38
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Mark stale issues and PRs
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 * * *' # daily at 02:00 UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
actions: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10
|
||||||
|
# gh api repos/actions/stale/commits/v10 --jq '.sha'
|
||||||
|
with:
|
||||||
|
days-before-stale: 60
|
||||||
|
days-before-close: 7
|
||||||
|
exempt-issue-labels: 'acknowledged'
|
||||||
|
exempt-pr-labels: 'acknowledged'
|
||||||
|
stale-issue-label: 'wontfix'
|
||||||
|
stale-pr-label: 'wontfix'
|
||||||
|
stale-issue-message: >
|
||||||
|
This issue has been automatically marked as stale because it has not had
|
||||||
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
for your contributions!
|
||||||
|
stale-pr-message: >
|
||||||
|
This pull request has been automatically marked as stale because it has not had
|
||||||
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
for your contributions!
|
||||||
|
close-issue-message: >
|
||||||
|
This issue has been closed due to inactivity.
|
||||||
|
close-pr-message: >
|
||||||
|
This pull request has been closed due to inactivity.
|
||||||
|
operations-per-run: 150
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Signal Android
|
# Signal Android
|
||||||
|
|
||||||
Signal is a simple, powerful, and secure messenger that uses your phone's data connection (WiFi/3G/4G/5G) to communicate securely.
|
Signal is a simple, powerful, and secure messenger that uses your phone's data connection (WiFi/4G/5G) to communicate securely.
|
||||||
|
|
||||||
Millions of people use Signal every day for free and instantaneous communication anywhere in the world. Send and receive high-fidelity messages, participate in HD voice/video calls, and explore a growing set of new features that help you stay connected.
|
Millions of people use Signal every day for free and instantaneous communication anywhere in the world. Send and receive high-fidelity messages, participate in HD voice/video calls, and explore a growing set of new features that help you stay connected.
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ The form and manner of this distribution makes it eligible for export under the
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright 2013-2025 Signal Messenger, LLC
|
Copyright 2013 Signal Messenger, LLC
|
||||||
|
|
||||||
Licensed under the GNU AGPLv3: https://www.gnu.org/licenses/agpl-3.0.html
|
Licensed under the GNU AGPLv3: https://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ plugins {
|
|||||||
|
|
||||||
apply(from = "static-ips.gradle.kts")
|
apply(from = "static-ips.gradle.kts")
|
||||||
|
|
||||||
val canonicalVersionCode = 1669
|
val canonicalVersionCode = 1684
|
||||||
val canonicalVersionName = "8.4.0"
|
val canonicalVersionName = "8.9.1"
|
||||||
val currentHotfixVersion = 0
|
val currentHotfixVersion = 0
|
||||||
val maxHotfixVersions = 100
|
val maxHotfixVersions = 100
|
||||||
|
|
||||||
@@ -92,6 +92,7 @@ wire {
|
|||||||
|
|
||||||
protoPath {
|
protoPath {
|
||||||
srcDir("${project.rootDir}/lib/libsignal-service/src/main/protowire")
|
srcDir("${project.rootDir}/lib/libsignal-service/src/main/protowire")
|
||||||
|
srcDir("${project.rootDir}/lib/archive/src/main/protowire")
|
||||||
}
|
}
|
||||||
// Handled by libsignal
|
// Handled by libsignal
|
||||||
prune("signalservice.DecryptionErrorMessage")
|
prune("signalservice.DecryptionErrorMessage")
|
||||||
@@ -594,7 +595,9 @@ dependencies {
|
|||||||
ktlintRuleset(libs.ktlint.twitter.compose)
|
ktlintRuleset(libs.ktlint.twitter.compose)
|
||||||
coreLibraryDesugaring(libs.android.tools.desugar)
|
coreLibraryDesugaring(libs.android.tools.desugar)
|
||||||
|
|
||||||
|
implementation(project(":lib:archive"))
|
||||||
implementation(project(":lib:libsignal-service"))
|
implementation(project(":lib:libsignal-service"))
|
||||||
|
implementation(project(":lib:network"))
|
||||||
implementation(project(":lib:paging"))
|
implementation(project(":lib:paging"))
|
||||||
implementation(project(":core:util"))
|
implementation(project(":core:util"))
|
||||||
implementation(project(":lib:glide"))
|
implementation(project(":lib:glide"))
|
||||||
@@ -613,6 +616,7 @@ dependencies {
|
|||||||
implementation(project(":core:models-jvm"))
|
implementation(project(":core:models-jvm"))
|
||||||
implementation(project(":feature:camera"))
|
implementation(project(":feature:camera"))
|
||||||
implementation(project(":feature:registration"))
|
implementation(project(":feature:registration"))
|
||||||
|
implementation(project(":lib:apng"))
|
||||||
|
|
||||||
implementation(libs.androidx.fragment.ktx)
|
implementation(libs.androidx.fragment.ktx)
|
||||||
implementation(libs.androidx.appcompat) {
|
implementation(libs.androidx.appcompat) {
|
||||||
@@ -675,7 +679,6 @@ dependencies {
|
|||||||
implementation(libs.mobilecoin)
|
implementation(libs.mobilecoin)
|
||||||
implementation(libs.signal.ringrtc)
|
implementation(libs.signal.ringrtc)
|
||||||
implementation(libs.leolin.shortcutbadger)
|
implementation(libs.leolin.shortcutbadger)
|
||||||
implementation(libs.emilsjolander.stickylistheaders)
|
|
||||||
implementation(libs.glide.glide)
|
implementation(libs.glide.glide)
|
||||||
implementation(libs.roundedimageview)
|
implementation(libs.roundedimageview)
|
||||||
implementation(libs.materialish.progress)
|
implementation(libs.materialish.progress)
|
||||||
@@ -686,10 +689,6 @@ dependencies {
|
|||||||
implementation(libs.subsampling.scale.image.view) {
|
implementation(libs.subsampling.scale.image.view) {
|
||||||
exclude(group = "com.android.support", module = "support-annotations")
|
exclude(group = "com.android.support", module = "support-annotations")
|
||||||
}
|
}
|
||||||
implementation(libs.android.tooltips) {
|
|
||||||
exclude(group = "com.android.support", module = "appcompat-v7")
|
|
||||||
}
|
|
||||||
implementation(libs.stream)
|
|
||||||
implementation(libs.lottie)
|
implementation(libs.lottie)
|
||||||
implementation(libs.lottie.compose)
|
implementation(libs.lottie.compose)
|
||||||
implementation(libs.signal.android.database.sqlcipher)
|
implementation(libs.signal.android.database.sqlcipher)
|
||||||
@@ -747,6 +746,7 @@ dependencies {
|
|||||||
testImplementation(testFixtures(project(":lib:libsignal-service")))
|
testImplementation(testFixtures(project(":lib:libsignal-service")))
|
||||||
testImplementation(testLibs.espresso.core)
|
testImplementation(testLibs.espresso.core)
|
||||||
testImplementation(testLibs.kotlinx.coroutines.test)
|
testImplementation(testLibs.kotlinx.coroutines.test)
|
||||||
|
testImplementation(testLibs.sqlite.jdbc)
|
||||||
testImplementation(libs.androidx.compose.ui.test.junit4)
|
testImplementation(libs.androidx.compose.ui.test.junit4)
|
||||||
|
|
||||||
"perfImplementation"(libs.androidx.compose.ui.test.manifest)
|
"perfImplementation"(libs.androidx.compose.ui.test.manifest)
|
||||||
|
|||||||
@@ -26454,61 +26454,6 @@
|
|||||||
column="7"/>
|
column="7"/>
|
||||||
</issue>
|
</issue>
|
||||||
|
|
||||||
<issue
|
|
||||||
id="Recycle"
|
|
||||||
message="This `Cursor` should be freed up after use with `#close()`"
|
|
||||||
errorLine1=" Cursor mmsCursor = db.query("mms", new String[] {"_id"},"
|
|
||||||
errorLine2=" ~~~~~">
|
|
||||||
<location
|
|
||||||
file="src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java"
|
|
||||||
line="298"
|
|
||||||
column="38"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
|
||||||
id="Recycle"
|
|
||||||
message="This `Cursor` should be freed up after use with `#close()`"
|
|
||||||
errorLine1=" Cursor partCursor = db.query("part", new String[] {"_id", "ct", "_data", "encrypted"},"
|
|
||||||
errorLine2=" ~~~~~">
|
|
||||||
<location
|
|
||||||
file="src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java"
|
|
||||||
line="310"
|
|
||||||
column="32"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
|
||||||
id="Recycle"
|
|
||||||
message="This `Cursor` should be freed up after use with `#close()`"
|
|
||||||
errorLine1=" Cursor threadCursor = db.query("thread", new String[] {"_id"}, null, null, null, null, null);"
|
|
||||||
errorLine2=" ~~~~~">
|
|
||||||
<location
|
|
||||||
file="src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java"
|
|
||||||
line="708"
|
|
||||||
column="32"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
|
||||||
id="Recycle"
|
|
||||||
message="This `Cursor` should be freed up after use with `#close()`"
|
|
||||||
errorLine1=" Cursor cursor = db.rawQuery("SELECT DISTINCT date AS date_received, status, " +"
|
|
||||||
errorLine2=" ~~~~~~~~">
|
|
||||||
<location
|
|
||||||
file="src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java"
|
|
||||||
line="713"
|
|
||||||
column="28"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
|
||||||
id="Recycle"
|
|
||||||
message="This `Cursor` should be freed up after use with `#close()`"
|
|
||||||
errorLine1=" cursor = db.query("mms", new String[] {"_id", "network_failures"}, "network_failures IS NOT NULL", null, null, null, null);"
|
|
||||||
errorLine2=" ~~~~~">
|
|
||||||
<location
|
|
||||||
file="src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java"
|
|
||||||
line="1037"
|
|
||||||
column="19"/>
|
|
||||||
</issue>
|
|
||||||
|
|
||||||
<issue
|
<issue
|
||||||
id="ObsoleteSdkInt"
|
id="ObsoleteSdkInt"
|
||||||
message="Unnecessary; SDK_INT is always >= 21"
|
message="Unnecessary; SDK_INT is always >= 21"
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import org.junit.Assert.assertTrue
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
import org.signal.archive.proto.Frame
|
||||||
|
import org.signal.archive.stream.PlainTextBackupReader
|
||||||
import org.signal.core.models.ServiceId
|
import org.signal.core.models.ServiceId
|
||||||
import org.signal.core.util.Base64
|
import org.signal.core.util.Base64
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
@@ -20,8 +22,6 @@ import org.signal.core.util.readFully
|
|||||||
import org.signal.libsignal.messagebackup.ComparableBackup
|
import org.signal.libsignal.messagebackup.ComparableBackup
|
||||||
import org.signal.libsignal.messagebackup.MessageBackup
|
import org.signal.libsignal.messagebackup.MessageBackup
|
||||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
||||||
import org.thoughtcrime.securesms.backup.v2.proto.Frame
|
|
||||||
import org.thoughtcrime.securesms.backup.v2.stream.PlainTextBackupReader
|
|
||||||
import org.thoughtcrime.securesms.database.KeyValueDatabase
|
import org.thoughtcrime.securesms.database.KeyValueDatabase
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
|
|||||||
@@ -358,5 +358,9 @@ class V2ConversationItemShapeTest {
|
|||||||
override fun onToggleVote(poll: PollRecord, pollOption: PollOption, isChecked: Boolean) = Unit
|
override fun onToggleVote(poll: PollRecord, pollOption: PollOption, isChecked: Boolean) = Unit
|
||||||
|
|
||||||
override fun onViewPinnedMessage(messageId: Long) = Unit
|
override fun onViewPinnedMessage(messageId: Long) = Unit
|
||||||
|
|
||||||
|
override fun onExpandEvents(messageId: Long, itemView: View, collapsedSize: Int) = Unit
|
||||||
|
|
||||||
|
override fun onCollapseEvents(messageId: Long, itemView: View, collapsedSize: Int) = Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,541 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.database
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
|
||||||
import net.zetetic.database.sqlcipher.SQLiteOpenHelper
|
|
||||||
import org.junit.Assert.assertTrue
|
|
||||||
import org.junit.Rule
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.signal.core.util.ForeignKeyConstraint
|
|
||||||
import org.signal.core.util.Index
|
|
||||||
import org.signal.core.util.getForeignKeys
|
|
||||||
import org.signal.core.util.getIndexes
|
|
||||||
import org.signal.core.util.readToList
|
|
||||||
import org.signal.core.util.requireNonNullString
|
|
||||||
import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations
|
|
||||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
|
||||||
import org.thoughtcrime.securesms.testing.SignalActivityRule
|
|
||||||
import org.thoughtcrime.securesms.database.SQLiteDatabase as SignalSQLiteDatabase
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A test that guarantees that a freshly-created database looks the same as one that went through the upgrade path.
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class DatabaseConsistencyTest {
|
|
||||||
|
|
||||||
@get:Rule
|
|
||||||
val harness = SignalActivityRule()
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testUpgradeConsistency() {
|
|
||||||
val currentVersionStatements = SignalDatabase.rawDatabase.getAllCreateStatements()
|
|
||||||
val testHelper = InMemoryTestHelper(AppDependencies.application).also {
|
|
||||||
it.onUpgrade(it.writableDatabase, 181, SignalDatabaseMigrations.DATABASE_VERSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
val upgradedStatements = testHelper.readableDatabase.getAllCreateStatements()
|
|
||||||
|
|
||||||
if (currentVersionStatements != upgradedStatements) {
|
|
||||||
var message = "\n"
|
|
||||||
|
|
||||||
val currentByName = currentVersionStatements.associateBy { it.name }
|
|
||||||
val upgradedByName = upgradedStatements.associateBy { it.name }
|
|
||||||
|
|
||||||
if (currentByName.keys != upgradedByName.keys) {
|
|
||||||
val exclusiveToCurrent = currentByName.keys - upgradedByName.keys
|
|
||||||
val exclusiveToUpgrade = upgradedByName.keys - currentByName.keys
|
|
||||||
|
|
||||||
message += "SQL entities exclusive to the newly-created database: $exclusiveToCurrent\n"
|
|
||||||
message += "SQL entities exclusive to the upgraded database: $exclusiveToUpgrade\n\n"
|
|
||||||
} else {
|
|
||||||
for (currentEntry in currentByName) {
|
|
||||||
val upgradedValue: Statement = upgradedByName[currentEntry.key]!!
|
|
||||||
if (upgradedValue.sql != currentEntry.value.sql) {
|
|
||||||
message += "Statement differed:\n"
|
|
||||||
message += "newly-created:\n"
|
|
||||||
message += "${currentEntry.value.sql}\n\n"
|
|
||||||
message += "upgraded:\n"
|
|
||||||
message += "${upgradedValue.sql}\n\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertTrue(message, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testForeignKeyIndexCoverage() {
|
|
||||||
/** We may deem certain indexes non-critical if deletion frequency is low or table size is small. */
|
|
||||||
val ignoredColumns: List<Pair<String, String>> = listOf(
|
|
||||||
StorySendTable.TABLE_NAME to StorySendTable.DISTRIBUTION_ID
|
|
||||||
)
|
|
||||||
|
|
||||||
val foreignKeys: List<ForeignKeyConstraint> = SignalDatabase.rawDatabase.getForeignKeys()
|
|
||||||
val indexesByFirstColumn: List<Index> = SignalDatabase.rawDatabase.getIndexes()
|
|
||||||
|
|
||||||
val notFound: List<Pair<String, String>> = foreignKeys
|
|
||||||
.filterNot { ignoredColumns.contains(it.table to it.column) }
|
|
||||||
.filterNot { foreignKey ->
|
|
||||||
indexesByFirstColumn.hasPrimaryIndexFor(foreignKey.table, foreignKey.column)
|
|
||||||
}
|
|
||||||
.map { it.table to it.column }
|
|
||||||
|
|
||||||
assertTrue("Missing indexes to cover: $notFound", notFound.isEmpty())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun List<Index>.hasPrimaryIndexFor(table: String, column: String): Boolean {
|
|
||||||
return this.any { index -> index.table == table && index.columns[0] == column }
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class Statement(
|
|
||||||
val name: String,
|
|
||||||
val sql: String
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun SQLiteDatabase.getAllCreateStatements(): List<Statement> {
|
|
||||||
return this.rawQuery("SELECT name, sql FROM sqlite_schema WHERE sql NOT NULL AND name != 'sqlite_sequence'")
|
|
||||||
.readToList { cursor ->
|
|
||||||
Statement(
|
|
||||||
name = cursor.requireNonNullString("name"),
|
|
||||||
sql = cursor.requireNonNullString("sql").normalizeSql()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.filterNot { it.name.startsWith("sqlite_stat") }
|
|
||||||
.sortedBy { it.name }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.normalizeSql(): String {
|
|
||||||
return this
|
|
||||||
.split("\n")
|
|
||||||
.map { it.trim() }
|
|
||||||
.joinToString(separator = " ")
|
|
||||||
.replace(Regex.fromLiteral(" ,"), ",")
|
|
||||||
.replace(",([^\\s])".toRegex(), ", $1")
|
|
||||||
.replace(Regex("\\s+"), " ")
|
|
||||||
.replace(Regex.fromLiteral("( "), "(")
|
|
||||||
.replace(Regex.fromLiteral(" )"), ")")
|
|
||||||
.replace(Regex("CREATE TABLE \"([a-zA-Z_]+)\""), "CREATE TABLE $1") // for some reason SQLite will wrap table names in quotes for upgraded tables. This unwraps them.
|
|
||||||
}
|
|
||||||
|
|
||||||
private class InMemoryTestHelper(private val application: Application) : SQLiteOpenHelper(application, null, null, 1) {
|
|
||||||
|
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
|
||||||
for (statement in SNAPSHOT_V181) {
|
|
||||||
db.execSQL(statement.sql)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
|
||||||
SignalDatabaseMigrations.migrate(application, SignalSQLiteDatabase(db), 181, SignalDatabaseMigrations.DATABASE_VERSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the list of statements that existed at version 181. Never change this.
|
|
||||||
*/
|
|
||||||
private val SNAPSHOT_V181 = listOf(
|
|
||||||
Statement(
|
|
||||||
name = "message",
|
|
||||||
sql = "CREATE TABLE message (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n date_sent INTEGER NOT NULL,\n date_received INTEGER NOT NULL,\n date_server INTEGER DEFAULT -1,\n thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE,\n recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,\n recipient_device_id INTEGER,\n type INTEGER NOT NULL,\n body TEXT,\n read INTEGER DEFAULT 0,\n ct_l TEXT,\n exp INTEGER,\n m_type INTEGER,\n m_size INTEGER,\n st INTEGER,\n tr_id TEXT,\n subscription_id INTEGER DEFAULT -1, \n receipt_timestamp INTEGER DEFAULT -1, \n delivery_receipt_count INTEGER DEFAULT 0, \n read_receipt_count INTEGER DEFAULT 0, \n viewed_receipt_count INTEGER DEFAULT 0,\n mismatched_identities TEXT DEFAULT NULL,\n network_failures TEXT DEFAULT NULL,\n expires_in INTEGER DEFAULT 0,\n expire_started INTEGER DEFAULT 0,\n notified INTEGER DEFAULT 0,\n quote_id INTEGER DEFAULT 0,\n quote_author INTEGER DEFAULT 0,\n quote_body TEXT DEFAULT NULL,\n quote_missing INTEGER DEFAULT 0,\n quote_mentions BLOB DEFAULT NULL,\n quote_type INTEGER DEFAULT 0,\n shared_contacts TEXT DEFAULT NULL,\n unidentified INTEGER DEFAULT 0,\n link_previews TEXT DEFAULT NULL,\n view_once INTEGER DEFAULT 0,\n reactions_unread INTEGER DEFAULT 0,\n reactions_last_seen INTEGER DEFAULT -1,\n remote_deleted INTEGER DEFAULT 0,\n mentions_self INTEGER DEFAULT 0,\n notified_timestamp INTEGER DEFAULT 0,\n server_guid TEXT DEFAULT NULL,\n message_ranges BLOB DEFAULT NULL,\n story_type INTEGER DEFAULT 0,\n parent_story_id INTEGER DEFAULT 0,\n export_state BLOB DEFAULT NULL,\n exported INTEGER DEFAULT 0,\n scheduled_date INTEGER DEFAULT -1\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "part",
|
|
||||||
sql = "CREATE TABLE part (_id INTEGER PRIMARY KEY, mid INTEGER, seq INTEGER DEFAULT 0, ct TEXT, name TEXT, chset INTEGER, cd TEXT, fn TEXT, cid TEXT, cl TEXT, ctt_s INTEGER, ctt_t TEXT, encrypted INTEGER, pending_push INTEGER, _data TEXT, data_size INTEGER, file_name TEXT, unique_id INTEGER NOT NULL, digest BLOB, fast_preflight_id TEXT, voice_note INTEGER DEFAULT 0, borderless INTEGER DEFAULT 0, video_gif INTEGER DEFAULT 0, data_random BLOB, quote INTEGER DEFAULT 0, width INTEGER DEFAULT 0, height INTEGER DEFAULT 0, caption TEXT DEFAULT NULL, sticker_pack_id TEXT DEFAULT NULL, sticker_pack_key DEFAULT NULL, sticker_id INTEGER DEFAULT -1, sticker_emoji STRING DEFAULT NULL, data_hash TEXT DEFAULT NULL, blur_hash TEXT DEFAULT NULL, transform_properties TEXT DEFAULT NULL, transfer_file TEXT DEFAULT NULL, display_order INTEGER DEFAULT 0, upload_timestamp INTEGER DEFAULT 0, cdn_number INTEGER DEFAULT 0)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "thread",
|
|
||||||
sql = "CREATE TABLE thread (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n date INTEGER DEFAULT 0, \n meaningful_messages INTEGER DEFAULT 0,\n recipient_id INTEGER NOT NULL UNIQUE REFERENCES recipient (_id) ON DELETE CASCADE,\n read INTEGER DEFAULT 1, \n type INTEGER DEFAULT 0, \n error INTEGER DEFAULT 0, \n snippet TEXT, \n snippet_type INTEGER DEFAULT 0, \n snippet_uri TEXT DEFAULT NULL, \n snippet_content_type TEXT DEFAULT NULL, \n snippet_extras TEXT DEFAULT NULL, \n unread_count INTEGER DEFAULT 0, \n archived INTEGER DEFAULT 0, \n status INTEGER DEFAULT 0, \n delivery_receipt_count INTEGER DEFAULT 0, \n read_receipt_count INTEGER DEFAULT 0, \n expires_in INTEGER DEFAULT 0, \n last_seen INTEGER DEFAULT 0, \n has_sent INTEGER DEFAULT 0, \n last_scrolled INTEGER DEFAULT 0, \n pinned INTEGER DEFAULT 0, \n unread_self_mention_count INTEGER DEFAULT 0\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "identities",
|
|
||||||
sql = "CREATE TABLE identities (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n address INTEGER UNIQUE, \n identity_key TEXT, \n first_use INTEGER DEFAULT 0, \n timestamp INTEGER DEFAULT 0, \n verified INTEGER DEFAULT 0, \n nonblocking_approval INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "drafts",
|
|
||||||
sql = "CREATE TABLE drafts (\n _id INTEGER PRIMARY KEY, \n thread_id INTEGER, \n type TEXT, \n value TEXT\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "push",
|
|
||||||
sql = "CREATE TABLE push (_id INTEGER PRIMARY KEY, type INTEGER, source TEXT, source_uuid TEXT, device_id INTEGER, body TEXT, content TEXT, timestamp INTEGER, server_timestamp INTEGER DEFAULT 0, server_delivered_timestamp INTEGER DEFAULT 0, server_guid TEXT DEFAULT NULL)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "groups",
|
|
||||||
sql = "CREATE TABLE groups (\n _id INTEGER PRIMARY KEY, \n group_id TEXT, \n recipient_id INTEGER,\n title TEXT,\n avatar_id INTEGER, \n avatar_key BLOB,\n avatar_content_type TEXT, \n avatar_relay TEXT,\n timestamp INTEGER,\n active INTEGER DEFAULT 1,\n avatar_digest BLOB, \n mms INTEGER DEFAULT 0, \n master_key BLOB, \n revision BLOB, \n decrypted_group BLOB, \n expected_v2_id TEXT DEFAULT NULL, \n former_v1_members TEXT DEFAULT NULL, \n distribution_id TEXT DEFAULT NULL, \n display_as_story INTEGER DEFAULT 0, \n auth_service_id TEXT DEFAULT NULL, \n last_force_update_timestamp INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_membership",
|
|
||||||
sql = "CREATE TABLE group_membership ( _id INTEGER PRIMARY KEY, group_id TEXT NOT NULL, recipient_id INTEGER NOT NULL, UNIQUE(group_id, recipient_id) )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "recipient",
|
|
||||||
sql = "CREATE TABLE recipient (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n uuid TEXT UNIQUE DEFAULT NULL,\n username TEXT UNIQUE DEFAULT NULL,\n phone TEXT UNIQUE DEFAULT NULL,\n email TEXT UNIQUE DEFAULT NULL,\n group_id TEXT UNIQUE DEFAULT NULL,\n group_type INTEGER DEFAULT 0,\n blocked INTEGER DEFAULT 0,\n message_ringtone TEXT DEFAULT NULL, \n message_vibrate INTEGER DEFAULT 0, \n call_ringtone TEXT DEFAULT NULL, \n call_vibrate INTEGER DEFAULT 0, \n notification_channel TEXT DEFAULT NULL, \n mute_until INTEGER DEFAULT 0, \n color TEXT DEFAULT NULL, \n seen_invite_reminder INTEGER DEFAULT 0,\n default_subscription_id INTEGER DEFAULT -1,\n message_expiration_time INTEGER DEFAULT 0,\n registered INTEGER DEFAULT 0,\n system_given_name TEXT DEFAULT NULL, \n system_family_name TEXT DEFAULT NULL, \n system_display_name TEXT DEFAULT NULL, \n system_photo_uri TEXT DEFAULT NULL, \n system_phone_label TEXT DEFAULT NULL, \n system_phone_type INTEGER DEFAULT -1, \n system_contact_uri TEXT DEFAULT NULL, \n system_info_pending INTEGER DEFAULT 0, \n profile_key TEXT DEFAULT NULL, \n profile_key_credential TEXT DEFAULT NULL, \n signal_profile_name TEXT DEFAULT NULL, \n profile_family_name TEXT DEFAULT NULL, \n profile_joined_name TEXT DEFAULT NULL, \n signal_profile_avatar TEXT DEFAULT NULL, \n profile_sharing INTEGER DEFAULT 0, \n last_profile_fetch INTEGER DEFAULT 0, \n unidentified_access_mode INTEGER DEFAULT 0, \n force_sms_selection INTEGER DEFAULT 0, \n storage_service_key TEXT UNIQUE DEFAULT NULL, \n mention_setting INTEGER DEFAULT 0, \n storage_proto TEXT DEFAULT NULL,\n capabilities INTEGER DEFAULT 0,\n last_session_reset BLOB DEFAULT NULL,\n wallpaper BLOB DEFAULT NULL,\n wallpaper_file TEXT DEFAULT NULL,\n about TEXT DEFAULT NULL,\n about_emoji TEXT DEFAULT NULL,\n extras BLOB DEFAULT NULL,\n groups_in_common INTEGER DEFAULT 0,\n chat_colors BLOB DEFAULT NULL,\n custom_chat_colors_id INTEGER DEFAULT 0,\n badges BLOB DEFAULT NULL,\n pni TEXT DEFAULT NULL,\n distribution_list_id INTEGER DEFAULT NULL,\n needs_pni_signature INTEGER DEFAULT 0,\n unregistered_timestamp INTEGER DEFAULT 0,\n hidden INTEGER DEFAULT 0,\n reporting_token BLOB DEFAULT NULL,\n system_nickname TEXT DEFAULT NULL\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_receipts",
|
|
||||||
sql = "CREATE TABLE group_receipts (\n _id INTEGER PRIMARY KEY, \n mms_id INTEGER, \n address INTEGER, \n status INTEGER, \n timestamp INTEGER, \n unidentified INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "one_time_prekeys",
|
|
||||||
sql = "CREATE TABLE one_time_prekeys (\n _id INTEGER PRIMARY KEY,\n account_id TEXT NOT NULL,\n key_id INTEGER UNIQUE, \n public_key TEXT NOT NULL, \n private_key TEXT NOT NULL,\n UNIQUE(account_id, key_id)\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "signed_prekeys",
|
|
||||||
sql = "CREATE TABLE signed_prekeys (\n _id INTEGER PRIMARY KEY,\n account_id TEXT NOT NULL,\n key_id INTEGER UNIQUE, \n public_key TEXT NOT NULL,\n private_key TEXT NOT NULL,\n signature TEXT NOT NULL, \n timestamp INTEGER DEFAULT 0,\n UNIQUE(account_id, key_id)\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sessions",
|
|
||||||
sql = "CREATE TABLE sessions (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n account_id TEXT NOT NULL,\n address TEXT NOT NULL,\n device INTEGER NOT NULL,\n record BLOB NOT NULL,\n UNIQUE(account_id, address, device)\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sender_keys",
|
|
||||||
sql = "CREATE TABLE sender_keys (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n address TEXT NOT NULL, \n device INTEGER NOT NULL, \n distribution_id TEXT NOT NULL,\n record BLOB NOT NULL, \n created_at INTEGER NOT NULL, \n UNIQUE(address,device, distribution_id) ON CONFLICT REPLACE\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sender_key_shared",
|
|
||||||
sql = "CREATE TABLE sender_key_shared (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n distribution_id TEXT NOT NULL, \n address TEXT NOT NULL, \n device INTEGER NOT NULL, \n timestamp INTEGER DEFAULT 0, \n UNIQUE(distribution_id,address, device) ON CONFLICT REPLACE\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "pending_retry_receipts",
|
|
||||||
sql = "CREATE TABLE pending_retry_receipts(_id INTEGER PRIMARY KEY AUTOINCREMENT, author TEXT NOT NULL, device INTEGER NOT NULL, sent_timestamp INTEGER NOT NULL, received_timestamp TEXT NOT NULL, thread_id INTEGER NOT NULL, UNIQUE(author,sent_timestamp) ON CONFLICT REPLACE)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sticker",
|
|
||||||
sql = "CREATE TABLE sticker (_id INTEGER PRIMARY KEY AUTOINCREMENT, pack_id TEXT NOT NULL, pack_key TEXT NOT NULL, pack_title TEXT NOT NULL, pack_author TEXT NOT NULL, sticker_id INTEGER, cover INTEGER, pack_order INTEGER, emoji TEXT NOT NULL, content_type TEXT DEFAULT NULL, last_used INTEGER, installed INTEGER,file_path TEXT NOT NULL, file_length INTEGER, file_random BLOB, UNIQUE(pack_id, sticker_id, cover) ON CONFLICT IGNORE)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "storage_key",
|
|
||||||
sql = "CREATE TABLE storage_key (_id INTEGER PRIMARY KEY AUTOINCREMENT, type INTEGER, key TEXT UNIQUE)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mention",
|
|
||||||
sql = "CREATE TABLE mention(_id INTEGER PRIMARY KEY AUTOINCREMENT, thread_id INTEGER, message_id INTEGER, recipient_id INTEGER, range_start INTEGER, range_length INTEGER)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "payments",
|
|
||||||
sql = "CREATE TABLE payments(_id INTEGER PRIMARY KEY, uuid TEXT DEFAULT NULL, recipient INTEGER DEFAULT 0, recipient_address TEXT DEFAULT NULL, timestamp INTEGER, note TEXT DEFAULT NULL, direction INTEGER, state INTEGER, failure_reason INTEGER, amount BLOB NOT NULL, fee BLOB NOT NULL, transaction_record BLOB DEFAULT NULL, receipt BLOB DEFAULT NULL, payment_metadata BLOB DEFAULT NULL, receipt_public_key TEXT DEFAULT NULL, block_index INTEGER DEFAULT 0, block_timestamp INTEGER DEFAULT 0, seen INTEGER, UNIQUE(uuid) ON CONFLICT ABORT)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "chat_colors",
|
|
||||||
sql = "CREATE TABLE chat_colors (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n chat_colors BLOB\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "emoji_search",
|
|
||||||
sql = "CREATE TABLE emoji_search (\n _id INTEGER PRIMARY KEY,\n label TEXT NOT NULL,\n emoji TEXT NOT NULL,\n rank INTEGER DEFAULT 2147483647 \n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "avatar_picker",
|
|
||||||
sql = "CREATE TABLE avatar_picker (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n last_used INTEGER DEFAULT 0,\n group_id TEXT DEFAULT NULL,\n avatar BLOB NOT NULL\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_call_ring",
|
|
||||||
sql = "CREATE TABLE group_call_ring (\n _id INTEGER PRIMARY KEY,\n ring_id INTEGER UNIQUE,\n date_received INTEGER,\n ring_state INTEGER\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "reaction",
|
|
||||||
sql = "CREATE TABLE reaction (\n _id INTEGER PRIMARY KEY,\n message_id INTEGER NOT NULL REFERENCES message (_id) ON DELETE CASCADE,\n author_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,\n emoji TEXT NOT NULL,\n date_sent INTEGER NOT NULL,\n date_received INTEGER NOT NULL,\n UNIQUE(message_id, author_id) ON CONFLICT REPLACE\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "donation_receipt",
|
|
||||||
sql = "CREATE TABLE donation_receipt (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n receipt_type TEXT NOT NULL,\n receipt_date INTEGER NOT NULL,\n amount TEXT NOT NULL,\n currency TEXT NOT NULL,\n subscription_level INTEGER NOT NULL\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "story_sends",
|
|
||||||
sql = "CREATE TABLE story_sends (\n _id INTEGER PRIMARY KEY,\n message_id INTEGER NOT NULL REFERENCES message (_id) ON DELETE CASCADE,\n recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,\n sent_timestamp INTEGER NOT NULL,\n allows_replies INTEGER NOT NULL,\n distribution_id TEXT NOT NULL REFERENCES distribution_list (distribution_id) ON DELETE CASCADE\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "cds",
|
|
||||||
sql = "CREATE TABLE cds (\n _id INTEGER PRIMARY KEY,\n e164 TEXT NOT NULL UNIQUE ON CONFLICT IGNORE,\n last_seen_at INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "remote_megaphone",
|
|
||||||
sql = "CREATE TABLE remote_megaphone (\n _id INTEGER PRIMARY KEY,\n uuid TEXT UNIQUE NOT NULL,\n priority INTEGER NOT NULL,\n countries TEXT,\n minimum_version INTEGER NOT NULL,\n dont_show_before INTEGER NOT NULL,\n dont_show_after INTEGER NOT NULL,\n show_for_days INTEGER NOT NULL,\n conditional_id TEXT,\n primary_action_id TEXT,\n secondary_action_id TEXT,\n image_url TEXT,\n image_uri TEXT DEFAULT NULL,\n title TEXT NOT NULL,\n body TEXT NOT NULL,\n primary_action_text TEXT,\n secondary_action_text TEXT,\n shown_at INTEGER DEFAULT 0,\n finished_at INTEGER DEFAULT 0,\n primary_action_data TEXT DEFAULT NULL,\n secondary_action_data TEXT DEFAULT NULL,\n snoozed_at INTEGER DEFAULT 0,\n seen_count INTEGER DEFAULT 0\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "pending_pni_signature_message",
|
|
||||||
sql = "CREATE TABLE pending_pni_signature_message (\n _id INTEGER PRIMARY KEY,\n recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,\n sent_timestamp INTEGER NOT NULL,\n device_id INTEGER NOT NULL\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "call",
|
|
||||||
sql = "CREATE TABLE call (\n _id INTEGER PRIMARY KEY,\n call_id INTEGER NOT NULL UNIQUE,\n message_id INTEGER NOT NULL REFERENCES message (_id) ON DELETE CASCADE,\n peer INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,\n type INTEGER NOT NULL,\n direction INTEGER NOT NULL,\n event INTEGER NOT NULL\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "message_fts",
|
|
||||||
sql = "CREATE VIRTUAL TABLE message_fts USING fts5(body, thread_id UNINDEXED, content=message, content_rowid=_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "remapped_recipients",
|
|
||||||
sql = "CREATE TABLE remapped_recipients (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n old_id INTEGER UNIQUE, \n new_id INTEGER\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "remapped_threads",
|
|
||||||
sql = "CREATE TABLE remapped_threads (\n _id INTEGER PRIMARY KEY AUTOINCREMENT, \n old_id INTEGER UNIQUE, \n new_id INTEGER\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_payload",
|
|
||||||
sql = "CREATE TABLE msl_payload (\n _id INTEGER PRIMARY KEY,\n date_sent INTEGER NOT NULL,\n content BLOB NOT NULL,\n content_hint INTEGER NOT NULL,\n urgent INTEGER NOT NULL DEFAULT 1\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_recipient",
|
|
||||||
sql = "CREATE TABLE msl_recipient (\n _id INTEGER PRIMARY KEY,\n payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE,\n recipient_id INTEGER NOT NULL, \n device INTEGER NOT NULL\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_message",
|
|
||||||
sql = "CREATE TABLE msl_message (\n _id INTEGER PRIMARY KEY,\n payload_id INTEGER NOT NULL REFERENCES msl_payload (_id) ON DELETE CASCADE,\n message_id INTEGER NOT NULL\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "notification_profile",
|
|
||||||
sql = "CREATE TABLE notification_profile (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n emoji TEXT NOT NULL,\n color TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n allow_all_calls INTEGER NOT NULL DEFAULT 0,\n allow_all_mentions INTEGER NOT NULL DEFAULT 0\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "notification_profile_schedule",
|
|
||||||
sql = "CREATE TABLE notification_profile_schedule (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n notification_profile_id INTEGER NOT NULL REFERENCES notification_profile (_id) ON DELETE CASCADE,\n enabled INTEGER NOT NULL DEFAULT 0,\n start INTEGER NOT NULL,\n end INTEGER NOT NULL,\n days_enabled TEXT NOT NULL\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "notification_profile_allowed_members",
|
|
||||||
sql = "CREATE TABLE notification_profile_allowed_members (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n notification_profile_id INTEGER NOT NULL REFERENCES notification_profile (_id) ON DELETE CASCADE,\n recipient_id INTEGER NOT NULL,\n UNIQUE(notification_profile_id, recipient_id) ON CONFLICT REPLACE\n)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "distribution_list",
|
|
||||||
sql = "CREATE TABLE distribution_list (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL,\n distribution_id TEXT UNIQUE NOT NULL,\n recipient_id INTEGER UNIQUE REFERENCES recipient (_id),\n allows_replies INTEGER DEFAULT 1,\n deletion_timestamp INTEGER DEFAULT 0,\n is_unknown INTEGER DEFAULT 0,\n privacy_mode INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "distribution_list_member",
|
|
||||||
sql = "CREATE TABLE distribution_list_member (\n _id INTEGER PRIMARY KEY AUTOINCREMENT,\n list_id INTEGER NOT NULL REFERENCES distribution_list (_id) ON DELETE CASCADE,\n recipient_id INTEGER NOT NULL REFERENCES recipient (_id),\n privacy_mode INTEGER DEFAULT 0\n )"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "recipient_group_type_index",
|
|
||||||
sql = "CREATE INDEX recipient_group_type_index ON recipient (group_type)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "recipient_pni_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX recipient_pni_index ON recipient (pni)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "recipient_service_id_profile_key",
|
|
||||||
sql = "CREATE INDEX recipient_service_id_profile_key ON recipient (uuid, profile_key) WHERE uuid NOT NULL AND profile_key NOT NULL"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_read_and_notified_and_thread_id_index",
|
|
||||||
sql = "CREATE INDEX mms_read_and_notified_and_thread_id_index ON message (read, notified, thread_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_type_index",
|
|
||||||
sql = "CREATE INDEX mms_type_index ON message (type)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_date_sent_index",
|
|
||||||
sql = "CREATE INDEX mms_date_sent_index ON message (date_sent, recipient_id, thread_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_date_server_index",
|
|
||||||
sql = "CREATE INDEX mms_date_server_index ON message (date_server)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_thread_date_index",
|
|
||||||
sql = "CREATE INDEX mms_thread_date_index ON message (thread_id, date_received)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_reactions_unread_index",
|
|
||||||
sql = "CREATE INDEX mms_reactions_unread_index ON message (reactions_unread)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_story_type_index",
|
|
||||||
sql = "CREATE INDEX mms_story_type_index ON message (story_type)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_parent_story_id_index",
|
|
||||||
sql = "CREATE INDEX mms_parent_story_id_index ON message (parent_story_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_thread_story_parent_story_scheduled_date_index",
|
|
||||||
sql = "CREATE INDEX mms_thread_story_parent_story_scheduled_date_index ON message (thread_id, date_received, story_type, parent_story_id, scheduled_date)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "message_quote_id_quote_author_scheduled_date_index",
|
|
||||||
sql = "CREATE INDEX message_quote_id_quote_author_scheduled_date_index ON message (quote_id, quote_author, scheduled_date)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_exported_index",
|
|
||||||
sql = "CREATE INDEX mms_exported_index ON message (exported)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mms_id_type_payment_transactions_index",
|
|
||||||
sql = "CREATE INDEX mms_id_type_payment_transactions_index ON message (_id,type) WHERE type & 12884901888 != 0"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "part_mms_id_index",
|
|
||||||
sql = "CREATE INDEX part_mms_id_index ON part (mid)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "pending_push_index",
|
|
||||||
sql = "CREATE INDEX pending_push_index ON part (pending_push)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "part_sticker_pack_id_index",
|
|
||||||
sql = "CREATE INDEX part_sticker_pack_id_index ON part (sticker_pack_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "part_data_hash_index",
|
|
||||||
sql = "CREATE INDEX part_data_hash_index ON part (data_hash)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "part_data_index",
|
|
||||||
sql = "CREATE INDEX part_data_index ON part (_data)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "thread_recipient_id_index",
|
|
||||||
sql = "CREATE INDEX thread_recipient_id_index ON thread (recipient_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "archived_count_index",
|
|
||||||
sql = "CREATE INDEX archived_count_index ON thread (archived, meaningful_messages)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "thread_pinned_index",
|
|
||||||
sql = "CREATE INDEX thread_pinned_index ON thread (pinned)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "thread_read",
|
|
||||||
sql = "CREATE INDEX thread_read ON thread (read)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "draft_thread_index",
|
|
||||||
sql = "CREATE INDEX draft_thread_index ON drafts (thread_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_id_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX group_id_index ON groups (group_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_recipient_id_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX group_recipient_id_index ON groups (recipient_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "expected_v2_id_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX expected_v2_id_index ON groups (expected_v2_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_distribution_id_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX group_distribution_id_index ON groups(distribution_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "group_receipt_mms_id_index",
|
|
||||||
sql = "CREATE INDEX group_receipt_mms_id_index ON group_receipts (mms_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sticker_pack_id_index",
|
|
||||||
sql = "CREATE INDEX sticker_pack_id_index ON sticker (pack_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "sticker_sticker_id_index",
|
|
||||||
sql = "CREATE INDEX sticker_sticker_id_index ON sticker (sticker_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "storage_key_type_index",
|
|
||||||
sql = "CREATE INDEX storage_key_type_index ON storage_key (type)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mention_message_id_index",
|
|
||||||
sql = "CREATE INDEX mention_message_id_index ON mention (message_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "mention_recipient_id_thread_id_index",
|
|
||||||
sql = "CREATE INDEX mention_recipient_id_thread_id_index ON mention (recipient_id, thread_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "timestamp_direction_index",
|
|
||||||
sql = "CREATE INDEX timestamp_direction_index ON payments (timestamp, direction)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "timestamp_index",
|
|
||||||
sql = "CREATE INDEX timestamp_index ON payments (timestamp)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "receipt_public_key_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX receipt_public_key_index ON payments (receipt_public_key)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_payload_date_sent_index",
|
|
||||||
sql = "CREATE INDEX msl_payload_date_sent_index ON msl_payload (date_sent)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_recipient_recipient_index",
|
|
||||||
sql = "CREATE INDEX msl_recipient_recipient_index ON msl_recipient (recipient_id, device, payload_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_recipient_payload_index",
|
|
||||||
sql = "CREATE INDEX msl_recipient_payload_index ON msl_recipient (payload_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_message_message_index",
|
|
||||||
sql = "CREATE INDEX msl_message_message_index ON msl_message (message_id, payload_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "date_received_index",
|
|
||||||
sql = "CREATE INDEX date_received_index on group_call_ring (date_received)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "notification_profile_schedule_profile_index",
|
|
||||||
sql = "CREATE INDEX notification_profile_schedule_profile_index ON notification_profile_schedule (notification_profile_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "notification_profile_allowed_members_profile_index",
|
|
||||||
sql = "CREATE INDEX notification_profile_allowed_members_profile_index ON notification_profile_allowed_members (notification_profile_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "donation_receipt_type_index",
|
|
||||||
sql = "CREATE INDEX donation_receipt_type_index ON donation_receipt (receipt_type)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "donation_receipt_date_index",
|
|
||||||
sql = "CREATE INDEX donation_receipt_date_index ON donation_receipt (receipt_date)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "story_sends_recipient_id_sent_timestamp_allows_replies_index",
|
|
||||||
sql = "CREATE INDEX story_sends_recipient_id_sent_timestamp_allows_replies_index ON story_sends (recipient_id, sent_timestamp, allows_replies)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "story_sends_message_id_distribution_id_index",
|
|
||||||
sql = "CREATE INDEX story_sends_message_id_distribution_id_index ON story_sends (message_id, distribution_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "distribution_list_member_list_id_recipient_id_privacy_mode_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX distribution_list_member_list_id_recipient_id_privacy_mode_index ON distribution_list_member (list_id, recipient_id, privacy_mode)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "pending_pni_recipient_sent_device_index",
|
|
||||||
sql = "CREATE UNIQUE INDEX pending_pni_recipient_sent_device_index ON pending_pni_signature_message (recipient_id, sent_timestamp, device_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "call_call_id_index",
|
|
||||||
sql = "CREATE INDEX call_call_id_index ON call (call_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "call_message_id_index",
|
|
||||||
sql = "CREATE INDEX call_message_id_index ON call (message_id)"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "message_ai",
|
|
||||||
sql = "CREATE TRIGGER message_ai AFTER INSERT ON message BEGIN\n INSERT INTO message_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n END"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "message_ad",
|
|
||||||
sql = "CREATE TRIGGER message_ad AFTER DELETE ON message BEGIN\n INSERT INTO message_fts(message_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n END"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "message_au",
|
|
||||||
sql = "CREATE TRIGGER message_au AFTER UPDATE ON message BEGIN\n INSERT INTO message_fts(message_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n INSERT INTO message_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n END"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_message_delete",
|
|
||||||
sql = "CREATE TRIGGER msl_message_delete AFTER DELETE ON message \n BEGIN \n \tDELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id);\n END"
|
|
||||||
),
|
|
||||||
Statement(
|
|
||||||
name = "msl_attachment_delete",
|
|
||||||
sql = "CREATE TRIGGER msl_attachment_delete AFTER DELETE ON part\n BEGIN\n \tDELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old.mid);\n END"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -313,7 +313,7 @@ class SmsDatabaseTest_collapseJoinRequestEventsIfPossible {
|
|||||||
timestamp = wallClock,
|
timestamp = wallClock,
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
update = updateDescription,
|
update = updateDescription,
|
||||||
isGroupAdd = false,
|
isNotifiable = false,
|
||||||
serverGuid = null
|
serverGuid = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.database
|
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
import org.junit.Assert.assertFalse
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Rule
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.signal.core.models.ServiceId.ACI
|
|
||||||
import org.signal.core.util.CursorUtil
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
|
||||||
import org.thoughtcrime.securesms.testing.SignalDatabaseRule
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
@Suppress("ClassName")
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ThreadTableTest_recents {
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
@JvmField
|
|
||||||
val databaseRule = SignalDatabaseRule()
|
|
||||||
|
|
||||||
private lateinit var recipient: Recipient
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun setUp() {
|
|
||||||
recipient = Recipient.resolved(SignalDatabase.recipients.getOrInsertFromServiceId(ACI.from(UUID.randomUUID())))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun givenARecentRecipient_whenIBlockAndGetRecents_thenIDoNotExpectToSeeThatRecipient() {
|
|
||||||
// GIVEN
|
|
||||||
val threadId = SignalDatabase.threads.getOrCreateThreadIdFor(recipient)
|
|
||||||
MmsHelper.insert(recipient = recipient, threadId = threadId)
|
|
||||||
SignalDatabase.threads.update(threadId, true)
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
SignalDatabase.recipients.setBlocked(recipient.id, true)
|
|
||||||
val results: MutableList<RecipientId> = SignalDatabase.threads.getRecentConversationList(10, false, false, false, false, false, false).use { cursor ->
|
|
||||||
val ids = mutableListOf<RecipientId>()
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
ids.add(RecipientId.from(CursorUtil.requireLong(cursor, ThreadTable.RECIPIENT_ID)))
|
|
||||||
}
|
|
||||||
|
|
||||||
ids
|
|
||||||
}
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
assertFalse(recipient.id in results)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,12 +4,12 @@ import android.app.Application
|
|||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import org.signal.core.util.billing.BillingApi
|
import org.signal.core.util.billing.BillingApi
|
||||||
|
import org.signal.network.api.ArchiveApi
|
||||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess
|
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess
|
||||||
import org.thoughtcrime.securesms.recipients.LiveRecipientCache
|
import org.thoughtcrime.securesms.recipients.LiveRecipientCache
|
||||||
import org.whispersystems.signalservice.api.SignalServiceDataStore
|
import org.whispersystems.signalservice.api.SignalServiceDataStore
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender
|
||||||
import org.whispersystems.signalservice.api.account.AccountApi
|
import org.whispersystems.signalservice.api.account.AccountApi
|
||||||
import org.whispersystems.signalservice.api.archive.ArchiveApi
|
|
||||||
import org.whispersystems.signalservice.api.attachment.AttachmentApi
|
import org.whispersystems.signalservice.api.attachment.AttachmentApi
|
||||||
import org.whispersystems.signalservice.api.donations.DonationsApi
|
import org.whispersystems.signalservice.api.donations.DonationsApi
|
||||||
import org.whispersystems.signalservice.api.keys.KeysApi
|
import org.whispersystems.signalservice.api.keys.KeysApi
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ class DataMessageProcessorTest_polls {
|
|||||||
|
|
||||||
private fun insertPoll(allowMultiple: Boolean = true): Long {
|
private fun insertPoll(allowMultiple: Boolean = true): Long {
|
||||||
val envelope = MessageContentFuzzer.envelope(100)
|
val envelope = MessageContentFuzzer.envelope(100)
|
||||||
val pollMessage = IncomingMessage(type = MessageType.NORMAL, from = alice.id, sentTimeMillis = envelope.timestamp!!, serverTimeMillis = envelope.serverTimestamp!!, receivedTimeMillis = 0, groupId = groupId)
|
val pollMessage = IncomingMessage(type = MessageType.NORMAL, from = alice.id, sentTimeMillis = envelope.clientTimestamp!!, serverTimeMillis = envelope.serverTimestamp!!, receivedTimeMillis = 0, groupId = groupId)
|
||||||
val messageId = SignalDatabase.messages.insertMessageInbox(pollMessage).get()
|
val messageId = SignalDatabase.messages.insertMessageInbox(pollMessage).get()
|
||||||
SignalDatabase.polls.insertPoll("question?", allowMultiple, listOf("a", "b", "c"), alice.id.toLong(), messageId.messageId)
|
SignalDatabase.polls.insertPoll("question?", allowMultiple, listOf("a", "b", "c"), alice.id.toLong(), messageId.messageId)
|
||||||
return messageId.messageId
|
return messageId.messageId
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ object MessageContentFuzzer {
|
|||||||
*/
|
*/
|
||||||
fun envelope(timestamp: Long, serverGuid: UUID = UUID.randomUUID()): Envelope {
|
fun envelope(timestamp: Long, serverGuid: UUID = UUID.randomUUID()): Envelope {
|
||||||
return Envelope.Builder()
|
return Envelope.Builder()
|
||||||
.timestamp(timestamp)
|
.clientTimestamp(timestamp)
|
||||||
.serverTimestamp(timestamp + 5)
|
.serverTimestamp(timestamp + 5)
|
||||||
.serverGuidBinary(serverGuid.toByteArray().toByteString())
|
.serverGuidBinary(serverGuid.toByteArray().toByteString())
|
||||||
.build()
|
.build()
|
||||||
@@ -292,7 +292,7 @@ object MessageContentFuzzer {
|
|||||||
body = string()
|
body = string()
|
||||||
val quoted = quoteAble.random(random)
|
val quoted = quoteAble.random(random)
|
||||||
quote = DataMessage.Quote.Builder().buildWith {
|
quote = DataMessage.Quote.Builder().buildWith {
|
||||||
id = quoted.envelope.timestamp
|
id = quoted.envelope.clientTimestamp
|
||||||
authorAciBinary = quoted.metadata.sourceServiceId.toByteString()
|
authorAciBinary = quoted.metadata.sourceServiceId.toByteString()
|
||||||
text = quoted.content.dataMessage?.body
|
text = quoted.content.dataMessage?.body
|
||||||
attachments(quoted.content.dataMessage?.attachments ?: emptyList())
|
attachments(quoted.content.dataMessage?.attachments ?: emptyList())
|
||||||
@@ -304,7 +304,7 @@ object MessageContentFuzzer {
|
|||||||
if (random.nextFloat() < 0.1 && quoteAble.isNotEmpty()) {
|
if (random.nextFloat() < 0.1 && quoteAble.isNotEmpty()) {
|
||||||
val quoted = quoteAble.random(random)
|
val quoted = quoteAble.random(random)
|
||||||
quote = DataMessage.Quote.Builder().buildWith {
|
quote = DataMessage.Quote.Builder().buildWith {
|
||||||
id = random.nextLong(quoted.envelope.timestamp!! - 1000000, quoted.envelope.timestamp!!)
|
id = random.nextLong(quoted.envelope.clientTimestamp!! - 1000000, quoted.envelope.clientTimestamp!!)
|
||||||
authorAciBinary = quoted.metadata.sourceServiceId.toByteString()
|
authorAciBinary = quoted.metadata.sourceServiceId.toByteString()
|
||||||
text = quoted.content.dataMessage?.body
|
text = quoted.content.dataMessage?.body
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ object MessageContentFuzzer {
|
|||||||
emoji = emojis.random(random)
|
emoji = emojis.random(random)
|
||||||
remove = false
|
remove = false
|
||||||
targetAuthorAciBinary = reactTo.metadata.sourceServiceId.toByteString()
|
targetAuthorAciBinary = reactTo.metadata.sourceServiceId.toByteString()
|
||||||
targetSentTimestamp = reactTo.envelope.timestamp
|
targetSentTimestamp = reactTo.envelope.clientTimestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ object MockProvider {
|
|||||||
val device = PreKeyResponseItem().apply {
|
val device = PreKeyResponseItem().apply {
|
||||||
this.deviceId = deviceId
|
this.deviceId = deviceId
|
||||||
registrationId = KeyHelper.generateRegistrationId(false)
|
registrationId = KeyHelper.generateRegistrationId(false)
|
||||||
signedPreKey = SignedPreKeyEntity(signedPreKeyRecord.id, signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature)
|
signedPreKey = SignedPreKeyEntity(signedPreKeyRecord.id.toLong(), signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature)
|
||||||
preKey = PreKeyEntity(oneTimePreKey.id, oneTimePreKey.keyPair.publicKey)
|
preKey = PreKeyEntity(oneTimePreKey.id.toLong(), oneTimePreKey.keyPair.publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
return PreKeyResponse().apply {
|
return PreKeyResponse().apply {
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ class BenchmarkCommandReceiver : BroadcastReceiver() {
|
|||||||
verb = "PUT",
|
verb = "PUT",
|
||||||
path = "/api/v1/message",
|
path = "/api/v1/message",
|
||||||
id = Random.nextLong(),
|
id = Random.nextLong(),
|
||||||
headers = listOf("X-Signal-Timestamp: ${this.timestamp}"),
|
headers = listOf("X-Signal-Timestamp: ${this.serverTimestamp}"),
|
||||||
body = this.encodeByteString()
|
body = this.encodeByteString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ object Generator {
|
|||||||
val serverGuid = UUID.randomUUID()
|
val serverGuid = UUID.randomUUID()
|
||||||
return Envelope.Builder()
|
return Envelope.Builder()
|
||||||
.type(Envelope.Type.fromValue(this.type))
|
.type(Envelope.Type.fromValue(this.type))
|
||||||
.sourceDevice(1)
|
.sourceDeviceId(1)
|
||||||
.timestamp(timestamp)
|
.clientTimestamp(timestamp)
|
||||||
.serverTimestamp(timestamp + 1)
|
.serverTimestamp(timestamp + 1)
|
||||||
.destinationServiceId(destination.toString())
|
.destinationServiceId(destination.toString())
|
||||||
.destinationServiceIdBinary(destination.toByteString())
|
.destinationServiceIdBinary(destination.toByteString())
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationM
|
|||||||
import org.thoughtcrime.securesms.conversation.v2.data.ConversationElementKey
|
import org.thoughtcrime.securesms.conversation.v2.data.ConversationElementKey
|
||||||
import org.thoughtcrime.securesms.conversation.v2.data.IncomingTextOnly
|
import org.thoughtcrime.securesms.conversation.v2.data.IncomingTextOnly
|
||||||
import org.thoughtcrime.securesms.conversation.v2.data.OutgoingTextOnly
|
import org.thoughtcrime.securesms.conversation.v2.data.OutgoingTextOnly
|
||||||
|
import org.thoughtcrime.securesms.database.CollapsedState
|
||||||
import org.thoughtcrime.securesms.database.MessageTypes
|
import org.thoughtcrime.securesms.database.MessageTypes
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.StoryType
|
import org.thoughtcrime.securesms.database.model.StoryType
|
||||||
@@ -122,7 +123,10 @@ class ConversationElementGenerator {
|
|||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
null,
|
null,
|
||||||
null
|
CollapsedState.NONE,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
val conversationMessage = ConversationMessageFactory.createWithUnresolvedData(
|
val conversationMessage = ConversationMessageFactory.createWithUnresolvedData(
|
||||||
|
|||||||
@@ -353,5 +353,13 @@ class InternalConversationTestFragment : Fragment(R.layout.conversation_test_fra
|
|||||||
override fun onViewPinnedMessage(messageId: Long) {
|
override fun onViewPinnedMessage(messageId: Long) {
|
||||||
Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onExpandEvents(messageId: Long, itemView: View, collapsedSize: Int) {
|
||||||
|
Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCollapseEvents(messageId: Long, itemView: View, collapsedSize: Int) {
|
||||||
|
Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,6 +458,13 @@
|
|||||||
android:label="@string/AndroidManifest__select_contacts"
|
android:label="@string/AndroidManifest__select_contacts"
|
||||||
android:windowSoftInputMode="stateHidden" />
|
android:windowSoftInputMode="stateHidden" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".search.SingleContactSelectionActivity"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="@string/AndroidManifest__select_contacts"
|
||||||
|
android:windowSoftInputMode="stateHidden" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".giph.ui.GiphyActivity"
|
android:name=".giph.ui.GiphyActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
@@ -475,7 +482,7 @@
|
|||||||
android:windowSoftInputMode="stateAlwaysHidden|adjustNothing" />
|
android:windowSoftInputMode="stateAlwaysHidden|adjustNothing" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.signal.mediasend.MediaSendActivity"
|
android:name=".mediasend.v3.MediaSendV3Activity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize|uiMode"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
@@ -668,6 +675,13 @@
|
|||||||
android:theme="@style/TextSecure.DarkNoActionBar"
|
android:theme="@style/TextSecure.DarkNoActionBar"
|
||||||
android:windowSoftInputMode="stateHidden" />
|
android:windowSoftInputMode="stateHidden" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".starred.StarredMessagesActivity"
|
||||||
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@style/Theme.Signal.DayNight.NoActionBar"
|
||||||
|
android:windowSoftInputMode="stateHidden" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".mediaoverview.MediaOverviewActivity"
|
android:name=".mediaoverview.MediaOverviewActivity"
|
||||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 97 KiB |
BIN
app/src/main/assets/emoji/People_10.webp
Normal file
|
After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 221 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 94 KiB |
@@ -62,6 +62,7 @@ import org.thoughtcrime.securesms.jobs.AccountConsistencyWorkerJob;
|
|||||||
import org.thoughtcrime.securesms.jobs.BackupRefreshJob;
|
import org.thoughtcrime.securesms.jobs.BackupRefreshJob;
|
||||||
import org.thoughtcrime.securesms.jobs.BackupSubscriptionCheckJob;
|
import org.thoughtcrime.securesms.jobs.BackupSubscriptionCheckJob;
|
||||||
import org.thoughtcrime.securesms.jobs.BuildExpirationConfirmationJob;
|
import org.thoughtcrime.securesms.jobs.BuildExpirationConfirmationJob;
|
||||||
|
import org.thoughtcrime.securesms.jobs.CallingAssetsDownloadJob;
|
||||||
import org.thoughtcrime.securesms.jobs.CheckKeyTransparencyJob;
|
import org.thoughtcrime.securesms.jobs.CheckKeyTransparencyJob;
|
||||||
import org.thoughtcrime.securesms.jobs.CheckServiceReachabilityJob;
|
import org.thoughtcrime.securesms.jobs.CheckServiceReachabilityJob;
|
||||||
import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob;
|
import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob;
|
||||||
@@ -102,12 +103,14 @@ import org.thoughtcrime.securesms.service.MessageBackupListener;
|
|||||||
import org.thoughtcrime.securesms.service.RotateSenderCertificateListener;
|
import org.thoughtcrime.securesms.service.RotateSenderCertificateListener;
|
||||||
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||||
import org.thoughtcrime.securesms.service.webrtc.ActiveCallManager;
|
import org.thoughtcrime.securesms.service.webrtc.ActiveCallManager;
|
||||||
|
import org.thoughtcrime.securesms.service.webrtc.CallingAssets;
|
||||||
import org.thoughtcrime.securesms.service.webrtc.AndroidTelecomUtil;
|
import org.thoughtcrime.securesms.service.webrtc.AndroidTelecomUtil;
|
||||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||||
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
||||||
import org.thoughtcrime.securesms.util.AppStartup;
|
import org.thoughtcrime.securesms.util.AppStartup;
|
||||||
import org.thoughtcrime.securesms.util.DeviceProperties;
|
import org.thoughtcrime.securesms.util.DeviceProperties;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
|
import org.thoughtcrime.securesms.util.Environment;
|
||||||
import org.thoughtcrime.securesms.util.RemoteConfig;
|
import org.thoughtcrime.securesms.util.RemoteConfig;
|
||||||
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
||||||
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
||||||
@@ -214,7 +217,6 @@ public class ApplicationContext extends Application implements AppForegroundObse
|
|||||||
.addNonBlocking(this::ensureProfileUploaded)
|
.addNonBlocking(this::ensureProfileUploaded)
|
||||||
.addNonBlocking(() -> AppDependencies.getExpireStoriesManager().scheduleIfNecessary())
|
.addNonBlocking(() -> AppDependencies.getExpireStoriesManager().scheduleIfNecessary())
|
||||||
.addNonBlocking(BackupRepository::maybeFixAnyDanglingUploadProgress)
|
.addNonBlocking(BackupRepository::maybeFixAnyDanglingUploadProgress)
|
||||||
.addNonBlocking(BackupRepository::maybeFixAnyDanglingLocalExportProgress)
|
|
||||||
.addPostRender(() -> AppDependencies.getDeletedCallEventManager().scheduleIfNecessary())
|
.addPostRender(() -> AppDependencies.getDeletedCallEventManager().scheduleIfNecessary())
|
||||||
.addPostRender(() -> RateLimitUtil.retryAllRateLimitedMessages(this))
|
.addPostRender(() -> RateLimitUtil.retryAllRateLimitedMessages(this))
|
||||||
.addPostRender(this::initializeExpiringMessageManager)
|
.addPostRender(this::initializeExpiringMessageManager)
|
||||||
@@ -227,6 +229,7 @@ public class ApplicationContext extends Application implements AppForegroundObse
|
|||||||
.addPostRender(RetrieveRemoteAnnouncementsJob::enqueue)
|
.addPostRender(RetrieveRemoteAnnouncementsJob::enqueue)
|
||||||
.addPostRender(AndroidTelecomUtil::registerPhoneAccount)
|
.addPostRender(AndroidTelecomUtil::registerPhoneAccount)
|
||||||
.addPostRender(() -> AppDependencies.getJobManager().add(new FontDownloaderJob()))
|
.addPostRender(() -> AppDependencies.getJobManager().add(new FontDownloaderJob()))
|
||||||
|
.addPostRender(() -> AppDependencies.getJobManager().add(new CallingAssetsDownloadJob()))
|
||||||
.addPostRender(CheckServiceReachabilityJob::enqueueIfNecessary)
|
.addPostRender(CheckServiceReachabilityJob::enqueueIfNecessary)
|
||||||
.addPostRender(GroupV2UpdateSelfProfileKeyJob::enqueueForGroupsIfNecessary)
|
.addPostRender(GroupV2UpdateSelfProfileKeyJob::enqueueForGroupsIfNecessary)
|
||||||
.addPostRender(StoryOnboardingDownloadJob.Companion::enqueueIfNeeded)
|
.addPostRender(StoryOnboardingDownloadJob.Companion::enqueueIfNeeded)
|
||||||
@@ -401,6 +404,20 @@ public class ApplicationContext extends Application implements AppForegroundObse
|
|||||||
AppDependencies.init(this, new ApplicationDependencyProvider(this));
|
AppDependencies.init(this, new ApplicationDependencyProvider(this));
|
||||||
}
|
}
|
||||||
AppForegroundObserver.begin();
|
AppForegroundObserver.begin();
|
||||||
|
|
||||||
|
if (Environment.USE_NEW_REGISTRATION) {
|
||||||
|
initializeRegistrationDependencies();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeRegistrationDependencies() {
|
||||||
|
org.signal.registration.RegistrationDependencies.Companion.provide(
|
||||||
|
new org.signal.registration.RegistrationDependencies(
|
||||||
|
new org.thoughtcrime.securesms.registration.v2.AppRegistrationNetworkController(this, AppDependencies.getPushServiceSocket()),
|
||||||
|
new org.thoughtcrime.securesms.registration.v2.AppRegistrationStorageController(this),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeFirstEverAppLaunch() {
|
private void initializeFirstEverAppLaunch() {
|
||||||
|
|||||||
@@ -148,5 +148,7 @@ public interface BindableConversationItem extends Unbindable, GiphyMp4Playable,
|
|||||||
void onViewPollClicked(long messageId);
|
void onViewPollClicked(long messageId);
|
||||||
void onToggleVote(@NonNull PollRecord poll, @NonNull PollOption pollOption, Boolean isChecked);
|
void onToggleVote(@NonNull PollRecord poll, @NonNull PollOption pollOption, Boolean isChecked);
|
||||||
void onViewPinnedMessage(long messageId);
|
void onViewPinnedMessage(long messageId);
|
||||||
|
void onExpandEvents(long messageId, @NonNull View itemView, int collapsedSize);
|
||||||
|
void onCollapseEvents(long messageId, @NonNull View itemView, int collapsedSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public final class BlockUnblockDialog {
|
|||||||
Resources resources = context.getResources();
|
Resources resources = context.getResources();
|
||||||
|
|
||||||
if (recipient.isGroup()) {
|
if (recipient.isGroup()) {
|
||||||
if (SignalDatabase.groups().isActive(recipient.requireGroupId())) {
|
if (SignalDatabase.groups().isMember(recipient.requireGroupId())) {
|
||||||
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_and_leave_s, recipient.getDisplayName(context)));
|
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_block_and_leave_s, recipient.getDisplayName(context)));
|
||||||
builder.setMessage(R.string.BlockUnblockDialog_you_will_no_longer_receive_messages_or_updates);
|
builder.setMessage(R.string.BlockUnblockDialog_you_will_no_longer_receive_messages_or_updates);
|
||||||
builder.setPositiveButton(R.string.BlockUnblockDialog_block_and_leave, ((dialog, which) -> onBlock.run()));
|
builder.setPositiveButton(R.string.BlockUnblockDialog_block_and_leave, ((dialog, which) -> onBlock.run()));
|
||||||
@@ -121,7 +121,7 @@ public final class BlockUnblockDialog {
|
|||||||
Resources resources = context.getResources();
|
Resources resources = context.getResources();
|
||||||
|
|
||||||
if (recipient.isGroup()) {
|
if (recipient.isGroup()) {
|
||||||
if (SignalDatabase.groups().isActive(recipient.requireGroupId())) {
|
if (SignalDatabase.groups().isMember(recipient.requireGroupId())) {
|
||||||
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context)));
|
builder.setTitle(resources.getString(R.string.BlockUnblockDialog_unblock_s, recipient.getDisplayName(context)));
|
||||||
builder.setMessage(R.string.BlockUnblockDialog_group_members_will_be_able_to_add_you);
|
builder.setMessage(R.string.BlockUnblockDialog_group_members_will_be_able_to_add_you);
|
||||||
builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run()));
|
builder.setPositiveButton(R.string.RecipientPreferenceActivity_unblock, ((dialog, which) -> onUnblock.run()));
|
||||||
|
|||||||