sync with dev

This commit is contained in:
Ryan ZHAO 2021-02-01 09:39:14 +11:00
parent 59ae46b300
commit 190badd9c0
6 changed files with 64 additions and 55 deletions

View File

@ -69,6 +69,7 @@ dependencies {
implementation 'se.emilsjolander:stickylistheaders:2.7.0'
implementation 'com.jpardogo.materialtabstrip:library:1.0.9'
implementation 'org.apache.httpcomponents:httpclient-android:4.3.5'
implementation 'commons-net:commons-net:3.7.2'
implementation 'com.github.chrisbanes:PhotoView:2.1.3'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

View File

@ -51,6 +51,7 @@ import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol
import org.session.libsignal.service.loki.protocol.sessionmanagement.SessionManagementProtocol
import org.session.libsignal.service.loki.protocol.shelved.multidevice.MultiDeviceProtocol
import org.session.libsignal.service.loki.protocol.shelved.syncmessages.SyncMessagesProtocol
import org.session.libsignal.service.loki.utilities.ThreadUtils
import org.session.libsignal.service.loki.utilities.toHexString
import org.thoughtcrime.securesms.loki.dialogs.*
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2
@ -298,13 +299,13 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
.setMessage(R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.RecipientPreferenceActivity_block) { dialog, _ ->
Thread {
ThreadUtils.queue {
DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, true)
Util.runOnMain {
recyclerView.adapter!!.notifyDataSetChanged()
dialog.dismiss()
}
}.start()
}
}.show()
}
@ -314,13 +315,13 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
.setMessage(R.string.RecipientPreferenceActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.RecipientPreferenceActivity_unblock) { dialog, _ ->
Thread {
ThreadUtils.queue {
DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, false)
Util.runOnMain {
recyclerView.adapter!!.notifyDataSetChanged()
dialog.dismiss()
}
}.start()
}
}.show()
}

View File

@ -12,6 +12,7 @@ import org.session.libsignal.libsignal.ecc.ECKeyPair
import org.session.libsignal.libsignal.util.guava.Optional
import org.session.libsignal.service.api.messages.SignalServiceGroup
import org.session.libsignal.service.internal.push.SignalServiceProtos
import org.session.libsignal.service.loki.utilities.ThreadUtils
import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey
import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded
import org.session.libsignal.service.loki.utilities.toHexString
@ -29,7 +30,6 @@ import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.recipients.Recipient
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.service.loki.utilities.ThreadUtils
import java.io.IOException
import java.util.*

View File

