diff --git a/build.gradle b/build.gradle
index 2b2cacd9..c72dfe34 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,7 +3,7 @@
apply plugin: 'com.github.ben-manes.versions'
buildscript {
- ext.kotlinVersion = '1.3.21'
+ ext.kotlinVersion = '1.3.30'
repositories {
google()
jcenter()
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 13372aef..87b738cb 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 17de17a7..51fb1c46 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Jan 03 07:06:26 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
diff --git a/gradlew b/gradlew
index 9d82f789..af6708ff 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,42 +6,6 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index aec99730..0f8d5937 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m"
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/mobile/build.gradle b/mobile/build.gradle
index 00d48a1e..553d9674 100644
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -41,6 +41,7 @@ android {
}
dataBinding.enabled = true
flavorDimensions("freedom")
+ packagingOptions.exclude '**/*.kotlin_*'
productFlavors {
fdroid {
dimension "freedom"
@@ -81,14 +82,14 @@ dependencies {
implementation "androidx.room:room-ktx:$roomVersion"
implementation 'com.android.billingclient:billing:1.2.2'
implementation 'com.github.luongvo:BadgeView:1.1.5'
- implementation 'com.github.topjohnwu.libsu:core:2.3.3'
+ implementation 'com.github.topjohnwu.libsu:core:2.4.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.0.0'
implementation 'net.glxn.qrgen:android:2.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.0'
for (dep in aux) {
freedomImplementation dep
googleImplementation dep
diff --git a/mobile/lint.xml b/mobile/lint.xml
index 06e04731..78700082 100644
--- a/mobile/lint.xml
+++ b/mobile/lint.xml
@@ -3,5 +3,5 @@
-
+
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt
index 685439ef..de9d3b51 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt
@@ -36,18 +36,15 @@ import be.mygod.vpnhotspot.room.AppDatabase
import be.mygod.vpnhotspot.room.ClientStats
import be.mygod.vpnhotspot.room.TrafficRecord
import be.mygod.vpnhotspot.room.macToString
-import be.mygod.vpnhotspot.util.MainScope
import be.mygod.vpnhotspot.util.SpanFormatter
import be.mygod.vpnhotspot.util.computeIfAbsentCompat
import be.mygod.vpnhotspot.util.toPluralInt
import be.mygod.vpnhotspot.widget.SmartSnackbar
import kotlinx.android.parcel.Parcelize
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
import java.text.NumberFormat
-class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
+class ClientsFragment : Fragment() {
@Parcelize
data class NicknameArg(val mac: Long, val nickname: CharSequence) : Parcelable
class NicknameDialogFragment : AlertDialogFragment() {
@@ -140,7 +137,9 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
val wasWorking = TrafficRecorder.isWorking(client.mac)
client.obtainRecord().apply {
blocked = !blocked
- launch(Dispatchers.Unconfined) { AppDatabase.instance.clientRecordDao.update(this@apply) }
+ GlobalScope.launch(Dispatchers.Unconfined) {
+ AppDatabase.instance.clientRecordDao.update(this@apply)
+ }
}
IpNeighbourMonitor.instance?.flush()
if (!wasWorking && item.itemId == R.id.block) {
@@ -150,7 +149,7 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
}
R.id.stats -> {
binding.client?.let { client ->
- launch(Dispatchers.Unconfined) {
+ scope.launch {
StatsDialogFragment().withArg(StatsArg(
client.title.value ?: return@launch,
AppDatabase.instance.trafficRecordDao.queryStats(client.mac)
@@ -205,6 +204,7 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
}
}
+ private val scope = MainScope() + Dispatchers.Unconfined
private lateinit var binding: FragmentClientsBinding
private val adapter = ClientAdapter()
private var rates = HashMap, TrafficRate>()
@@ -237,7 +237,7 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
}
override fun onDestroy() {
- job.cancel()
+ scope.cancel()
super.onDestroy()
}
}
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt
index f8c38527..f23bb7fd 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt
@@ -219,6 +219,6 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
}
holder.config = null
}
- RepeaterService.operatingChannel = config.apChannel
+ if (Build.VERSION.SDK_INT >= 23) RepeaterService.operatingChannel = config.apChannel
}
}
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherManager.kt
index f1a0a1ab..3ca6a172 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherManager.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherManager.kt
@@ -163,7 +163,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
override val type get() = VIEW_TYPE_BLUETOOTH
override val isStarted get() = tethering.active == true
- override fun onException() = ManageBar.start(parent.requireContext())
+ override fun onException() = ManageBar.start(parent.context ?: app)
override fun start() = BluetoothTethering.start(this)
override fun stop() {
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt
index 65161c04..46fb8caf 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt
@@ -105,7 +105,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
}
private fun updateMonitorList(canMonitor: List = emptyList()) {
- val item = requireActivity().toolbar.menu.findItem(R.id.monitor) ?: return // assuming no longer foreground
+ val item = activity?.toolbar?.menu?.findItem(R.id.monitor) ?: return // assuming no longer foreground
item.isNotGone = canMonitor.isNotEmpty()
item.subMenu.apply {
clear()
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt
index 7d9740ac..ca81b80c 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt
@@ -13,7 +13,9 @@ object WifiApManager {
var configuration: WifiConfiguration
get() = getWifiApConfiguration.invoke(app.wifi) as WifiConfiguration
set(value) {
- if (setWifiApConfiguration.invoke(app.wifi, value) as? Boolean != true) throw IllegalArgumentException()
+ if (setWifiApConfiguration.invoke(app.wifi, value) as? Boolean != true) {
+ throw IllegalArgumentException("setWifiApConfiguration failed")
+ }
}
private val setWifiApEnabled by lazy {
diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt
index f0af651c..c08b6b34 100644
--- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt
+++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/configuration/WifiApDialogFragment.kt
@@ -24,6 +24,7 @@ import be.mygod.vpnhotspot.RepeaterService
import be.mygod.vpnhotspot.util.QRCodeDialog
import be.mygod.vpnhotspot.util.toByteArray
import be.mygod.vpnhotspot.util.toParcelable
+import be.mygod.vpnhotspot.widget.SmartSnackbar
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.dialog_wifi_ap.view.*
import java.lang.IllegalStateException
@@ -75,10 +76,11 @@ class WifiApDialogFragment : AlertDialogFragment
private var started = false
+ private val selectedSecurity get() =
+ if (arg.p2pMode) WifiConfiguration.KeyMgmt.WPA_PSK else dialogView.security.selectedItemPosition
override val ret get() = Arg(WifiConfiguration().apply {
SSID = dialogView.ssid.text.toString()
- allowedKeyManagement.set(
- if (arg.p2pMode) WifiConfiguration.KeyMgmt.WPA_PSK else dialogView.security.selectedItemPosition)
+ allowedKeyManagement.set(selectedSecurity)
allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
if (dialogView.password.length() != 0) preSharedKey = dialogView.password.text.toString()
if (Build.VERSION.SDK_INT >= 23) {
@@ -132,7 +134,7 @@ class WifiApDialogFragment : AlertDialogFragment dialogView.password.length() >= 8
else -> true // do not try to validate
}
@@ -181,12 +183,15 @@ class WifiApDialogFragment : AlertDialogFragment {
+ android.R.id.paste -> try {
app.clipboard.primaryClip?.getItemAt(0)?.text?.apply {
Base64.decode(toString(), BASE64_FLAGS).toParcelable()
?.let { populateFromConfiguration(it) }
}
true
+ } catch (e: IllegalArgumentException) {
+ SmartSnackbar.make(e).show()
+ false
}
R.id.share_qr -> {
QRCodeDialog().withArg(ret.configuration.toQRString())
@@ -199,7 +204,7 @@ class WifiApDialogFragment : AlertDialogFragmentWi-Fi директ недоступен, пожалуйста включите Wi-Fi
Не удалось создать группу P2P (причина: %s)
Не удалось удалить группу P2P (причина: %s)
+ Не удалось удалить старую группу P2P (причина:%s)
внутренняя ошибка
Wi-Fi напрямую не поддерживается
@@ -31,12 +32,15 @@
Включите службу для этого интерфейса, чтобы заблокировать клиента.
Разблокировать
Статистика…
+ Сервер вернул ошибку для %1$s: %2$s
Никнэйм для %s
+ Имя вендора
Статистика для %s
VPN-модем активен
VPN модемная служба
+ Неактивных: %s
Неизвестно #%d
Ошибка: Нисходящий интерфейс не найден
@@ -55,7 +59,7 @@
Закрыть
- Считаете это приложение полезным?\\nПоддержите его разработку, отправив пожертвование разработчику!
+ Считаете это приложение полезным?\nПоддержите его разработку, отправив пожертвование разработчику!
Google Play Store
In-App пожертвования не поддерживаются.
Пожертвования через приложение не поддерживаются. Google Play Store установлен правильно?