Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db1abf3746 | ||
|
|
66dde4415d | ||
|
|
ce3deb4057 | ||
|
|
2209ff2272 | ||
|
|
1502b0ae3e | ||
|
|
553669de45 | ||
|
|
4952b4470d | ||
|
|
5450967d00 | ||
|
|
37b9e4f200 | ||
|
|
254275a8e0 | ||
|
|
8434813ad6 | ||
|
|
dcae8a8a2f | ||
|
|
6fa7eca60b | ||
|
|
bae55f4b2f | ||
|
|
7278f6db76 | ||
|
|
b553bb1cb0 | ||
|
|
3b67382f67 | ||
|
|
19d5ba5c0e | ||
|
|
96c641c2a0 | ||
|
|
1a50910910 | ||
|
|
40f9b32a75 | ||
|
|
975d7268a1 | ||
|
|
7bda952ee5 | ||
|
|
1c3052a580 | ||
|
|
7c66c4a4f7 | ||
|
|
c6f3a66cad | ||
|
|
4ab02f5b9c | ||
|
|
2ab2b2306d | ||
|
|
3a7f01e16a | ||
|
|
e5a2cea6b0 | ||
|
|
be215b3b1e | ||
|
|
2d5c2d24e5 | ||
|
|
038238a333 | ||
|
|
bfdad2f47c | ||
|
|
2489ea0d5b | ||
|
|
053f071f41 | ||
|
|
caf93b9203 | ||
|
|
f0bfd7224f | ||
|
|
f13becc50b | ||
|
|
4b88f7b845 | ||
|
|
a81cc685b2 | ||
|
|
b6098a26b4 | ||
|
|
d6abf89a7a | ||
|
|
dd55fe90bc | ||
|
|
5a53268534 | ||
|
|
1f9a65e389 | ||
|
|
81055e61a6 | ||
|
|
8a1a47e773 | ||
|
|
193d82789f | ||
|
|
7f09d1d0d7 | ||
|
|
187d7b3e3a | ||
|
|
5d1fcdaded | ||
|
|
36b24d0a20 | ||
|
|
f9d7cf0e19 | ||
|
|
47a10a0288 | ||
|
|
e665252b86 | ||
|
|
a3411072ba | ||
|
|
776b0e23ae | ||
|
|
3f25fb7d5f | ||
|
|
053e6fc223 | ||
|
|
a2ea115650 | ||
|
|
3f7e9cb46f | ||
|
|
cefe50e8a9 | ||
|
|
ff9d5df0e0 | ||
|
|
3716d69b0b | ||
|
|
d5be43cc85 | ||
|
|
481ff5c81e | ||
|
|
3e26060e99 | ||
|
|
d93bfbf693 | ||
|
|
a7e15dc21e | ||
|
|
bb566cb11f | ||
|
|
28081abe1c | ||
|
|
e7c00a3066 | ||
|
|
446585ad68 | ||
|
|
4ebca9ddde | ||
|
|
4c6655bd9a | ||
|
|
cbc7288242 | ||
|
|
78627ecb08 | ||
|
|
bf9582c97e | ||
|
|
1ab3d57378 | ||
|
|
b36d196873 | ||
|
|
e31029da89 | ||
|
|
787bcf7752 | ||
|
|
8c3d50c6dc | ||
|
|
532431b0ad | ||
|
|
cfeee25488 | ||
|
|
608b7ef89a | ||
|
|
4063ef39a4 | ||
|
|
eeb2e2e3af | ||
|
|
2573900c30 | ||
|
|
2acab563d9 | ||
|
|
5f31762220 | ||
|
|
b7b9554364 | ||
|
|
f15fb904bf | ||
|
|
86e4221182 | ||
|
|
dfe8b25dd7 | ||
|
|
53050b3845 | ||
|
|
6ce278114f | ||
|
|
48ff9673b9 | ||
|
|
1999d09901 | ||
|
|
f93a79ae37 | ||
|
|
fac56be499 | ||
|
|
638012f3d0 | ||
|
|
bf452dfa92 | ||
|
|
2b14c98eb0 | ||
|
|
f164ac90db | ||
|
|
14abbb1bbb | ||
|
|
91db26437d | ||
|
|
76054a9e33 | ||
|
|
ae9c53bdf8 | ||
|
|
0dd7b39bb1 | ||
|
|
4a0ea0c51c | ||
|
|
668e8dee5d | ||
|
|
8ec3cf6a43 | ||
|
|
a287408a7a | ||
|
|
78124ef224 | ||
|
|
45e0bb281f | ||
|
|
7a6d863ff7 | ||
|
|
feb9e1d513 | ||
|
|
1a5c1a4b42 | ||
|
|
e41ed92f49 | ||
|
|
7e485b8095 | ||
|
|
92773b1a12 | ||
|
|
7cadb0d35a | ||
|
|
e1f572e1f4 | ||
|
|
ead323c1af | ||
|
|
20c059280c | ||
|
|
50eb8f2322 | ||
|
|
15f418f2cc | ||
|
|
b133546ca6 | ||
|
|
5219d79e27 | ||
|
|
89f97f57cb | ||
|
|
4c63428b71 | ||
|
|
704715de8f | ||
|
|
0d48f10806 | ||
|
|
275ca9e3ba | ||
|
|
710fa4a6f0 | ||
|
|
b1d653a230 | ||
|
|
1b736e9e04 | ||
|
|
1c197ad93d | ||
|
|
a1ba5003d3 | ||
|
|
f26c6f890f | ||
|
|
eb11d5ceda | ||
|
|
43ebcfdee5 | ||
|
|
d9272c3b33 | ||
|
|
1d7f7b6c38 | ||
|
|
07d7af6e75 | ||
|
|
4da1af9a7b | ||
|
|
0840175d6f | ||
|
|
b6e40ea812 | ||
|
|
c81bc22943 | ||
|
|
547b7a3c6f | ||
|
|
5eec3c9541 | ||
|
|
f725dd5a7e | ||
|
|
a3cba66450 | ||
|
|
bab92fca7b | ||
|
|
c37c1dffd4 | ||
|
|
127505af0b | ||
|
|
cfd20d23e8 | ||
|
|
e4b56d4e40 | ||
|
|
c86c2c51bb | ||
|
|
5a623810cb | ||
|
|
444e01deae | ||
|
|
d25ebdc818 | ||
|
|
24e82abf80 | ||
|
|
cfa13867e5 | ||
|
|
34770a2333 | ||
|
|
2c5fa155ae | ||
|
|
bc6941589c | ||
|
|
12afdad291 | ||
|
|
4799d30077 | ||
|
|
fafad0d555 | ||
|
|
3f4133b163 | ||
|
|
68746bcecb | ||
|
|
0fbb4ac333 | ||
|
|
f2e4f626c1 | ||
|
|
2f530dc970 | ||
|
|
87e6aa48bb | ||
|
|
d10a44f8eb | ||
|
|
6359961a82 | ||
|
|
946f76a442 | ||
|
|
616912d85f | ||
|
|
bd38b96095 | ||
|
|
12d9d7741b | ||
|
|
91a119393c | ||
|
|
c82afd8944 | ||
|
|
84c71fce16 | ||
|
|
a0ab252bc9 | ||
|
|
08ace15f95 | ||
|
|
e9a38bab1e | ||
|
|
e63773e5c8 | ||
|
|
bcebf58b76 | ||
|
|
2209e68ae0 |
1
.gitignore
vendored
@@ -24,3 +24,4 @@ test/androidTestEspresso/res/values/arrays.xml
|
||||
obj/
|
||||
jni/libspeex/.deps/
|
||||
*.sh
|
||||
pkcs11.password
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = fr_CA:fr-rCA,pt_BR:pt-rBR,pt_PT:pt,zh_CN:zh-rCN,zh_HK:zh-rHK,zh_TW:zh-rTW,da_DK:da-rDK,de_DE:de,tr_TR:tr,sv_SE:sv-rSE,bg_BG:bg,el_GR:el,kn_IN:kn-rIN,cs_CZ:cs,he:iw,id:in,lt_LT:lt,km_KH:km-rKH,th_TH:th,hi_IN:hi-rIN
|
||||
lang_map = da_DK:da-rDK,he:iw,hi_IN:hi-rIN,id:in,kn_IN:kn-rIN,pt_BR:pt-rBR,pt_PT:pt,qu_EC:qu-rEC,sv_SE:sv-rSE,zh_CN:zh-rCN,zh_HK:zh-rHK,zh_TW:zh-rTW
|
||||
|
||||
[signal-android.master]
|
||||
file_filter = res/values-<lang>/strings.xml
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_LOG" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
@@ -45,7 +44,6 @@
|
||||
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.READ_CALL_STATE"/>
|
||||
|
||||
<!-- For sending/receiving events -->
|
||||
@@ -280,6 +278,11 @@
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".mediasend.MediaSendActivity"
|
||||
android:theme="@style/TextSecure.LightNoActionBar"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".PassphraseChangeActivity"
|
||||
android:label="@string/AndroidManifest__change_passphrase"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
@@ -383,7 +386,7 @@
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".scribbles.StickerSelectActivity"
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:theme="@style/TextSecure.ScribbleTheme"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name="com.soundcloud.android.crop.CropImageActivity" />
|
||||
@@ -422,10 +425,15 @@
|
||||
android:exported="true"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".camera.CameraActivity"
|
||||
android:theme="@style/TextSecure.ScribbleTheme"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<service android:enabled="true" android:name="org.thoughtcrime.securesms.service.WebRtcCallService"/>
|
||||
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
|
||||
<service android:enabled="true" android:exported="false" android:name=".service.KeyCachingService"/>
|
||||
<service android:enabled="true" android:name=".service.MessageRetrievalService"/>
|
||||
<service android:enabled="true" android:name=".service.IncomingMessageObserver$ForegroundService"/>
|
||||
|
||||
<service android:name=".service.QuickResponseService"
|
||||
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
|
||||
@@ -536,8 +544,6 @@
|
||||
|
||||
<receiver android:name=".service.ExpirationListener" />
|
||||
|
||||
<receiver android:name=".jobmanager.requirements.BackoffReceiver" />
|
||||
|
||||
<provider android:name=".providers.PartProvider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false"
|
||||
@@ -569,6 +575,12 @@
|
||||
android:authorities="org.thoughtcrime.securesms.database.attachment"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
android:exported="false"
|
||||
tools:node="remove" />
|
||||
|
||||
<receiver android:name=".service.BootReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
@@ -588,6 +600,12 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".service.RotateSenderCertificateListener">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".service.LocalBackupListener">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
FROM ubuntu:17.04
|
||||
FROM ubuntu:17.10
|
||||
|
||||
RUN dpkg --add-architecture i386 && \
|
||||
apt-get update -y && \
|
||||
apt-get install -y software-properties-common && \
|
||||
apt-get update -y && \
|
||||
apt-get install -y libc6:i386=2.24-9ubuntu2.2 libncurses5:i386=6.0+20160625-1ubuntu1 libstdc++6:i386=6.3.0-12ubuntu2 lib32z1=1:1.2.11.dfsg-0ubuntu1 wget openjdk-8-jdk=8u131-b11-2ubuntu1.17.04.3 git unzip && \
|
||||
apt-get install -y libc6:i386=2.26-0ubuntu2.1 libncurses5:i386=6.0+20160625-1ubuntu1 libstdc++6:i386=7.2.0-8ubuntu3.2 lib32z1=1:1.2.11.dfsg-0ubuntu2 wget openjdk-8-jdk=8u171-b11-0ubuntu0.17.10.1 git unzip opensc pcscd && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean
|
||||
|
||||
ENV ANDROID_SDK_FILENAME android-sdk_r24.4.1-linux.tgz
|
||||
ENV ANDROID_SDK_URL https://dl.google.com/android/${ANDROID_SDK_FILENAME}
|
||||
ENV ANDROID_API_LEVELS android-27
|
||||
ENV ANDROID_BUILD_TOOLS_VERSION 27.0.1
|
||||
ENV ANDROID_API_LEVELS android-28
|
||||
ENV ANDROID_BUILD_TOOLS_VERSION 27.0.3
|
||||
ENV ANDROID_HOME /usr/local/android-sdk-linux
|
||||
ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
|
||||
RUN cd /usr/local/ && \
|
||||
|
||||
@@ -31,10 +31,10 @@ Instructions on how to setup your development environment and build Signal can b
|
||||
|
||||
If you're new to the Signal codebase, we recommend going through our issues and picking out a simple bug to fix (check the "easy" label in our issues) in order to get yourself familiar. Also please have a look at the [CONTRIBUTING.md](https://github.com/signalapp/Signal-Android/blob/master/CONTRIBUTING.md), that might answer some of your questions.
|
||||
|
||||
For larger changes and feature ideas, we ask that you propose it on the [unofficial Community Forum](https://whispersystems.discoursehosting.net) for a high-level discussion with the wider community before implementation.
|
||||
For larger changes and feature ideas, we ask that you propose it on the [unofficial Community Forum](https://community.signalusers.org) for a high-level discussion with the wider community before implementation.
|
||||
|
||||
## Contributing Ideas
|
||||
Have something you want to say about Open Whisper Systems projects or want to be part of the conversation? Get involved in the [community forum](https://whispersystems.discoursehosting.net).
|
||||
Have something you want to say about Open Whisper Systems projects or want to be part of the conversation? Get involved in the [community forum](https://community.signalusers.org).
|
||||
|
||||
Help
|
||||
====
|
||||
|
||||
|
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 333 KiB |
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 812 KiB |
|
Before Width: | Height: | Size: 610 KiB After Width: | Height: | Size: 604 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 691 KiB |
|
Before Width: | Height: | Size: 873 KiB After Width: | Height: | Size: 866 KiB |
|
Before Width: | Height: | Size: 2.0 MiB |
BIN
assets/emoji/People_0.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
assets/emoji/People_1.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
assets/emoji/People_2.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
assets/emoji/People_3.png
Normal file
|
After Width: | Height: | Size: 692 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 482 KiB After Width: | Height: | Size: 487 KiB |
298
build.gradle
@@ -1,15 +1,17 @@
|
||||
import org.signal.signing.ApkSignerUtil
|
||||
|
||||
import java.security.MessageDigest
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://repo1.maven.org/maven2"
|
||||
jcenter()
|
||||
}
|
||||
maven {
|
||||
url 'https://maven.google.com/'
|
||||
name 'Google'
|
||||
}
|
||||
maven {
|
||||
url "https://repo1.maven.org/maven2"
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
@@ -48,36 +50,40 @@ repositories {
|
||||
maven { // textdrawable
|
||||
url 'https://dl.bintray.com/amulyakhare/maven'
|
||||
}
|
||||
maven {
|
||||
url 'https://dl.bintray.com/google/flexbox-layout/'
|
||||
}
|
||||
google()
|
||||
jcenter()
|
||||
mavenLocal()
|
||||
maven {
|
||||
url 'https://maven.google.com/'
|
||||
name 'Google'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:appcompat-v7:27.0.2'
|
||||
compile 'com.android.support:recyclerview-v7:27.0.2'
|
||||
compile 'com.android.support:design:27.0.2'
|
||||
compile 'com.android.support:support-v13:27.0.2'
|
||||
compile 'com.android.support:cardview-v7:27.0.2'
|
||||
compile 'com.android.support:preference-v7:27.0.2'
|
||||
compile 'com.android.support:preference-v14:27.0.2'
|
||||
compile 'com.android.support:gridlayout-v7:27.0.2'
|
||||
compile 'com.android.support:multidex:1.0.2'
|
||||
compile 'com.android.support:exifinterface:27.0.2'
|
||||
def supportVersion = '28.0.0'
|
||||
|
||||
compile "com.android.support:appcompat-v7:$supportVersion"
|
||||
compile "com.android.support:recyclerview-v7:$supportVersion"
|
||||
compile "com.android.support:design:$supportVersion"
|
||||
compile "com.android.support:support-v13:$supportVersion"
|
||||
compile "com.android.support:cardview-v7:$supportVersion"
|
||||
compile "com.android.support:preference-v7:$supportVersion"
|
||||
compile "com.android.support:preference-v14:$supportVersion"
|
||||
compile "com.android.support:gridlayout-v7:$supportVersion"
|
||||
compile "com.android.support:exifinterface:$supportVersion"
|
||||
compile 'com.android.support:multidex:1.0.3'
|
||||
compile 'android.arch.lifecycle:extensions:1.1.1'
|
||||
compile 'android.arch.lifecycle:common-java8:1.1.1'
|
||||
compile 'android.arch.work:work-runtime:1.0.0-beta02'
|
||||
|
||||
compile 'com.google.android.gms:play-services-gcm:9.6.1'
|
||||
compile 'com.google.android.gms:play-services-maps:9.6.1'
|
||||
compile 'com.google.android.gms:play-services-places:9.6.1'
|
||||
compile 'com.google.android.gms:play-services-gcm:16.0.0'
|
||||
compile 'com.google.android.gms:play-services-maps:16.0.0'
|
||||
compile 'com.google.android.gms:play-services-places:16.0.0'
|
||||
compile 'com.google.android.gms:play-services-auth:16.0.1'
|
||||
|
||||
compile 'com.google.android.exoplayer:exoplayer-core:2.8.4'
|
||||
compile 'com.google.android.exoplayer:exoplayer-ui:2.8.4'
|
||||
compile 'com.google.android.exoplayer:exoplayer-core:2.9.1'
|
||||
compile 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
|
||||
|
||||
compile 'org.whispersystems:signal-service-android:2.8.1'
|
||||
compile 'org.whispersystems:signal-service-android:2.12.5'
|
||||
compile 'org.whispersystems:webrtc-android:M69'
|
||||
|
||||
compile "me.leolin:ShortcutBadger:1.1.16"
|
||||
@@ -134,8 +140,8 @@ dependencies {
|
||||
testCompile 'org.powermock:powermock-module-junit4-rule:1.6.1'
|
||||
testCompile 'org.powermock:powermock-classloading-xstream:1.6.1'
|
||||
|
||||
androidTestCompile 'com.android.support:multidex:1.0.2'
|
||||
androidTestCompile 'com.android.support:multidex-instrumentation:1.0.2'
|
||||
androidTestCompile 'com.android.support:multidex:1.0.3'
|
||||
androidTestCompile 'com.android.support:multidex-instrumentation:1.0.3'
|
||||
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
|
||||
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
|
||||
androidTestCompile ('org.assertj:assertj-core:1.7.1') {
|
||||
@@ -149,29 +155,31 @@ dependencies {
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.android.support:design:fa5c27a705310e95a8f4099c98777132ed901a0d69178942306bb34cd76f0d57',
|
||||
'com.android.support:preference-v14:1fcf40bd560dc21ce55b6a292d1326d28f52dc5e4f2a64eef2f38dd95777b645',
|
||||
'com.android.support:preference-v7:d9f32ddc92f8d6a0bd86a18f4fcaff805fa021245e395b6e7dd382907443ee53',
|
||||
'com.android.support:design:7874ad1904eedc74aa41cffffb7f759d8990056f3bbbc9264911651c67c42f5f',
|
||||
'com.android.support:preference-v14:8133c6e19233fa51e036a341e6d3f4adeead3375cebf777efced0fe154c3267e',
|
||||
'com.android.support:preference-v7:75eabe936d1fc3b178450a554c4d433466036f2be6d6dccdf971eac9590fdbf5',
|
||||
'com.pnikosis:materialish-progress:d71d80e00717a096784482aee21001a9d299fec3833e4ebd87739ed36cf77c54',
|
||||
'pl.tajchert:waitingdots:2835d49e0787dbcb606c5a60021ced66578503b1e9fddcd7a5ef0cd5f095ba2c',
|
||||
'mobi.upod:time-duration-picker:db469ce0f48dd96b892eac424ed76870e54bf00fe0a28cdcddfbe5f2a226a0e1',
|
||||
'com.codewaves.stickyheadergrid:stickyheadergrid:5b4aa6a52a957cfd55f60f4220c11c0c371385a3cb9786cae03c260dcdef5794',
|
||||
'com.android.support:appcompat-v7:b2825e8b47f665d3362d8481c8d147d1af9230d16f23a2b94f6ccbc53c68cec1',
|
||||
'com.android.support:appcompat-v7:a3a8e5230359746ed91801579b5fbe4668e3b1c4e6a14c7d67c8f58cb0311752',
|
||||
'com.melnykov:floatingactionbutton:15d58d4fac0f7a288d0e5301bbaf501a146f5b3f5921277811bf99bd3b397263',
|
||||
'com.android.support:recyclerview-v7:3eb953930f10941f2b0447ec123a9b03d2746a42a99c523e82c3ece3308ca70b',
|
||||
'com.android.support:support-v13:6f2848811ceef2e32cc98da02a045d65f7e7447a6bd7198b9ec10aa14d7ad55c',
|
||||
'com.android.support:cardview-v7:57f867a3c8f33e2d4dc0a03e2dfa03cad6267a908179f04a725a68ea9f0b8ccf',
|
||||
'com.android.support:gridlayout-v7:227b5fdffa20f53bd562503aab6d2293d52cf64b5a6ab1116d2150f87bff9e88',
|
||||
'com.android.support:multidex:7cd48755c7cfdb6dd2d21cbb02236ec390f6ac91cde87eb62f475b259ab5301d',
|
||||
'com.android.support:exifinterface:0e7cd526c4468895cd8549def46b3d33c8bcfb1ae4830569898d8c7326b15bb2',
|
||||
'com.android.support:recyclerview-v7:eb296414c1f6d4c7b522f69fe50588ea85297855db0e7806c24eb4f75409587d',
|
||||
'com.android.support:support-v13:491f940c5d6d2ec7678fa2f14bd4bbbe8bf776e2c776d04bf0e5c2175975be43',
|
||||
'com.android.support:cardview-v7:bc9e6b0e06ce1205f1db34f0e6193019613d19cfeb54cdccea722340d1c60f26',
|
||||
'com.android.support:gridlayout-v7:5029529f7db66f8773426bf7318645f0840fc50d74f66355cd60c5e58d2da087',
|
||||
'com.android.support:exifinterface:bbf44e519edd6333a24a3285aa21fd00181b920b81ca8aa89a8899f03ab4d6b0',
|
||||
'com.android.support:multidex:ecf6098572e23b5155bab3b9a82b2fd1530eda6c6c157745e0f5287c66eec60c',
|
||||
'android.arch.work:work-runtime:a865eaf55179bb800f04b04f2fa35c3c4d1108c550bc6b447bca168dac16b56e',
|
||||
'android.arch.lifecycle:extensions:429426b2feec2245ffc5e75b3b5309bedb36159cf06dc71843ae43526ac289b6',
|
||||
'android.arch.lifecycle:common-java8:7078b5c8ccb94203df9cc2a463c69cf0021596e6cf966d78fbfd697aaafe0630',
|
||||
'com.google.android.gms:play-services-gcm:312e61253a236f2d9b750b9c04fc92fd190d23b0b2755c99de6ce4a28b259dae',
|
||||
'com.google.android.gms:play-services-places:abf3a4a3b146ec7e6e753be62775e512868cf37d6f88ffe2d81167b33b57132b',
|
||||
'com.google.android.gms:play-services-maps:45e8021e7ddac4a44a82a0e9698991389ded3023d35c58f38dbd86d54211ec0e',
|
||||
'com.google.android.exoplayer:exoplayer-ui:027557b2d69b15e1852a2530b36971f0dcc177abae240ee35e05f63502cdb0a7',
|
||||
'com.google.android.exoplayer:exoplayer-core:e69b409e11887c955deb373357c30eeabf183395db0092b4817e0f80bb467d5b',
|
||||
'org.whispersystems:signal-service-android:414e91598abd941eb3be9a85702538cc9928d8c22f00e07716b83a096cbbe54d',
|
||||
'com.google.android.gms:play-services-gcm:921b4651a2f4d108753f8b4c5d3844b5f8c1f3c31b740c80f69765082713d004',
|
||||
'com.google.android.gms:play-services-places:2d5c4e4ac3ee5be21b4ec544411bc51d11457b5ae2fa2a5d4539019f87c233c6',
|
||||
'com.google.android.gms:play-services-maps:07f59c5955b759ce7b80ceaeb8261643c5b79acc9f180df2b7c3987658eed2e8',
|
||||
'com.google.android.gms:play-services-auth:aec9e1c584d442cb9f59481a50b2c66dc191872607c04d97ecb82dd0eb5149ec',
|
||||
'com.google.android.exoplayer:exoplayer-ui:7a942afcc402ff01e9bf48e8d3942850986710f06562d50a1408aaf04a683151',
|
||||
'com.google.android.exoplayer:exoplayer-core:b6ab34abac36bc2bc6934b7a50008162feca2c0fde91aaf1e8c1c22f2c16e2c0',
|
||||
'org.whispersystems:signal-service-android:d48244f9e19a4300b0baf65c2cef8c76082d55f11d331b00d098c686729cde2e',
|
||||
'org.whispersystems:webrtc-android:5493c92141ce884fc5ce8240d783232f4fe14bd17a8d0d7d1bd4944d0bd1682f',
|
||||
'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774',
|
||||
'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb',
|
||||
@@ -195,30 +203,54 @@ dependencyVerification {
|
||||
'com.github.dmytrodanylyk.circular-progress-button:library:8dc6a29a5a8db7b2ad5a9a7fda1dc9ae0893f4c8f0545732b2c63854ea693e8e',
|
||||
'org.signal:android-database-sqlcipher:33d4063336893af00b9d68b418e7b290cace74c20ce8aacffddc0911010d3d73',
|
||||
'com.googlecode.ez-vcard:ez-vcard:7e24ad50b222d2f70ac91bdccfa3c0f6200b078d797cb784837f75e77bb4210f',
|
||||
'com.google.android.gms:play-services-iid:54e919f9957b8b7820da7ee9b83471d00d0cac1cf08ddea8b5b41aea80bb1a70',
|
||||
'com.google.android.gms:play-services-base:0ca636a8fc9a5af45e607cdcd61783bf5d561cbbb0f862021ce69606eee5ad49',
|
||||
'com.google.android.gms:play-services-tasks:69ec265168e601d0203d04cd42e34bb019b2f029aa1e16fabd38a5153eea2086',
|
||||
'com.google.android.gms:play-services-basement:95dd882c5ffba15b9a99de3fefb05d3a01946623af67454ca00055d222f85a8d',
|
||||
'com.android.support:support-v4:1b2b37169fcccfef5e563d273749e3792decdce9818bc17932403a2363f537b4',
|
||||
'com.android.support:support-fragment:e4358388022a2205777575a7251fe357334658e4123d5d6e3b082f5899d9b011',
|
||||
'com.android.support:animated-vector-drawable:5b117a2c13a898c2a3c84c480d64edcfac2ef720aa9b742c29249fac774ffc48',
|
||||
'com.android.support:support-core-ui:2284072511a95d504c074de80c82cd33724c6d2754117833b98ba3a09994163e',
|
||||
'com.android.support:transition:1a7db0453c1467fc8fd815e6d50ca6bb475a7a9ba6b5f3b307329688a7c62a68',
|
||||
'com.google.android.gms:play-services-iid:62aa9d8fbfb66ab68d5afdfe78db3d5da1f6adcc19abac142cee25fb23d3391f',
|
||||
'com.google.android.gms:play-services-auth-api-phone:19365818b9ceb048ef48db12b5ffadd5eb86dbeb2c7c7b823bfdd89c665f42e5',
|
||||
'com.google.android.gms:play-services-auth-base:51dc02ad2f8d1d9dff7b5b52c4df2c6c12ef7df55d752e919d5cb4dd6002ecd0',
|
||||
'com.google.android.gms:play-services-base:aca10c780c3219bc50f3db06734f4ab88badd3113c564c0a3156ff8ff674655b',
|
||||
'com.google.android.gms:play-services-stats:5b2d8281adbfd6e74d2295c94bab9ea80fc9a84dfbb397995673f5af4d4c6368',
|
||||
'com.google.android.gms:play-services-places-placereport:04f8baeb1f8f8a734c7d4b1701a3974281b45591affa7e963b59dd019b8abc6e',
|
||||
'com.google.android.gms:play-services-tasks:b31c18d8d1cc8d9814f295ee7435471333f370ba5bd904ca14f8f2bec4f35c35',
|
||||
'com.google.android.gms:play-services-basement:e08bfd1e87c4e50ef76161d7ac76b873aeb975367eeb3afa4abe62ea1887c7c6',
|
||||
'com.android.support:support-v4:8b9031381c678d628c9e47b566ae1d161e1c9710f7855c759beeac7596cecf30',
|
||||
'com.android.support:support-fragment:3772fc738ada86824ba1a4b3f197c3dbd67b7ddcfe2c9db1de95ef2e3487a915',
|
||||
'com.android.support:animated-vector-drawable:271ecbc906cda8dcd9e655ba0473129c3408a4189c806f616c378e6fd18fb3b7',
|
||||
'com.android.support:support-core-ui:bbc7f65fc95649464733af373361532ab5f9f3b749c3badaa2bbf27e574b6c6f',
|
||||
'com.android.support:transition:45d09fc51284c17bbab300f5122512ac7d7348a6d23bda2051648bbe76cc9aa5',
|
||||
'com.android.support:viewpager:013c4c53058758ec104dbae970be58159f75dfe342ba8b937d15ff5282e35ffc',
|
||||
'com.android.support:coordinatorlayout:9dfacd80423dc979048fbaed83c0ee543c46259feb2417377e79a656888d3892',
|
||||
'com.android.support:drawerlayout:8f6809afae4793550c37461c9810e954ae6a23dbb4d23e5333bf18148df1150a',
|
||||
'com.android.support:slidingpanelayout:d1d234f66a1b36a9aee9b94fa6c66f97128c0828078c8e889e9037ec898cd600',
|
||||
'com.android.support:customview:98db03845f994e08248bf701c1ff0ccaa12e70f94251ec9272900f0f694e072b',
|
||||
'com.android.support:swiperefreshlayout:a3b41f7f6730866b49865e86e49f988d4858699765f534300fb2ff5f9325e712',
|
||||
'com.android.support:asynclayoutinflater:115bde87721f7334579b0c735f60dd7c98af1bb7f34010c5b0553b95dc351aa2',
|
||||
'android.arch.persistence.room:runtime:d05c78d494dc700fd6dbc0e873451aebb2510ffbb070c82179055cb10bdd8822',
|
||||
'com.android.support:support-core-utils:c81e1e98ca3cb2edae002c69cf35b22aec364b8cb2f1042c97e206eb5790ac41',
|
||||
'com.android.support:loader:920b85efd72dc33e915b0f88a883fe73b88483c6df8751a741e17611f2460341',
|
||||
'com.android.support:support-vector-drawable:f658986d968172bccfed28578471c96050780fe5e133861e4d331069cc373f4d',
|
||||
'com.android.support:support-media-compat:266eff9605f515013eee1ebdbd8818a9270696dc807f34bbcc5fc11fb61a22c7',
|
||||
'com.android.support:support-compat:e17e3b01dbea3f9ea1c86943292f903ca93d2231c6242e456e0b6a9c5817118a',
|
||||
'com.android.support:versionedparcelable:60eb1cb08f71b65c3f6123135e03ebeb5930b5e126e1e5b2ac91b386908c9d02',
|
||||
'com.android.support:collections:93c258c8a09f531a267653829742c0f8f6da0e348b11cb8655b0855628f2d4f0',
|
||||
'android.arch.lifecycle:livedata:50ab0490c1ff1a7cfb4e554032998b080888946d0dd424f39900efc4a1bcd750',
|
||||
'android.arch.lifecycle:livedata-core:d6fdd8b985d6178d7ea2f16986a24e83f1bee936b74d43167c69e08d3cc12c50',
|
||||
'android.arch.core:runtime:c3215aa5873311b3f88a6f4e4a3c25ad89971bc127de8c3e1291c57f93a05c39',
|
||||
'com.android.support:support-core-utils:b69c6e1e7731b876b910fc7100bcadf40a57f27b32ca26b91400995542112c96',
|
||||
'com.android.support:support-vector-drawable:bf4f4fcbf58b1380616581224e6487c230bfdb3434ec353d4adaa4b1f4865cfa',
|
||||
'com.android.support:support-media-compat:6dd9327ee9aa467cab479aad97df375072b2b6ba61eadffdaa5a88de3843c457',
|
||||
'com.android.support:support-compat:ed4d25d91a0b13d8b9def1c0de69ed03d7fb89d50fb37eb0e9b63b0cf7a42357',
|
||||
'android.arch.lifecycle:runtime:c4e4be66c1b2f0abec593571454e1de14013f7e0f96bf2a9f212931a48cae550',
|
||||
'android.arch.core:common:3a616a32f433e9e23f556b38575c31b013613d3ae85206263b7625fe1f4c151a',
|
||||
'android.arch.lifecycle:common:8d378e88ebd5189e09eef623414812c868fd90aa519d6160e2311fb8b81cff56',
|
||||
'android.arch.lifecycle:viewmodel:7de29cfaba77d6b5d5be234c57f6812d0150d087e63941af22ba1d1f8e2bc96a',
|
||||
'com.github.bumptech.glide:gifdecoder:59ccf3bb0cec11dab4b857382cbe0b171111b6fc62bf141adce4e1180889af15',
|
||||
'com.android.support:support-annotations:af05330d997eb92a066534dbe0a3ea24347d26d7001221092113ae02a8f233da',
|
||||
'org.whispersystems:signal-protocol-android:5b8acded7f2a40178eb90ab8e8cbfec89d170d91b3ff5e78487d1098df6185a1',
|
||||
'org.whispersystems:signal-service-java:c7ab92374e9656ba86a8d859cec71d03a68bba3e7ec0b7c597b726bf720eac21',
|
||||
'com.android.support:interpolator:7bc7ee86a0db39a4b51956f3e89842d2bd962118d57d779eb6ed6b34ba0677ea',
|
||||
'com.android.support:cursoradapter:87feffe742b8d62ca8a9833abe564838bf6a672e31c7ad1306ec4006adf90d21',
|
||||
'android.arch.persistence.room:common:fa506873be8a7de9685389b6539ad5849b39731328454b6db151bcab8a9577c3',
|
||||
'android.arch.persistence:db-framework:f9d1629574008e815a494390857f2125cb3e2cfc291aef8b63625bb3fdc5f360',
|
||||
'android.arch.persistence:db:4ed3c473a2da0944203a66a9e84f4c2fb3bca9854c5d4a263a56b1aec4a52e74',
|
||||
'android.arch.core:runtime:c3215aa5873311b3f88a6f4e4a3c25ad89971bc127de8c3e1291c57f93a05c39',
|
||||
'android.arch.core:common:3a616a32f433e9e23f556b38575c31b013613d3ae85206263b7625fe1f4c151a',
|
||||
'android.arch.lifecycle:viewmodel:7de29cfaba77d6b5d5be234c57f6812d0150d087e63941af22ba1d1f8e2bc96a',
|
||||
'com.android.support:documentfile:47cdcd3e9302b7b064923f05487a5c03babbd9bbda4726b71e97791fab5d4779',
|
||||
'com.android.support:localbroadcastmanager:d287c823af5fdde72c099fcfc5f630efe9687af7a914343ae6fd92de32c8a806',
|
||||
'com.android.support:print:4be8a812d73e4a80e35b91ceae127def3f0bb9726bf3bc439aa0cc81503f5728',
|
||||
'com.android.support:support-annotations:5d5b9414f02d3fa0ee7526b8d5ddae0da67c8ecc8c4d63ffa6cf91488a93b927',
|
||||
'com.google.guava:listenablefuture:e4ad7607e5c0477c6f890ef26a49cb8d1bb4dffb650bab4502afee64644e3069',
|
||||
'org.signal:signal-metadata-android:d9d798aab7ee7200373ecff8718baf8aaeb632c123604e8a41b7b4c0c97eeee1',
|
||||
'org.whispersystems:signal-service-java:746b0334a2c11e978b50f6474bd67ba1aa7bc76fa96b0f3658411436238d1c79',
|
||||
'com.github.bumptech.glide:disklrucache:c1b1b6f5bbd01e2fcdc9d7f60913c8d338bdb65ed4a93bfa02b56f19daaade4b',
|
||||
'com.github.bumptech.glide:annotations:bede99ef9f71517a4274bac18fd3e483e9f2b6108d7d6fe8f4949be4aa4d9512',
|
||||
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
|
||||
@@ -226,25 +258,29 @@ dependencyVerification {
|
||||
'com.klinkerapps:logger:177e325259a8b111ad6745ec10db5861723c99f402222b80629f576f49408541',
|
||||
'com.google.android:flexbox:a9989fd13ae2ee42765dfc515fe362edf4f326e74925d02a10369df8092a4935',
|
||||
'org.jsoup:jsoup:abeaf34795a4de70f72aed6de5966d2955ec7eb348eeb813324f23c999575473',
|
||||
'org.whispersystems:curve25519-android:82595394422b957d4a5b5f1b27b75ba25cf6dc4db4d312418ca38cd6fff279ca',
|
||||
'org.whispersystems:signal-protocol-java:5152c2b01a25147967d6bf82e540f947901bdfa79260be3eb3e96b03f787d6b5',
|
||||
'org.whispersystems:signal-protocol-android:b41b7c3a47b0a4ce35802474ae7c5ddc8f033d80209e98abf7ec669543b2b3ee',
|
||||
'org.signal:signal-metadata-java:af1d0dd766b1e301ed1c44e65161084cf03e2587fe97fdd29ecbea58c6aa6930',
|
||||
'org.whispersystems:signal-protocol-java:b08207f7e1847228f2a1f0d49e113f93c96c6ed8490be14edddd4be55b2a4a4e',
|
||||
'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74',
|
||||
'com.googlecode.libphonenumber:libphonenumber:183392c0565be16d3f6f86680b4106bbde6fe31a402ad21bf9823d938c0c8706',
|
||||
'com.fasterxml.jackson.core:jackson-databind:835097bcdd11f5bc8a08378c70d4c8054dfa4b911691cc2752063c75534d198d',
|
||||
'com.fasterxml.jackson.core:jackson-databind:0fb4e079c118e752cc94c15ad22e6782b0dfc5dc09145f4813fb39d82e686047',
|
||||
'com.squareup.okhttp3:okhttp:7265adbd6f028aade307f58569d814835cd02bc9beffb70c25f72c9de50d61c4',
|
||||
'com.madgag.spongycastle:pkix:0d9cca6991f68eb373cfad309d5268c9fc38db5efb5fe00dcccf5c973af1eca1',
|
||||
'com.madgag.spongycastle:prov:b8c3fec3a59aac1aa04ccf4dad7179351e54ef7672f53f508151b614c131398a',
|
||||
'org.whispersystems:curve25519-java:7dd659d8822c06c3aea1a47f18fac9e5761e29cab8100030b877db445005f03e',
|
||||
'com.fasterxml.jackson.core:jackson-annotations:0ca408c24202a7626ec8b861e99d85eca5e38b73311dd6dd12e3e9deecc3fe94',
|
||||
'com.fasterxml.jackson.core:jackson-core:cbf4604784b4de226262845447a1ad3bb38a6728cebe86562e2c5afada8be2c0',
|
||||
'org.threeten:threetenbp:f4c23ffaaed717c3b99c003e0ee02d6d66377fd47d866fec7d971bd8644fc1a7',
|
||||
'org.whispersystems:curve25519-android:82595394422b957d4a5b5f1b27b75ba25cf6dc4db4d312418ca38cd6fff279ca',
|
||||
'com.fasterxml.jackson.core:jackson-annotations:45d32ac61ef8a744b464c54c2b3414be571016dd46bfc2bec226761cf7ae457a',
|
||||
'com.fasterxml.jackson.core:jackson-core:a2bebaa325ad25455b02149c67e6052367a7d7fc1ce77de000eed284a5214eac',
|
||||
'com.squareup.okio:okio:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
|
||||
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||
'org.whispersystems:curve25519-java:7dd659d8822c06c3aea1a47f18fac9e5761e29cab8100030b877db445005f03e',
|
||||
]
|
||||
}
|
||||
|
||||
android {
|
||||
flavorDimensions "none"
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '27.0.1'
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion '27.0.3'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
|
||||
dexOptions {
|
||||
@@ -252,11 +288,11 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionCode 407
|
||||
versionName "4.26.2"
|
||||
versionCode 442
|
||||
versionName "4.32.2"
|
||||
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 25
|
||||
targetSdkVersion 26
|
||||
multiDexEnabled true
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
@@ -265,11 +301,14 @@ android {
|
||||
buildConfigField "long", "BUILD_TIMESTAMP", getLastCommitTimestamp() + "L"
|
||||
buildConfigField "String", "SIGNAL_URL", "\"https://textsecure-service.whispersystems.org\""
|
||||
buildConfigField "String", "SIGNAL_CDN_URL", "\"https://cdn.signal.org\""
|
||||
buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"https://api.directory.signal.org\""
|
||||
buildConfigField "String", "SIGNAL_SERVICE_STATUS_URL", "\"uptime.signal.org\""
|
||||
buildConfigField "String", "GIPHY_PROXY_HOST", "\"giphy-proxy-production.whispersystems.org\""
|
||||
buildConfigField "int", "GIPHY_PROXY_PORT", "80"
|
||||
buildConfigField "String", "USER_AGENT", "\"OWA\""
|
||||
buildConfigField "boolean", "DEV_BUILD", "false"
|
||||
buildConfigField "String", "MRENCLAVE", "\"cd6cfc342937b23b1bdd3bbf9721aa5615ac9ff50a75c5527d441cd3276826c9\""
|
||||
buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\""
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi", "armeabi-v7a", "x86"
|
||||
@@ -288,10 +327,7 @@ android {
|
||||
exclude 'asm-license.txt'
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release
|
||||
exclude 'META-INF/proguard/androidx-annotations.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -315,6 +351,7 @@ android {
|
||||
'proguard-retrolambda.pro',
|
||||
'proguard-okhttp.pro',
|
||||
'proguard-ez-vcard.pro',
|
||||
'proguard-workmanager.pro',
|
||||
'proguard.cfg'
|
||||
testProguardFiles 'proguard-automation.pro',
|
||||
'proguard.cfg'
|
||||
@@ -322,7 +359,6 @@ android {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles = buildTypes.debug.proguardFiles
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,47 +410,66 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
task assembleWebsiteDescriptor << {
|
||||
android.applicationVariants.all { variant ->
|
||||
if (variant.name.equals("websiteDebug") ||
|
||||
variant.name.equals("websiteRelease"))
|
||||
{
|
||||
File file = new File(variant.outputs[0].outputFile.path)
|
||||
|
||||
if (file.exists()) {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
file.eachByte 4096, {bytes, size ->
|
||||
md.update(bytes, 0, size);
|
||||
}
|
||||
|
||||
String digest = md.digest().collect {String.format "%02x", it}.join();
|
||||
String url = variant.productFlavors.get(0).ext.websiteUpdateUrl
|
||||
String apkName = variant.outputs[0].outputFile.name
|
||||
|
||||
String descriptor = "{" +
|
||||
"\"versionCode\" : $project.android.defaultConfig.versionCode," +
|
||||
"\"versionName\" : \"$project.android.defaultConfig.versionName\"," +
|
||||
"\"sha256sum\" : \"$digest\"," +
|
||||
"\"url\" : \"$url/$apkName\"" +
|
||||
"}"
|
||||
|
||||
File descriptorFile = new File(variant.outputs[0].outputFile.parent, apkName.replace(".apk", ".json"))
|
||||
|
||||
descriptorFile.write(descriptor)
|
||||
}
|
||||
def assembleWebsiteDescriptor = { variant, file ->
|
||||
if (file.exists()) {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
file.eachByte 4096, {bytes, size ->
|
||||
md.update(bytes, 0, size);
|
||||
}
|
||||
|
||||
String digest = md.digest().collect {String.format "%02x", it}.join();
|
||||
String url = variant.productFlavors.get(0).ext.websiteUpdateUrl
|
||||
String apkName = file.getName()
|
||||
|
||||
String descriptor = "{" +
|
||||
"\"versionCode\" : $project.android.defaultConfig.versionCode," +
|
||||
"\"versionName\" : \"$project.android.defaultConfig.versionName\"," +
|
||||
"\"sha256sum\" : \"$digest\"," +
|
||||
"\"url\" : \"$url/$apkName\"" +
|
||||
"}"
|
||||
|
||||
File descriptorFile = new File(file.getParent(), apkName.replace(".apk", ".json"))
|
||||
|
||||
descriptorFile.write(descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
def signProductionRelease = { variant ->
|
||||
String apkName = variant.outputs[0].outputFile.name
|
||||
File inputFile = new File(variant.outputs[0].outputFile.path);
|
||||
File outputFile = new File(variant.outputs[0].outputFile.parent, apkName.replace("-unsigned", ""));
|
||||
|
||||
new ApkSignerUtil("sun.security.pkcs11.SunPKCS11",
|
||||
"pkcs11.config",
|
||||
"PKCS11",
|
||||
"file:pkcs11.password").calculateSignature(inputFile.getAbsolutePath(),
|
||||
outputFile.getAbsolutePath());
|
||||
|
||||
inputFile.delete();
|
||||
return outputFile
|
||||
}
|
||||
|
||||
task signProductionPlayRelease << {
|
||||
signProductionRelease(android.applicationVariants.find({ it.name.equals("playRelease") }))
|
||||
}
|
||||
|
||||
task signProductionWebsiteRelease << {
|
||||
def variant = android.applicationVariants.find({ it.name.equals("websiteRelease") })
|
||||
File signedRelease = signProductionRelease(variant)
|
||||
assembleWebsiteDescriptor(variant, signedRelease);
|
||||
}
|
||||
|
||||
tasks.whenTaskAdded { task ->
|
||||
if (task.name.equals("lint")) {
|
||||
task.enabled = false
|
||||
}
|
||||
|
||||
if (task.name.equals("assembleWebsiteDebug") ||
|
||||
task.name.equals("assembleWebsiteRelease"))
|
||||
{
|
||||
task.finalizedBy assembleWebsiteDescriptor
|
||||
if (task.name.equals("assemblePlayRelease")) {
|
||||
task.finalizedBy signProductionPlayRelease
|
||||
}
|
||||
|
||||
if (task.name.equals("assembleWebsiteRelease")) {
|
||||
task.finalizedBy signProductionWebsiteRelease
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,28 +485,3 @@ def getLastCommitTimestamp() {
|
||||
}
|
||||
}
|
||||
|
||||
def Properties props = new Properties()
|
||||
def propFile = new File('signing.properties')
|
||||
|
||||
if (propFile.canRead()){
|
||||
props.load(new FileInputStream(propFile))
|
||||
|
||||
if (props !=null &&
|
||||
props.containsKey('STORE_FILE') &&
|
||||
props.containsKey('STORE_PASSWORD') &&
|
||||
props.containsKey('KEY_ALIAS') &&
|
||||
props.containsKey('KEY_PASSWORD'))
|
||||
{
|
||||
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
|
||||
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
|
||||
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
|
||||
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
|
||||
} else {
|
||||
println 'signing.properties found but some entries are missing'
|
||||
android.buildTypes.release.signingConfig = null
|
||||
}
|
||||
}else {
|
||||
println 'signing.properties not found'
|
||||
android.buildTypes.release.signingConfig = null
|
||||
}
|
||||
|
||||
|
||||
9
buildSrc/build.gradle
Normal file
@@ -0,0 +1,9 @@
|
||||
apply plugin: 'java-gradle-plugin'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'com.android.tools.build', name: 'apksig', version: '2.3.0'
|
||||
}
|
||||
141
buildSrc/src/main/java/org/signal/signing/ApkSignerUtil.java
Normal file
@@ -0,0 +1,141 @@
|
||||
package org.signal.signing;
|
||||
|
||||
import com.android.apksig.ApkSigner;
|
||||
import com.android.apksig.apk.ApkFormatException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ApkSignerUtil {
|
||||
|
||||
private final String providerClass;
|
||||
|
||||
private final String providerArgument;
|
||||
|
||||
private final String keyStoreType;
|
||||
|
||||
private final String keyStorePassword;
|
||||
|
||||
|
||||
public ApkSignerUtil(String providerClass, String providerArgument, String keyStoreType, String keyStorePassword) {
|
||||
this.providerClass = providerClass;
|
||||
this.providerArgument = providerArgument;
|
||||
this.keyStoreType = keyStoreType;
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
}
|
||||
|
||||
public void calculateSignature(String inputApkFile, String outputApkFile)
|
||||
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, ApkFormatException, InvalidKeyException, SignatureException
|
||||
{
|
||||
System.out.println("Running calculateSignature()...");
|
||||
|
||||
if (providerClass != null) {
|
||||
installProvider(providerClass, providerArgument);
|
||||
}
|
||||
|
||||
ApkSigner apkSigner = new ApkSigner.Builder(Collections.singletonList(loadKeyStore(keyStoreType, keyStorePassword)))
|
||||
.setV1SigningEnabled(true)
|
||||
.setV2SigningEnabled(true)
|
||||
.setInputApk(new File(inputApkFile))
|
||||
.setOutputApk(new File(outputApkFile))
|
||||
.setOtherSignersSignaturesPreserved(false)
|
||||
.build();
|
||||
|
||||
apkSigner.sign();
|
||||
}
|
||||
|
||||
private void installProvider(String providerName, String providerArgument) {
|
||||
try {
|
||||
Class<?> providerClass = Class.forName(providerName);
|
||||
|
||||
if (!Provider.class.isAssignableFrom(providerClass)) {
|
||||
throw new IllegalArgumentException("JCA Provider class " + providerClass + " not subclass of " + Provider.class.getName());
|
||||
}
|
||||
|
||||
Provider provider;
|
||||
|
||||
if (providerArgument != null) {
|
||||
provider = (Provider) providerClass.getConstructor(String.class).newInstance(providerArgument);
|
||||
} else {
|
||||
provider = (Provider) providerClass.getConstructor().newInstance();
|
||||
}
|
||||
|
||||
Security.addProvider(provider);
|
||||
} catch (ClassNotFoundException | InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ApkSigner.SignerConfig loadKeyStore(String keyStoreType, String keyStorePassword) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||
KeyStore keyStoreEntity = KeyStore.getInstance(keyStoreType == null ? KeyStore.getDefaultType() : keyStoreType);
|
||||
char[] password = getPassword(keyStorePassword);
|
||||
keyStoreEntity.load(null, password);
|
||||
|
||||
Enumeration<String> aliases = keyStoreEntity.aliases();
|
||||
String keyAlias = null;
|
||||
|
||||
while (aliases != null && aliases.hasMoreElements()) {
|
||||
String alias = aliases.nextElement();
|
||||
if (keyStoreEntity.isKeyEntry(alias)) {
|
||||
keyAlias = alias;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyAlias == null) {
|
||||
throw new IllegalArgumentException("Keystore has no key entries!");
|
||||
}
|
||||
|
||||
PrivateKey privateKey = (PrivateKey) keyStoreEntity.getKey(keyAlias, password);
|
||||
Certificate[] certificates = keyStoreEntity.getCertificateChain(keyAlias);
|
||||
|
||||
if (certificates == null || certificates.length == 0) {
|
||||
throw new IllegalArgumentException("Unable to load certificates!");
|
||||
}
|
||||
|
||||
List<X509Certificate> results = new LinkedList<>();
|
||||
|
||||
for (Certificate certificate : certificates) {
|
||||
results.add((X509Certificate)certificate);
|
||||
}
|
||||
|
||||
|
||||
return new ApkSigner.SignerConfig.Builder("Signal Signer", privateKey, results).build();
|
||||
}
|
||||
|
||||
private char[] getPassword(String encoded) throws IOException {
|
||||
if (encoded.startsWith("file:")) {
|
||||
String name = encoded.substring("file:".length());
|
||||
BufferedReader reader = new BufferedReader(new FileReader(new File(name)));
|
||||
String password = reader.readLine();
|
||||
|
||||
if (password.length() == 0) {
|
||||
throw new IOException("Failed to read password from file: " + name);
|
||||
}
|
||||
|
||||
return password.toCharArray();
|
||||
} else {
|
||||
return encoded.toCharArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
5
pkcs11.config
Normal file
@@ -0,0 +1,5 @@
|
||||
name = OpenSC-PKCS11
|
||||
description = SunPKCS11 via OpenSC
|
||||
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
|
||||
slotListIndex = 0
|
||||
|
||||
2
proguard-workmanager.pro
Normal file
@@ -0,0 +1,2 @@
|
||||
-dontwarn sun.misc.Unsafe
|
||||
-dontwarn com.google.common.util.concurrent.ListenableFuture
|
||||
15
protobuf/DeviceName.proto
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (C) 2014-2016 Open Whisper Systems
|
||||
*
|
||||
* Licensed according to the LICENSE file in this repository.
|
||||
*/
|
||||
package signalservice;
|
||||
|
||||
option java_package = "org.thoughtcrime.securesms.devicelist";
|
||||
option java_outer_classname = "DeviceNameProtos";
|
||||
|
||||
message DeviceName {
|
||||
optional bytes ephemeralPublic = 1;
|
||||
optional bytes syntheticIv = 2;
|
||||
optional bytes ciphertext = 3;
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
all:
|
||||
protoc --java_out=../src/ WebRtcData.proto Backups.proto
|
||||
protoc --java_out=../src/ WebRtcData.proto Backups.proto DeviceName.proto
|
||||
|
||||
13
res/anim/camera_capture_button_grow.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:duration="100"
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:fromXScale=".85"
|
||||
android:fromYScale=".85"
|
||||
android:toXScale="1.0"
|
||||
android:toYScale="1.0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%" />
|
||||
</set>
|
||||
13
res/anim/camera_capture_button_shrink.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<scale
|
||||
android:duration="100"
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:fromXScale="1.0"
|
||||
android:fromYScale="1.0"
|
||||
android:toXScale=".85"
|
||||
android:toYScale=".85"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%" />
|
||||
</set>
|
||||
8
res/anim/camera_slide_from_bottom.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<translate
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:duration="350"
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0%" />
|
||||
</set>
|
||||
8
res/anim/camera_slide_to_bottom.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<translate
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:duration="250"
|
||||
android:fromYDelta="0%"
|
||||
android:toYDelta="100%" />
|
||||
</set>
|
||||
6
res/anim/fade_in.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<alpha
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:fromAlpha="0.0"
|
||||
android:toAlpha="1.0"
|
||||
android:duration="@android:integer/config_shortAnimTime" />
|
||||
6
res/anim/fade_out.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<alpha
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:fromAlpha="1.0"
|
||||
android:toAlpha="0.0"
|
||||
android:duration="@android:integer/config_shortAnimTime" />
|
||||
7
res/anim/stationary.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="250"
|
||||
android:fromYDelta="0%"
|
||||
android:toYDelta="0%" />
|
||||
</set>
|
||||
|
Before Width: | Height: | Size: 961 B |
BIN
res/drawable-hdpi/ic_add_caption.png
Normal file
|
After Width: | Height: | Size: 221 B |
BIN
res/drawable-hdpi/ic_add_photo.png
Normal file
|
After Width: | Height: | Size: 397 B |
|
Before Width: | Height: | Size: 788 B |
BIN
res/drawable-hdpi/ic_camera_front.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
res/drawable-hdpi/ic_camera_rear.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_camera_shutter.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
res/drawable-hdpi/ic_caption.png
Normal file
|
After Width: | Height: | Size: 661 B |
BIN
res/drawable-hdpi/ic_profile_default.png
Normal file
|
After Width: | Height: | Size: 475 B |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_scribble_brush.png
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
res/drawable-hdpi/ic_scribble_delete.png
Normal file
|
After Width: | Height: | Size: 721 B |
BIN
res/drawable-hdpi/ic_scribble_highlight.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-hdpi/ic_scribble_save.png
Normal file
|
After Width: | Height: | Size: 718 B |
BIN
res/drawable-hdpi/ic_scribble_sticker.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_scribble_text.png
Normal file
|
After Width: | Height: | Size: 926 B |
BIN
res/drawable-hdpi/ic_scribble_undo.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-hdpi/ic_signal_background_connection.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
res/drawable-hdpi/ic_signal_backup.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
res/drawable-hdpi/ic_signal_downloading.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 708 B |
BIN
res/drawable-hdpi/ic_unidentified_delivery.png
Normal file
|
After Width: | Height: | Size: 478 B |
BIN
res/drawable-hdpi/ic_x_circle.png
Normal file
|
After Width: | Height: | Size: 485 B |
|
Before Width: | Height: | Size: 654 B |
BIN
res/drawable-mdpi/ic_add_caption.png
Normal file
|
After Width: | Height: | Size: 165 B |
BIN
res/drawable-mdpi/ic_add_photo.png
Normal file
|
After Width: | Height: | Size: 227 B |
|
Before Width: | Height: | Size: 506 B |
BIN
res/drawable-mdpi/ic_camera_front.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-mdpi/ic_camera_rear.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-mdpi/ic_camera_shutter.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
res/drawable-mdpi/ic_caption.png
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
res/drawable-mdpi/ic_profile_default.png
Normal file
|
After Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 838 B |
BIN
res/drawable-mdpi/ic_scribble_brush.png
Normal file
|
After Width: | Height: | Size: 537 B |
BIN
res/drawable-mdpi/ic_scribble_delete.png
Normal file
|
After Width: | Height: | Size: 399 B |
BIN
res/drawable-mdpi/ic_scribble_highlight.png
Normal file
|
After Width: | Height: | Size: 609 B |
BIN
res/drawable-mdpi/ic_scribble_save.png
Normal file
|
After Width: | Height: | Size: 421 B |
BIN
res/drawable-mdpi/ic_scribble_sticker.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-mdpi/ic_scribble_text.png
Normal file
|
After Width: | Height: | Size: 503 B |
BIN
res/drawable-mdpi/ic_scribble_undo.png
Normal file
|
After Width: | Height: | Size: 788 B |
BIN
res/drawable-mdpi/ic_signal_background_connection.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-mdpi/ic_signal_backup.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-mdpi/ic_signal_downloading.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 482 B |
BIN
res/drawable-mdpi/ic_unidentified_delivery.png
Normal file
|
After Width: | Height: | Size: 311 B |
BIN
res/drawable-mdpi/ic_x_circle.png
Normal file
|
After Width: | Height: | Size: 324 B |
|
Before Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-xhdpi/ic_add_caption.png
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
res/drawable-xhdpi/ic_add_photo.png
Normal file
|
After Width: | Height: | Size: 365 B |
|
Before Width: | Height: | Size: 984 B |
BIN
res/drawable-xhdpi/ic_camera_front.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
res/drawable-xhdpi/ic_camera_rear.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
res/drawable-xhdpi/ic_camera_shutter.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
res/drawable-xhdpi/ic_caption.png
Normal file
|
After Width: | Height: | Size: 725 B |
BIN
res/drawable-xhdpi/ic_profile_default.png
Normal file
|
After Width: | Height: | Size: 575 B |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
res/drawable-xhdpi/ic_scribble_brush.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/drawable-xhdpi/ic_scribble_delete.png
Normal file
|
After Width: | Height: | Size: 906 B |
BIN
res/drawable-xhdpi/ic_scribble_highlight.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
res/drawable-xhdpi/ic_scribble_save.png
Normal file
|
After Width: | Height: | Size: 916 B |
BIN
res/drawable-xhdpi/ic_scribble_sticker.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
res/drawable-xhdpi/ic_scribble_text.png
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
res/drawable-xhdpi/ic_scribble_undo.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
res/drawable-xhdpi/ic_signal_background_connection.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
res/drawable-xhdpi/ic_signal_backup.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
res/drawable-xhdpi/ic_signal_downloading.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 539 B |
BIN
res/drawable-xhdpi/ic_unidentified_delivery.png
Normal file
|
After Width: | Height: | Size: 490 B |
BIN
res/drawable-xhdpi/ic_x_circle.png
Normal file
|
After Width: | Height: | Size: 664 B |