mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
sync with dev
This commit is contained in:
parent
59ae46b300
commit
190badd9c0
@ -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'
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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.*
|
||||
|
@ -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
|
||||
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
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user