This commit is contained in:
Brice
2021-01-15 16:19:29 +11:00
158 changed files with 650 additions and 6100 deletions

View File

@@ -48,8 +48,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'com.annimon:stream:1.1.8'
implementation 'com.makeramen:roundedimageview:2.1.0'

View File

@@ -54,6 +54,22 @@ public class PointerAttachment extends Attachment {
return results;
}
public static List<Attachment> forPointersOfDataMessage(List<SignalServiceDataMessage.Quote.QuotedAttachment> pointers) {
List<Attachment> results = new LinkedList<>();
if (pointers != null) {
for (SignalServiceDataMessage.Quote.QuotedAttachment pointer : pointers) {
Optional<Attachment> result = forPointer(pointer);
if (result.isPresent()) {
results.add(result.get());
}
}
}
return results;
}
public static List<Attachment> forPointers(List<SignalServiceProtos.DataMessage.Quote.QuotedAttachment> pointers) {
List<Attachment> results = new LinkedList<>();
@@ -141,4 +157,24 @@ public class PointerAttachment extends Attachment {
null,
thumbnail != null ? thumbnail.getUrl() : ""));
}
public static Optional<Attachment> forPointer(SignalServiceDataMessage.Quote.QuotedAttachment pointer) {
SignalServiceAttachment thumbnail = pointer.getThumbnail();
return Optional.of(new PointerAttachment(pointer.getContentType(),
AttachmentTransferProgress.TRANSFER_PROGRESS_PENDING.getValue(),
thumbnail != null ? thumbnail.asPointer().getSize().or(0) : 0,
pointer.getFileName(),
String.valueOf(thumbnail != null ? thumbnail.asPointer().getId() : 0),
thumbnail != null && thumbnail.asPointer().getKey() != null ? Base64.encodeBytes(thumbnail.asPointer().getKey()) : null,
null,
thumbnail != null ? thumbnail.asPointer().getDigest().orNull() : null,
null,
false,
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
thumbnail != null ? thumbnail.asPointer().getCaption().orNull() : null,
null,
thumbnail != null ? thumbnail.asPointer().getUrl() : ""));
}
}

View File

