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 установлен правильно?