@ -8,6 +8,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import org.thoughtcrime.securesms.logging.Log
import com.opencsv.CSVReader
import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI
import org.session.libsignal.service.loki.utilities.ThreadUtils
import java.io.File
import java.io.FileOutputStream
import java.io.FileReader
@ -16,12 +17,33 @@ class IP2Country private constructor(private val context: Context) {
private val pathsBuiltEventReceiver: BroadcastReceiver
val countryNamesCache = mutableMapOf<String, String>()
private val ipv4Table by lazy {
loadFile("geolite2_country_blocks_ipv4.csv")
private fun Ipv4Int(ip:String) = ip.takeWhile { it != '/' }.split('.').foldIndexed(0L) { i, acc, s ->
val asInt = s.toLong()
acc + (asInt shl (8 * (3-i)))
}
private val countryNamesTable by lazy {
loadFile("geolite2_country_locations_english.csv")
private val ipv4ToCountry by lazy {
val file = loadFile("geolite2_country_blocks_ipv4.csv")
val csv = CSVReader(FileReader(file.absoluteFile)).apply {
skip(1)
}
csv.readAll()
.associate { cols ->
Ipv4Int(cols[0]) to cols[1].toIntOrNull()
}
}
private val countryToNames by lazy {
val file = loadFile("geolite2_country_locations_english.csv")
val csv = CSVReader(FileReader(file.absoluteFile)).apply {
skip(1)
}
csv.readAll()
.filter { cols -> !cols[0].isNullOrEmpty() && !cols[1].isNullOrEmpty() }
.associate { cols ->
cols[0].toInt() to cols[5]
}
}
// region Initialization
@ -40,7 +62,6 @@ class IP2Country private constructor(private val context: Context) {
init {
populateCacheIfNeeded()
pathsBuiltEventReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
populateCacheIfNeeded()
}
@ -69,51 +90,40 @@ class IP2Country private constructor(private val context: Context) {
return file
}
private fun cacheCountryForIP(ip: String): String {
var truncatedIP = ip
fun getCountryInternal(): String {
val country = countryNamesCache[ip]
if (country != null) { return country }
val ipv4TableReader = CSVReader(FileReader(ipv4Table.absoluteFile))
val countryNamesTableReader = CSVReader(FileReader(countryNamesTable.absoluteFile))
var ipv4TableLine = ipv4TableReader.readNext()
while (ipv4TableLine != null) {
if (!ipv4TableLine[0].startsWith(truncatedIP)) {
ipv4TableLine = ipv4TableReader.readNext()
continue
}
val countryID = ipv4TableLine[1]
var countryNamesTableLine = countryNamesTableReader.readNext()
while (countryNamesTableLine != null) {
if (countryNamesTableLine[0] != countryID) {
countryNamesTableLine = countryNamesTableReader.readNext()
continue
}
@Suppress("NAME_SHADOWING") val country = countryNamesTableLine[5]
countryNamesCache[ip] = country
return country
}
}
if (truncatedIP.contains(".") && !truncatedIP.endsWith(".")) { // The fuzziest we want to go is xxx.x
truncatedIP = truncatedIP.dropLast(1)
if (truncatedIP.endsWith(".")) { truncatedIP = truncatedIP.dropLast(1) }
return getCountryInternal()
private fun cacheCountryForIP(ip: String): String? {
// return early if cached
countryNamesCache[ip]?.let { return it }
val comps = ipv4ToCountry.asSequence()
val bestMatchCountry = comps.lastOrNull { it.key <= Ipv4Int(ip) }?.let { (_, code) ->
if (code != null) {
countryToNames[code]
} else {
return "Unknown Country"
null
}
}
return getCountryInternal()
if (bestMatchCountry != null) {
countryNamesCache[ip] = bestMatchCountry
return bestMatchCountry
} else {
Log.d("Loki","Country name for $ip couldn't be found")
}
return null
}
private fun populateCacheIfNeeded() {
Thread {
val path = OnionRequestAPI.paths.firstOrNull() ?: return@Thread
path.forEach { snode ->
cacheCountryForIP(snode.ip) // Preload if needed
ThreadUtils.queue {
OnionRequestAPI.paths.forEach { path ->
path.forEach { snode ->
cacheCountryForIP(snode.ip) // Preload if needed
}
}
Broadcaster(context).broadcast("onionRequestPathCountriesLoaded")
Log.d("Loki", "Finished preloading onion request path countries.")
}.start()
}
}
// endregion
}

View File

@ -6,18 +6,15 @@ import android.os.Looper;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
import org.session.libsignal.service.api.messages.SignalServiceGroup;
import org.session.libsignal.service.internal.push.SignalServiceProtos;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.loki.api.PublicChatManager;
import org.thoughtcrime.securesms.util.Debouncer;
import org.session.libsignal.service.loki.api.Poller;
import org.session.libsignal.service.loki.utilities.ThreadUtils;
import org.session.libsession.messaging.threads.recipients.Recipient;
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
public class OptimizedMessageNotifier implements MessageNotifier {
@ -129,7 +126,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
private void performOnBackgroundThreadIfNeeded(Runnable r) {
if (Looper.myLooper() == Looper.getMainLooper()) {
new Thread(r).start();
ThreadUtils.queue(r);
} else {
r.run();
}

View File

@ -45,25 +45,25 @@ fun <V, E : Throwable> Promise<V, E>.recover(callback: (exception: E) -> V): Pro
}
fun <V, E> Promise<V, E>.successBackground(callback: (value: V) -> Unit): Promise<V, E> {
Thread {
ThreadUtils.queue {
try {
callback(get())
} catch (e: Exception) {
Log.d("Loki", "Failed to execute task in background: ${e.message}.")
}
}.start()
}
return this
}
fun <V> Promise<V, Exception>.timeout(millis: Long): Promise<V, Exception> {
if (this.isDone()) { return this; }
val deferred = deferred<V, Exception>()
Thread {
ThreadUtils.queue {
Thread.sleep(millis)
if (!deferred.promise.isDone()) {
deferred.reject(TimeoutException("Promise timed out."))
}
}.start()
}
this.success {
if (!deferred.promise.isDone()) { deferred.resolve(it) }
}.fail {