@@ -160,12 +160,12 @@ public class Contact implements Parcelable {
@JsonProperty
private final String middleName;
Name(@JsonProperty("displayName") @Nullable String displayName,
@JsonProperty("givenName") @Nullable String givenName,
@JsonProperty("familyName") @Nullable String familyName,
@JsonProperty("prefix") @Nullable String prefix,
@JsonProperty("suffix") @Nullable String suffix,
@JsonProperty("middleName") @Nullable String middleName)
public Name(@JsonProperty("displayName") @Nullable String displayName,
@JsonProperty("givenName") @Nullable String givenName,
@JsonProperty("familyName") @Nullable String familyName,
@JsonProperty("prefix") @Nullable String prefix,
@JsonProperty("suffix") @Nullable String suffix,
@JsonProperty("middleName") @Nullable String middleName)
{
this.displayName = displayName;
this.givenName = givenName;
@@ -254,9 +254,9 @@ public class Contact implements Parcelable {
@JsonIgnore
private boolean selected;
Phone(@JsonProperty("number") @NonNull String number,
@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label)
public Phone(@JsonProperty("number") @NonNull String number,
@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label)
{
this.number = number;
this.type = type;
@@ -333,9 +333,9 @@ public class Contact implements Parcelable {
@JsonIgnore
private boolean selected;
Email(@JsonProperty("email") @NonNull String email,
@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label)
public Email(@JsonProperty("email") @NonNull String email,
@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label)
{
this.email = email;
this.type = type;
@@ -430,15 +430,15 @@ public class Contact implements Parcelable {
@JsonIgnore
private boolean selected;
PostalAddress(@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label,
@JsonProperty("street") @Nullable String street,
@JsonProperty("poBox") @Nullable String poBox,
@JsonProperty("neighborhood") @Nullable String neighborhood,
@JsonProperty("city") @Nullable String city,
@JsonProperty("region") @Nullable String region,
@JsonProperty("postalCode") @Nullable String postalCode,
@JsonProperty("country") @Nullable String country)
public PostalAddress(@JsonProperty("type") @NonNull Type type,
@JsonProperty("label") @Nullable String label,
@JsonProperty("street") @Nullable String street,
@JsonProperty("poBox") @Nullable String poBox,
@JsonProperty("neighborhood") @Nullable String neighborhood,
@JsonProperty("city") @Nullable String city,
@JsonProperty("region") @Nullable String region,
@JsonProperty("postalCode") @Nullable String postalCode,
@JsonProperty("country") @Nullable String country)
{
this.type = type;
this.label = label;

View File

@@ -1,6 +1,14 @@
package org.session.libsession.utilities
import android.content.Context
import org.session.libsession.messaging.threads.Address.Companion.fromSerialized
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.messaging.threads.recipients.RecipientModifiedListener
import org.session.libsignal.libsignal.logging.Log
import org.session.libsignal.service.api.messages.SignalServiceGroup
import org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext
import java.io.IOException
import java.util.*
object GroupUtil {
const val CLOSED_GROUP_PREFIX = "__textsecure_group__!"
@@ -31,6 +39,7 @@ object GroupUtil {
return (MMS_GROUP_PREFIX + groupID).toByteArray()
}
@JvmStatic
fun getEncodedId(group: SignalServiceGroup): String? {
val groupId = group.groupId
if (group.groupType == SignalServiceGroup.GroupType.PUBLIC_CHAT) {
@@ -39,6 +48,7 @@ object GroupUtil {
return getEncodedGroupID(groupId)
}
@JvmStatic
fun getEncodedGroupID(groupID: ByteArray): String {
return groupID.toString()
}

View File

@@ -13,6 +13,7 @@ object NumberUtil {
return matcher.matches()
}
@JvmStatic
fun isValidSmsOrEmail(number: String): Boolean {
return PhoneNumberUtils.isWellFormedSmsAddress(number) || isValidEmail(number)
}

View File

@@ -278,6 +278,7 @@ object TextSecurePreferences {
// org.greenrobot.eventbus.EventBus.getDefault().post(SqlCipherNeedsMigrationEvent())
// }
@JvmStatic
fun getNeedsSqlCipherMigration(context: Context): Boolean {
return getBooleanPreference(context, NEEDS_SQLCIPHER_MIGRATION, false)
}
@@ -343,6 +344,7 @@ object TextSecurePreferences {
setBooleanPreference(context, READ_RECEIPTS_PREF, enabled)
}
@JvmStatic
fun isTypingIndicatorsEnabled(context: Context): Boolean {
return getBooleanPreference(context, TYPING_INDICATORS, false)
}
@@ -359,6 +361,7 @@ object TextSecurePreferences {
setBooleanPreference(context, LINK_PREVIEWS, enabled)
}
@JvmStatic
fun isGifSearchInGridLayout(context: Context): Boolean {
return getBooleanPreference(context, GIF_GRID_LAYOUT, false)
}
@@ -367,10 +370,12 @@ object TextSecurePreferences {
setBooleanPreference(context, GIF_GRID_LAYOUT, isGrid)
}
@JvmStatic
fun getProfileKey(context: Context): String? {
return getStringPreference(context, PROFILE_KEY_PREF, null)
}
@JvmStatic
fun setProfileKey(context: Context, key: String?) {
setStringPreference(context, PROFILE_KEY_PREF, key)
}
@@ -379,6 +384,7 @@ object TextSecurePreferences {
setStringPreference(context, PROFILE_NAME_PREF, name)
}
@JvmStatic
fun getProfileName(context: Context): String? {
return getStringPreference(context, PROFILE_NAME_PREF, null)
}
@@ -404,6 +410,7 @@ object TextSecurePreferences {
return getStringPreference(context, NOTIFICATION_PRIORITY_PREF, NotificationCompat.PRIORITY_HIGH.toString())!!.toInt()
}
@JvmStatic
fun getMessageBodyTextSize(context: Context): Int {
return getStringPreference(context, MESSAGE_BODY_TEXT_SIZE_PREF, "16")!!.toInt()
}
@@ -485,6 +492,7 @@ object TextSecurePreferences {
setBooleanPreference(context, WEBSOCKET_REGISTERED_PREF, registered)
}
@JvmStatic
fun isWifiSmsEnabled(context: Context): Boolean {
return getBooleanPreference(context, WIFI_SMS_PREF, false)
}
@@ -562,6 +570,7 @@ object TextSecurePreferences {
setBooleanPreference(context, UNIDENTIFIED_DELIVERY_ENABLED, enabled)
}
@JvmStatic
fun isUnidentifiedDeliveryEnabled(context: Context): Boolean {
// Loki - Always enable unidentified sender
return true
@@ -592,18 +601,22 @@ object TextSecurePreferences {
setLongPreference(context, UPDATE_APK_REFRESH_TIME_PREF, value)
}
@JvmStatic
fun setUpdateApkDownloadId(context: Context, value: Long) {
setLongPreference(context, UPDATE_APK_DOWNLOAD_ID, value)
}
@JvmStatic
fun getUpdateApkDownloadId(context: Context): Long {
return getLongPreference(context, UPDATE_APK_DOWNLOAD_ID, -1)
}
@JvmStatic
fun setUpdateApkDigest(context: Context, value: String?) {
setStringPreference(context, UPDATE_APK_DIGEST, value)
}
@JvmStatic
fun getUpdateApkDigest(context: Context): String? {
return getStringPreference(context, UPDATE_APK_DIGEST, null)
}
@@ -637,6 +650,7 @@ object TextSecurePreferences {
return getBooleanPreference(context, ENTER_PRESENT_PREF, false)
}
@JvmStatic
fun isEnterSendsEnabled(context: Context): Boolean {
return getBooleanPreference(context, ENTER_SENDS_PREF, false)
}
@@ -832,6 +846,7 @@ object TextSecurePreferences {
setStringPreference(context, LANGUAGE_PREF, language)
}
@JvmStatic
fun isSmsDeliveryReportsEnabled(context: Context): Boolean {
return getBooleanPreference(context, SMS_DELIVERY_REPORT_PREF, false)
}
@@ -928,10 +943,12 @@ object TextSecurePreferences {
setStringPreference(context, LED_BLINK_PREF_CUSTOM, pattern)
}
@JvmStatic
fun isThreadLengthTrimmingEnabled(context: Context): Boolean {
return getBooleanPreference(context, THREAD_TRIM_ENABLED, false)
}
@JvmStatic
fun getThreadTrimLength(context: Context): Int {
return getStringPreference(context, THREAD_TRIM_LENGTH, "500")!!.toInt()
}
@@ -973,18 +990,22 @@ object TextSecurePreferences {
setBooleanPreference(context, NEEDS_FULL_CONTACT_SYNC, needsSync)
}
@JvmStatic
fun setLogEncryptedSecret(context: Context, base64Secret: String?) {
setStringPreference(context, LOG_ENCRYPTED_SECRET, base64Secret)
}
@JvmStatic
fun getLogEncryptedSecret(context: Context): String? {
return getStringPreference(context, LOG_ENCRYPTED_SECRET, null)
}
@JvmStatic
fun setLogUnencryptedSecret(context: Context, base64Secret: String?) {
setStringPreference(context, LOG_UNENCRYPTED_SECRET, base64Secret)
}
@JvmStatic
fun getLogUnencryptedSecret(context: Context): String? {
return getStringPreference(context, LOG_UNENCRYPTED_SECRET, null)
}

View File

@@ -6,13 +6,12 @@ import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import android.text.TextUtils
import org.session.libsession.messaging.threads.Address
import org.session.libsignal.libsignal.logging.Log
import java.io.Closeable
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.io.*
import java.nio.charset.StandardCharsets
import java.security.SecureRandom
import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.ThreadPoolExecutor
@@ -26,6 +25,13 @@ object Util {
return Looper.myLooper() == Looper.getMainLooper()
}
@JvmStatic
fun assertMainThread() {
if (!isMainThread()) {
throw java.lang.AssertionError("Main-thread assertion failed.")
}
}
@JvmStatic
@Throws(IOException::class)
fun copy(`in`: InputStream, out: OutputStream): Long {
@@ -199,4 +205,68 @@ object Util {
return context.packageName == Telephony.Sms.getDefaultSmsPackage(context)
}
@JvmStatic
@Throws(IOException::class)
fun readFully(`in`: InputStream?, buffer: ByteArray) {
if (`in` == null) return
readFully(`in`, buffer, buffer.size)
}
@JvmStatic
@Throws(IOException::class)
fun readFully(`in`: InputStream, buffer: ByteArray?, len: Int) {
var offset = 0
while (true) {
val read = `in`.read(buffer, offset, len - offset)
if (read == -1) throw EOFException("Stream ended early")
offset += if (read + offset < len) read else return
}
}
@JvmStatic
@Throws(IOException::class)
fun readFully(`in`: InputStream): ByteArray? {
val bout = ByteArrayOutputStream()
val buffer = ByteArray(4096)
var read: Int
while (`in`.read(buffer).also { read = it } != -1) {
bout.write(buffer, 0, read)
}
`in`.close()
return bout.toByteArray()
}
@JvmStatic
@Throws(IOException::class)
fun readFullyAsString(`in`: InputStream): String? {
return String(readFully(`in`)!!)
}
@JvmStatic
fun getSecret(size: Int): String? {
val secret = getSecretBytes(size)
return Base64.encodeBytes(secret)
}
fun getSecretBytes(size: Int): ByteArray {
val secret = ByteArray(size)
getSecureRandom().nextBytes(secret)
return secret
}
@JvmStatic
fun getSecureRandom(): SecureRandom {
return SecureRandom()
}
@JvmStatic
fun getFirstNonEmpty(vararg values: String?): String? {
for (value in values) {
if (!TextUtils.isEmpty(value)) {
return value
}
}
return ""
}
}