Moves ExoPlayer to OkHttp in order to enable Tor support.

This commit is contained in:
Vitor Pamplona
2023-05-29 18:00:29 -04:00
parent 605861dc32
commit ac00694690
6 changed files with 45 additions and 34 deletions
+2
View File
@@ -140,6 +140,8 @@ dependencies {
// view videos // view videos
implementation 'com.google.android.exoplayer:exoplayer:2.18.7' implementation 'com.google.android.exoplayer:exoplayer:2.18.7'
// important for proxy / tor
implementation 'com.google.android.exoplayer:extension-okhttp:2.18.7'
// Load images from the web. // Load images from the web.
implementation "io.coil-kt:coil-compose:$coil_version" implementation "io.coil-kt:coil-compose:$coil_version"
@@ -1,5 +1,12 @@
package com.vitorpamplona.amethyst package com.vitorpamplona.amethyst
import android.content.Context
import android.os.Build
import coil.Coil
import coil.ImageLoader
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.HttpClient
@@ -19,14 +26,30 @@ import com.vitorpamplona.amethyst.service.relays.Client
object ServiceManager { object ServiceManager {
private var account: Account? = null private var account: Account? = null
fun start(account: Account) { fun start(account: Account, context: Context) {
this.account = account this.account = account
start() start(context)
} }
fun start() { fun start(context: Context) {
val myAccount = account val myAccount = account
// Resets Proxy Use
HttpClient.start(account) HttpClient.start(account)
Coil.setImageLoader {
ImageLoader.Builder(context).components {
if (Build.VERSION.SDK_INT >= 28) {
add(ImageDecoderDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
add(SvgDecoder.Factory())
} // .logger(DebugLogger())
.okHttpClient { HttpClient.getHttpClient() }
.respectCacheHeaders(false)
.build()
}
if (myAccount != null) { if (myAccount != null) {
Client.connect(myAccount.activeRelays() ?: myAccount.convertLocalRelays()) Client.connect(myAccount.activeRelays() ?: myAccount.convertLocalRelays())
@@ -2,10 +2,11 @@ package com.vitorpamplona.amethyst
import android.content.Context import android.content.Context
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
import com.google.android.exoplayer2.upstream.cache.CacheDataSource import com.google.android.exoplayer2.upstream.cache.CacheDataSource
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
import com.google.android.exoplayer2.upstream.cache.SimpleCache import com.google.android.exoplayer2.upstream.cache.SimpleCache
import com.vitorpamplona.amethyst.service.HttpClient
object VideoCache { object VideoCache {
@@ -31,7 +32,7 @@ object VideoCache {
cacheDataSourceFactory = CacheDataSource.Factory() cacheDataSourceFactory = CacheDataSource.Factory()
.setCache(simpleCache) .setCache(simpleCache)
.setUpstreamDataSourceFactory( .setUpstreamDataSourceFactory(
DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true) OkHttpDataSource.Factory(HttpClient.getHttpClient())
) )
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR) .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
} }
@@ -2,7 +2,6 @@ package com.vitorpamplona.amethyst.ui
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build.VERSION.SDK_INT
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -12,15 +11,9 @@ import androidx.compose.material.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.Coil
import coil.ImageLoader
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.VideoCache import com.vitorpamplona.amethyst.VideoCache
import com.vitorpamplona.amethyst.service.HttpClient
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent import com.vitorpamplona.amethyst.service.model.ChannelMetadataEvent
@@ -52,20 +45,6 @@ class MainActivity : FragmentActivity() {
// Initializes video cache. // Initializes video cache.
VideoCache.init(this.applicationContext) VideoCache.init(this.applicationContext)
Coil.setImageLoader {
ImageLoader.Builder(this).components {
if (SDK_INT >= 28) {
add(ImageDecoderDecoder.Factory())
} else {
add(GifDecoder.Factory())
}
add(SvgDecoder.Factory())
} // .logger(DebugLogger())
.okHttpClient { HttpClient.getHttpClient() }
.respectCacheHeaders(false)
.build()
}
LocalPreferences.migrateSingleUserPrefs() LocalPreferences.migrateSingleUserPrefs()
setContent { setContent {
@@ -73,7 +52,7 @@ class MainActivity : FragmentActivity() {
// A surface container using the 'background' color from the theme // A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
val accountStateViewModel: AccountStateViewModel = viewModel { val accountStateViewModel: AccountStateViewModel = viewModel {
AccountStateViewModel() AccountStateViewModel(this@MainActivity)
} }
AccountScreen(accountStateViewModel, startingPage) AccountScreen(accountStateViewModel, startingPage)
@@ -92,7 +71,7 @@ class MainActivity : FragmentActivity() {
// Only starts after login // Only starts after login
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
ServiceManager.start() ServiceManager.start(this@MainActivity)
} }
PushNotificationUtils().init(LocalPreferences.allSavedAccounts()) PushNotificationUtils().init(LocalPreferences.allSavedAccounts())
@@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.navigation package com.vitorpamplona.amethyst.ui.navigation
import android.content.Context
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -43,6 +44,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -335,6 +337,8 @@ fun ListContent(
AccountBackupDialog(account, onClose = { backupDialogOpen = false }) AccountBackupDialog(account, onClose = { backupDialogOpen = false })
} }
val context = LocalContext.current
if (conectOrbotDialogOpen) { if (conectOrbotDialogOpen) {
ConnectOrbotDialog( ConnectOrbotDialog(
onClose = { conectOrbotDialogOpen = false }, onClose = { conectOrbotDialogOpen = false },
@@ -342,7 +346,7 @@ fun ListContent(
conectOrbotDialogOpen = false conectOrbotDialogOpen = false
disconnectTorDialog = false disconnectTorDialog = false
checked = true checked = true
enableTor(account, true, proxyPort) enableTor(account, true, proxyPort, context = context)
}, },
proxyPort proxyPort
) )
@@ -364,7 +368,7 @@ fun ListContent(
onClick = { onClick = {
disconnectTorDialog = false disconnectTorDialog = false
checked = false checked = false
enableTor(account, false, proxyPort) enableTor(account, false, proxyPort, context)
} }
) { ) {
Text(text = stringResource(R.string.yes)) Text(text = stringResource(R.string.yes))
@@ -386,13 +390,14 @@ fun ListContent(
private fun enableTor( private fun enableTor(
account: Account, account: Account,
checked: Boolean, checked: Boolean,
portNumber: MutableState<String> portNumber: MutableState<String>,
context: Context
) { ) {
account.proxyPort = portNumber.value.toInt() account.proxyPort = portNumber.value.toInt()
account.proxy = HttpClient.initProxy(checked, "127.0.0.1", account.proxyPort) account.proxy = HttpClient.initProxy(checked, "127.0.0.1", account.proxyPort)
LocalPreferences.saveToEncryptedStorage(account) LocalPreferences.saveToEncryptedStorage(account)
ServiceManager.pause() ServiceManager.pause()
ServiceManager.start() ServiceManager.start(context)
} }
@Composable @Composable
@@ -1,5 +1,6 @@
package com.vitorpamplona.amethyst.ui.screen package com.vitorpamplona.amethyst.ui.screen
import android.content.Context
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
@@ -21,7 +22,7 @@ import nostr.postr.Persona
import nostr.postr.bechToBytes import nostr.postr.bechToBytes
import java.util.regex.Pattern import java.util.regex.Pattern
class AccountStateViewModel() : ViewModel() { class AccountStateViewModel(val context: Context) : ViewModel() {
private val _accountContent = MutableStateFlow<AccountState>(AccountState.LoggedOff) private val _accountContent = MutableStateFlow<AccountState>(AccountState.LoggedOff)
val accountContent = _accountContent.asStateFlow() val accountContent = _accountContent.asStateFlow()
@@ -85,7 +86,7 @@ class AccountStateViewModel() : ViewModel() {
} }
val scope = CoroutineScope(Job() + Dispatchers.IO) val scope = CoroutineScope(Job() + Dispatchers.IO)
scope.launch { scope.launch {
ServiceManager.start(account) ServiceManager.start(account, context)
} }
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
account.saveable.observeForever(saveListener) account.saveable.observeForever(saveListener)