diff options
author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-09-12 06:17:39 +0000 |
---|---|---|
committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-09-12 06:17:39 +0000 |
commit | 53f4a9ce311d612d43fa770cf7e8f8e98fbb43a0 (patch) | |
tree | 59c58e58cfef0e370f39bd9c150e36c6dfcb50c0 /ipscrambling/src/main/java/foundation/e/privacymodules | |
parent | 1a77e3924bc78eabca7b859ef62be30bbf2476ad (diff) |
2: organise module with clean archi, use Koin for injection.
Diffstat (limited to 'ipscrambling/src/main/java/foundation/e/privacymodules')
2 files changed, 0 insertions, 355 deletions
diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt deleted file mode 100644 index 859319a..0000000 --- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2021 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacymodules.ipscrambler - -import android.content.Intent - -interface IIpScramblerModule { - fun prepareAndroidVpn(): Intent? - - fun start(enableNotification: Boolean = true) - - fun stop() - - fun requestStatus() - - var appList: Set<String> - - var exitCountry: String - fun getAvailablesLocations(): Set<String> - - val httpProxyPort: Int - val socksProxyPort: Int - - fun addListener(listener: Listener) - fun removeListener(listener: Listener) - fun clearListeners() - - fun onCleared() - - interface Listener { - fun onStatusChanged(newStatus: Status) - fun log(message: String) - fun onTrafficUpdate(upload: Long, download: Long, read: Long, write: Long) - } - - enum class Status { - OFF, ON, STARTING, STOPPING, START_DISABLED - } -} diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt deleted file mode 100644 index 1c39330..0000000 --- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2021 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacymodules.ipscrambler - -import android.annotation.SuppressLint -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.net.VpnService -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.os.Message -import android.util.Log -import androidx.localbroadcastmanager.content.LocalBroadcastManager -import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Listener -import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Status -import org.torproject.android.service.OrbotConstants -import org.torproject.android.service.OrbotConstants.ACTION_STOP_FOREGROUND_TASK -import org.torproject.android.service.OrbotService -import org.torproject.android.service.util.Prefs -import java.security.InvalidParameterException - -@SuppressLint("CommitPrefEdits") -class IpScramblerModule(private val context: Context) : IIpScramblerModule { - companion object { - const val TAG = "IpScramblerModule" - - private val EXIT_COUNTRY_CODES = setOf("DE", "AT", "SE", "CH", "IS", "CA", "US", "ES", "FR", "BG", "PL", "AU", "BR", "CZ", "DK", "FI", "GB", "HU", "NL", "JP", "RO", "RU", "SG", "SK") - - // Key where exit country is stored by orbot service. - private const val PREFS_KEY_EXIT_NODES = "pref_exit_nodes" - // Copy of the package private OrbotService.NOTIFY_ID value. - // const val ORBOT_SERVICE_NOTIFY_ID_COPY = 1 - } - - private var currentStatus: Status? = null - private val listeners = mutableSetOf<Listener>() - - private val localBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - val action = intent.action ?: return - if (action == OrbotConstants.ACTION_RUNNING_SYNC) { - try { - intent.getStringExtra(OrbotConstants.EXTRA_STATUS)?.let { - val newStatus = Status.valueOf(it) - currentStatus = newStatus - } - } catch (e: Exception) { - Log.e(TAG, "Can't parse Orbot service status.") - } - return - } - - val msg = messageHandler.obtainMessage() - msg.obj = action - msg.data = intent.extras - messageHandler.sendMessage(msg) - } - } - - private val messageHandler: Handler = object : Handler(Looper.getMainLooper()) { - override fun handleMessage(msg: Message) { - val action = msg.obj as? String ?: return - val data = msg.data - when (action) { - OrbotConstants.LOCAL_ACTION_LOG -> - data.getString(OrbotConstants.LOCAL_EXTRA_LOG)?.let { newLog(it) } - - OrbotConstants.LOCAL_ACTION_BANDWIDTH -> { - trafficUpdate( - data.getLong("up", 0), - data.getLong("down", 0), - data.getLong("written", 0), - data.getLong("read", 0) - ) - } - - OrbotConstants.LOCAL_ACTION_PORTS -> { - httpProxyPort = data.getInt(OrbotService.EXTRA_HTTP_PROXY_PORT, -1) - socksProxyPort = data.getInt(OrbotService.EXTRA_SOCKS_PROXY_PORT, -1) - } - - OrbotConstants.LOCAL_ACTION_STATUS -> - data.getString(OrbotConstants.EXTRA_STATUS)?.let { - try { - val newStatus = Status.valueOf(it) - updateStatus(newStatus, force = true) - } catch (e: Exception) { - Log.e(TAG, "Can't parse Orbot service status.") - } - } - } - super.handleMessage(msg) - } - } - - init { - Prefs.setContext(context) - - val lbm = LocalBroadcastManager.getInstance(context) - lbm.registerReceiver( - localBroadcastReceiver, - IntentFilter(OrbotConstants.LOCAL_ACTION_STATUS) - ) - lbm.registerReceiver( - localBroadcastReceiver, - IntentFilter(OrbotConstants.LOCAL_ACTION_BANDWIDTH) - ) - lbm.registerReceiver( - localBroadcastReceiver, - IntentFilter(OrbotConstants.LOCAL_ACTION_LOG) - ) - lbm.registerReceiver( - localBroadcastReceiver, - IntentFilter(OrbotConstants.LOCAL_ACTION_PORTS) - ) - lbm.registerReceiver( - localBroadcastReceiver, - IntentFilter(OrbotConstants.ACTION_RUNNING_SYNC) - ) - - Prefs.getSharedPrefs(context).edit() - .putInt(OrbotConstants.PREFS_DNS_PORT, OrbotConstants.TOR_DNS_PORT_DEFAULT) - .apply() - } - - private fun updateStatus(status: Status, force: Boolean = false) { - if (force || status != currentStatus) { - currentStatus = status - listeners.forEach { - it.onStatusChanged(status) - } - } - } - - private fun isServiceRunning(): Boolean { - // Reset status, and then ask to refresh it synchronously. - currentStatus = Status.OFF - LocalBroadcastManager.getInstance(context) - .sendBroadcastSync(Intent(OrbotConstants.ACTION_CHECK_RUNNING_SYNC)) - return currentStatus != Status.OFF - } - - private fun newLog(message: String) { - listeners.forEach { it.log(message) } - } - - private fun trafficUpdate(upload: Long, download: Long, read: Long, write: Long) { - listeners.forEach { it.onTrafficUpdate(upload, download, read, write) } - } - - private fun sendIntentToService(action: String, extra: Bundle? = null) { - val intent = Intent(context, OrbotService::class.java) - intent.action = action - extra?.let { intent.putExtras(it) } - context.startService(intent) - } - - @SuppressLint("ApplySharedPref") - private fun saveTorifiedApps(packageNames: Collection<String>) { - packageNames.joinToString("|") - Prefs.getSharedPrefs(context).edit().putString( - OrbotConstants.PREFS_KEY_TORIFIED, packageNames.joinToString("|") - ).commit() - - if (isServiceRunning()) { - sendIntentToService(OrbotConstants.ACTION_RESTART_VPN) - } - } - - private fun getTorifiedApps(): Set<String> { - val list = Prefs.getSharedPrefs(context).getString(OrbotConstants.PREFS_KEY_TORIFIED, "") - ?.split("|") - return if (list == null || list == listOf("")) { - emptySet() - } else { - list.toSet() - } - } - - @SuppressLint("ApplySharedPref") - private fun setExitCountryCode(countryCode: String) { - val countryParam = when { - countryCode.isEmpty() -> "" - countryCode in EXIT_COUNTRY_CODES -> "{$countryCode}" - else -> throw InvalidParameterException( - "Only these countries are available: ${EXIT_COUNTRY_CODES.joinToString { ", " } }" - ) - } - - if (isServiceRunning()) { - val extra = Bundle() - extra.putString("exit", countryParam) - sendIntentToService(OrbotConstants.CMD_SET_EXIT, extra) - } else { - Prefs.getSharedPrefs(context) - .edit().putString(PREFS_KEY_EXIT_NODES, countryParam) - .commit() - } - } - - private fun getExitCountryCode(): String { - val raw = Prefs.getExitNodes() - return if (raw.isEmpty()) raw else raw.slice(1..2) - } - - override fun prepareAndroidVpn(): Intent? { - return VpnService.prepare(context) - } - - override fun start(enableNotification: Boolean) { - Prefs.enableNotification(enableNotification) - Prefs.putUseVpn(true) - Prefs.putStartOnBoot(true) - - sendIntentToService(OrbotConstants.ACTION_START) - sendIntentToService(OrbotConstants.ACTION_START_VPN) - } - - override fun stop() { - updateStatus(Status.STOPPING) - - Prefs.putUseVpn(false) - Prefs.putStartOnBoot(false) - - sendIntentToService(OrbotConstants.ACTION_STOP_VPN) - sendIntentToService( - action = OrbotConstants.ACTION_STOP, - extra = Bundle().apply { putBoolean(ACTION_STOP_FOREGROUND_TASK, true) } - ) - stoppingWatchdog(5) - } - - private fun stoppingWatchdog(countDown: Int) { - Handler(Looper.getMainLooper()).postDelayed( - { - if (isServiceRunning() && countDown > 0) { - stoppingWatchdog(countDown - 1) - } else { - updateStatus(Status.OFF, force = true) - } - }, - 500 - ) - } - - override fun requestStatus() { - if (isServiceRunning()) { - sendIntentToService(OrbotConstants.ACTION_STATUS) - } else { - updateStatus(Status.OFF, force = true) - } - } - - override var appList: Set<String> - get() = getTorifiedApps() - set(value) = saveTorifiedApps(value) - - override var exitCountry: String - get() = getExitCountryCode() - set(value) = setExitCountryCode(value) - - override fun getAvailablesLocations(): Set<String> = EXIT_COUNTRY_CODES - - override var httpProxyPort: Int = -1 - private set - - override var socksProxyPort: Int = -1 - private set - - override fun addListener(listener: Listener) { - listeners.add(listener) - } - override fun removeListener(listener: Listener) { - listeners.remove(listener) - } - override fun clearListeners() { - listeners.clear() - } - - override fun onCleared() { - LocalBroadcastManager.getInstance(context).unregisterReceiver(localBroadcastReceiver) - } -} |