Update dependencies
This commit is contained in:
@@ -12,7 +12,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.android.tools.build:gradle:4.0.0-alpha08'
|
||||
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
classpath 'io.fabric.tools:gradle:1.31.2'
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
29
gradlew
vendored
29
gradlew
vendored
@@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +175,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# 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" "$@"
|
||||
|
||||
@@ -11,7 +11,7 @@ if (!getGradle().getStartParameter().getTaskRequests().toString().contains("Fdro
|
||||
def javaVersion = JavaVersion.VERSION_1_8
|
||||
def aux = [
|
||||
'com.crashlytics.sdk.android:crashlytics:2.10.1',
|
||||
'com.google.firebase:firebase-analytics:17.2.1',
|
||||
'com.google.firebase:firebase-analytics:17.2.2',
|
||||
]
|
||||
def lifecycleVersion = '2.2.0-rc03'
|
||||
def roomVersion = '2.2.3'
|
||||
@@ -19,6 +19,7 @@ def roomVersion = '2.2.3'
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility javaVersion
|
||||
targetCompatibility javaVersion
|
||||
}
|
||||
@@ -37,6 +38,10 @@ android {
|
||||
]
|
||||
buildConfigField "boolean", "DONATIONS", "true"
|
||||
}
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
viewBinding = true
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
pseudoLocalesEnabled true
|
||||
@@ -47,7 +52,6 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
dataBinding.enabled = true
|
||||
flavorDimensions("freedom")
|
||||
packagingOptions.exclude '**/*.kotlin_*'
|
||||
productFlavors {
|
||||
@@ -73,22 +77,23 @@ androidExtensions {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
|
||||
kapt "androidx.room:room-compiler:$roomVersion"
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.browser:browser:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
implementation 'androidx.emoji:emoji:1.0.0'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.2.0-rc05'
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
|
||||
implementation 'androidx.preference:preference:1.1.0'
|
||||
implementation "androidx.room:room-ktx:$roomVersion"
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
|
||||
implementation 'com.android.billingclient:billing-ktx:2.1.0'
|
||||
implementation 'com.github.topjohnwu.libsu:core:2.5.1'
|
||||
implementation 'com.google.android.material:material:1.1.0-rc01'
|
||||
implementation 'com.google.android.material:material:1.1.0-rc02'
|
||||
implementation 'com.google.zxing:core:3.4.0'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
implementation 'com.linkedin.dexmaker:dexmaker:2.25.1'
|
||||
|
||||
@@ -6,14 +6,13 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Button
|
||||
import android.widget.Spinner
|
||||
import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import be.mygod.vpnhotspot.App.Companion.app
|
||||
import be.mygod.vpnhotspot.databinding.FragmentEbegBinding
|
||||
import be.mygod.vpnhotspot.util.launchUrl
|
||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import com.android.billingclient.api.*
|
||||
import kotlinx.android.synthetic.main.fragment_ebeg.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -65,11 +64,11 @@ class EBegFragment : AppCompatDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var googleSpinner: Spinner
|
||||
private lateinit var binding: FragmentEbegBinding
|
||||
private var skus: List<SkuDetails>? = null
|
||||
set(value) {
|
||||
field = value
|
||||
googleSpinner.apply {
|
||||
binding.donationsGoogleAndroidMarketSpinner.apply {
|
||||
val adapter = ArrayAdapter(context ?: return, android.R.layout.simple_spinner_item,
|
||||
value?.map { it.price } ?: listOf("…"))
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
@@ -77,12 +76,13 @@ class EBegFragment : AppCompatDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
inflater.inflate(R.layout.fragment_ebeg, container, false)
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
binding = FragmentEbegBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
dialog!!.setTitle(R.string.settings_misc_donate)
|
||||
googleSpinner = view.donations__google_android_market_spinner
|
||||
lifecycleScope.launchWhenCreated {
|
||||
billingClient.querySkuDetails(SkuDetailsParams.newBuilder().apply {
|
||||
setSkusList(listOf("donate001", "donate002", "donate005", "donate010", "donate020", "donate050",
|
||||
@@ -95,14 +95,15 @@ class EBegFragment : AppCompatDialogFragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
view.donations__google_android_market_donate_button.setOnClickListener {
|
||||
val sku = skus?.getOrNull(googleSpinner.selectedItemPosition)
|
||||
binding.donationsGoogleAndroidMarketDonateButton.setOnClickListener {
|
||||
val sku = skus?.getOrNull(binding.donationsGoogleAndroidMarketSpinner.selectedItemPosition)
|
||||
if (sku != null) billingClient.launchBillingFlow(requireActivity(), BillingFlowParams.newBuilder().apply {
|
||||
setSkuDetails(sku)
|
||||
}.build()) else SmartSnackbar.make(R.string.donations__google_android_market_not_supported).show()
|
||||
}
|
||||
@Suppress("ConstantConditionIf")
|
||||
if (BuildConfig.DONATIONS) (view.donations__more_stub.inflate() as Button)
|
||||
.setOnClickListener { requireContext().launchUrl("https://mygod.be/donate/") }
|
||||
if (BuildConfig.DONATIONS) (binding.donationsMoreStub.inflate() as Button).setOnClickListener {
|
||||
requireContext().launchUrl("https://mygod.be/donate/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@ package be.mygod.vpnhotspot
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.get
|
||||
import androidx.lifecycle.observe
|
||||
import be.mygod.vpnhotspot.client.ClientViewModel
|
||||
import be.mygod.vpnhotspot.client.ClientsFragment
|
||||
@@ -22,16 +20,15 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import java.net.Inet4Address
|
||||
|
||||
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
val provider by lazy { ViewModelProvider(this) }
|
||||
lateinit var binding: ActivityMainBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
|
||||
binding.lifecycleOwner = this
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
binding.navigation.setOnNavigationItemSelectedListener(this)
|
||||
if (savedInstanceState == null) displayFragment(TetheringFragment())
|
||||
val model = provider.get<ClientViewModel>()
|
||||
val model by viewModels<ClientViewModel>()
|
||||
if (RepeaterService.supported) ServiceForegroundConnector(this, model, RepeaterService::class)
|
||||
model.clients.observe(this) { clients ->
|
||||
val count = clients.count {
|
||||
|
||||
@@ -5,8 +5,6 @@ import android.os.Build
|
||||
import be.mygod.vpnhotspot.App.Companion.app
|
||||
import be.mygod.vpnhotspot.net.Routing
|
||||
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
|
||||
import be.mygod.vpnhotspot.util.putIfAbsentCompat
|
||||
import be.mygod.vpnhotspot.util.removeCompat
|
||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import timber.log.Timber
|
||||
|
||||
@@ -56,7 +54,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p
|
||||
val started get() = active[downstream] === this
|
||||
private var routing: Routing? = null
|
||||
|
||||
fun start() = when (val other = active.putIfAbsentCompat(downstream, this)) {
|
||||
fun start() = when (val other = active.putIfAbsent(downstream, this)) {
|
||||
null -> {
|
||||
if (isWifi) WifiDoubleLock.acquire(this)
|
||||
initRouting()
|
||||
@@ -85,7 +83,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p
|
||||
protected abstract fun Routing.configure()
|
||||
|
||||
fun stop() {
|
||||
if (active.removeCompat(downstream, this)) {
|
||||
if (active.remove(downstream, this)) {
|
||||
if (isWifi) WifiDoubleLock.release(this)
|
||||
routing?.revert()
|
||||
}
|
||||
|
||||
@@ -12,12 +12,11 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.databinding.BaseObservable
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.get
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
@@ -38,7 +37,6 @@ import be.mygod.vpnhotspot.room.ClientStats
|
||||
import be.mygod.vpnhotspot.room.TrafficRecord
|
||||
import be.mygod.vpnhotspot.room.macToString
|
||||
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
|
||||
@@ -182,7 +180,7 @@ class ClientsFragment : Fragment() {
|
||||
val client = getItem(position)
|
||||
holder.binding.client = client
|
||||
holder.binding.rate =
|
||||
rates.computeIfAbsentCompat(Pair(client.iface, client.mac)) { TrafficRate() }
|
||||
rates.computeIfAbsent(Pair(client.iface, client.mac)) { TrafficRate() }
|
||||
holder.binding.executePendingBindings()
|
||||
}
|
||||
|
||||
@@ -197,7 +195,7 @@ class ClientsFragment : Fragment() {
|
||||
check(newRecord.receivedPackets == oldRecord.receivedPackets)
|
||||
check(newRecord.receivedBytes == oldRecord.receivedBytes)
|
||||
} else {
|
||||
val rate = rates.computeIfAbsentCompat(Pair(newRecord.downstream, newRecord.mac)) { TrafficRate() }
|
||||
val rate = rates.computeIfAbsent(Pair(newRecord.downstream, newRecord.mac)) { TrafficRate() }
|
||||
if (rate.send < 0 || rate.receive < 0) {
|
||||
rate.send = 0
|
||||
rate.receive = 0
|
||||
@@ -215,8 +213,7 @@ class ClientsFragment : Fragment() {
|
||||
private var rates = HashMap<Pair<String, Long>, TrafficRate>()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_clients, container, false)
|
||||
binding.lifecycleOwner = this
|
||||
binding = FragmentClientsBinding.inflate(inflater, container, false)
|
||||
binding.clients.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
|
||||
binding.clients.itemAnimator = DefaultItemAnimator()
|
||||
binding.clients.adapter = adapter
|
||||
@@ -224,7 +221,7 @@ class ClientsFragment : Fragment() {
|
||||
binding.swipeRefresher.setOnRefreshListener {
|
||||
IpNeighbourMonitor.instance?.flush()
|
||||
}
|
||||
(activity as MainActivity).provider.get<ClientViewModel>().clients.observe(this) {
|
||||
(activity as MainActivity).viewModels<ClientViewModel>().value.clients.observe(this) {
|
||||
adapter.submitList(it.toMutableList())
|
||||
}
|
||||
return binding.root
|
||||
|
||||
@@ -20,9 +20,8 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.databinding.BaseObservable
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.get
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import be.mygod.vpnhotspot.*
|
||||
import be.mygod.vpnhotspot.databinding.ListitemRepeaterBinding
|
||||
@@ -136,7 +135,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
|
||||
internal var binder: RepeaterService.Binder? = null
|
||||
private var p2pInterface: String? = null
|
||||
@Suppress("DEPRECATION")
|
||||
private val holder = ViewModelProvider(parent).get<ConfigHolder>()
|
||||
private val holder by parent.viewModels<ConfigHolder>()
|
||||
|
||||
override fun bindTo(viewHolder: RecyclerView.ViewHolder) {
|
||||
(viewHolder as ViewHolder).binding.data = data
|
||||
|
||||
@@ -12,7 +12,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
@@ -31,7 +30,6 @@ import be.mygod.vpnhotspot.util.ServiceForegroundConnector
|
||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||
import be.mygod.vpnhotspot.util.isNotGone
|
||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
@@ -107,8 +105,8 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
|
||||
}
|
||||
|
||||
private fun updateMonitorList(canMonitor: List<String> = emptyList()) {
|
||||
val activity = activity
|
||||
val item = activity?.toolbar?.menu?.findItem(R.id.monitor) ?: return // assuming no longer foreground
|
||||
val activity = activity as? MainActivity
|
||||
val item = activity?.binding?.toolbar?.menu?.findItem(R.id.monitor) ?: return // assuming no longer foreground
|
||||
item.isNotGone = canMonitor.isNotEmpty()
|
||||
item.subMenu.apply {
|
||||
clear()
|
||||
@@ -157,14 +155,13 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_tethering, container, false)
|
||||
binding.lifecycleOwner = this
|
||||
binding = FragmentTetheringBinding.inflate(inflater, container, false)
|
||||
binding.interfaces.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
|
||||
binding.interfaces.itemAnimator = DefaultItemAnimator()
|
||||
binding.interfaces.adapter = adapter
|
||||
adapter.update(emptyList(), emptyList(), emptyList())
|
||||
ServiceForegroundConnector(this, this, TetheringService::class)
|
||||
requireActivity().toolbar.apply {
|
||||
(activity as MainActivity).binding.toolbar.apply {
|
||||
inflateMenu(R.menu.toolbar_tethering)
|
||||
setOnMenuItemClickListener(this@TetheringFragment)
|
||||
}
|
||||
@@ -173,7 +170,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
requireActivity().toolbar.apply {
|
||||
(activity as MainActivity).binding.toolbar.apply {
|
||||
menu.clear()
|
||||
setOnMenuItemClickListener(null)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import be.mygod.vpnhotspot.net.monitor.TrafficRecorder
|
||||
import be.mygod.vpnhotspot.net.monitor.UpstreamMonitor
|
||||
import be.mygod.vpnhotspot.room.AppDatabase
|
||||
import be.mygod.vpnhotspot.util.RootSession
|
||||
import be.mygod.vpnhotspot.util.computeIfAbsentCompat
|
||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
@@ -235,7 +234,7 @@ class Routing(private val caller: Any, private val downstream: String) : IpNeigh
|
||||
AppDatabase.instance.clientRecordDao.lookupOrDefaultBlocking(neighbour.lladdr).blocked) continue
|
||||
toRemove.remove(neighbour.ip)
|
||||
try {
|
||||
clients.computeIfAbsentCompat(neighbour.ip) { Client(neighbour.ip, neighbour.lladdr) }
|
||||
clients.computeIfAbsent(neighbour.ip) { Client(neighbour.ip, neighbour.lladdr) }
|
||||
} catch (e: Exception) {
|
||||
Timber.w(e)
|
||||
SmartSnackbar.make(e).show()
|
||||
|
||||
@@ -9,7 +9,6 @@ import be.mygod.vpnhotspot.room.TrafficRecord
|
||||
import be.mygod.vpnhotspot.util.Event2
|
||||
import be.mygod.vpnhotspot.util.RootSession
|
||||
import be.mygod.vpnhotspot.util.parseNumericAddress
|
||||
import be.mygod.vpnhotspot.util.putIfAbsentCompat
|
||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import timber.log.Timber
|
||||
import java.net.InetAddress
|
||||
@@ -29,7 +28,7 @@ object TrafficRecorder {
|
||||
AppDatabase.instance.trafficRecordDao.insert(record)
|
||||
synchronized(this) {
|
||||
DebugHelper.log(TAG, "Registering $ip%$downstream")
|
||||
check(records.putIfAbsentCompat(Pair(ip, downstream), record) == null)
|
||||
check(records.putIfAbsent(Pair(ip, downstream), record) == null)
|
||||
scheduleUpdateLocked()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ import be.mygod.vpnhotspot.AlertDialogFragment
|
||||
import be.mygod.vpnhotspot.App.Companion.app
|
||||
import be.mygod.vpnhotspot.R
|
||||
import be.mygod.vpnhotspot.RepeaterService
|
||||
import be.mygod.vpnhotspot.databinding.DialogWifiApBinding
|
||||
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.nio.charset.Charset
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var dialogView: View
|
||||
private lateinit var dialogView: DialogWifiApBinding
|
||||
private lateinit var bandOptions: MutableList<BandOption>
|
||||
private var started = false
|
||||
private val selectedSecurity get() =
|
||||
@@ -92,14 +92,14 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
override fun AlertDialog.Builder.prepare(listener: DialogInterface.OnClickListener) {
|
||||
val activity = requireActivity()
|
||||
@SuppressLint("InflateParams")
|
||||
dialogView = activity.layoutInflater.inflate(R.layout.dialog_wifi_ap, null)
|
||||
setView(dialogView)
|
||||
dialogView = DialogWifiApBinding.inflate(activity.layoutInflater)
|
||||
setView(dialogView.root)
|
||||
if (!arg.readOnly) setPositiveButton(R.string.wifi_save, listener)
|
||||
setNegativeButton(R.string.donations__button_close, null)
|
||||
dialogView.toolbar.inflateMenu(R.menu.toolbar_configuration)
|
||||
dialogView.toolbar.setOnMenuItemClickListener(this@WifiApDialogFragment)
|
||||
if (!arg.readOnly) dialogView.ssid.addTextChangedListener(this@WifiApDialogFragment)
|
||||
if (arg.p2pMode) dialogView.security_wrapper.isGone = true else dialogView.security.apply {
|
||||
if (arg.p2pMode) dialogView.securityWrapper.isGone = true else dialogView.security.apply {
|
||||
adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0,
|
||||
WifiConfiguration.KeyMgmt.strings).apply {
|
||||
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
@@ -107,7 +107,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) = error("Must select something")
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
dialogView.password_wrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE
|
||||
dialogView.passwordWrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
setSelection(bandOptions.indexOfFirst { it.apChannel == RepeaterService.operatingChannel })
|
||||
}
|
||||
} else dialogView.band_wrapper.isGone = true
|
||||
} else dialogView.bandWrapper.isGone = true
|
||||
populateFromConfiguration(arg.configuration)
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
||||
WifiConfiguration.KeyMgmt.WPA_PSK, WPA2_PSK -> dialogView.password.length() >= 8
|
||||
else -> true // do not try to validate
|
||||
}
|
||||
dialogView.password_wrapper.error = if (passwordValid) null else {
|
||||
dialogView.passwordWrapper.error = if (passwordValid) null else {
|
||||
requireContext().getString(R.string.credentials_password_too_short)
|
||||
}
|
||||
(dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = ssidValid && passwordValid
|
||||
|
||||
@@ -123,15 +123,3 @@ var MenuItem.isNotGone: Boolean
|
||||
isVisible = value
|
||||
isEnabled = value
|
||||
}
|
||||
|
||||
fun <K, V> MutableMap<K, V>.computeIfAbsentCompat(key: K, value: () -> V) = if (Build.VERSION.SDK_INT >= 24)
|
||||
computeIfAbsent(key) { value() } else this[key] ?: value().also { put(key, it) }
|
||||
fun <K, V> MutableMap<K, V>.putIfAbsentCompat(key: K, value: V) = if (Build.VERSION.SDK_INT >= 24)
|
||||
putIfAbsent(key, value) else this[key] ?: put(key, value)
|
||||
fun <K, V> MutableMap<K, V>.removeCompat(key: K, value: V) = if (Build.VERSION.SDK_INT >= 24) remove(key, value) else {
|
||||
val curValue = get(key)
|
||||
if (curValue === value && (curValue != null || containsKey(key))) {
|
||||
remove(key)
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<LinearLayout
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
@@ -46,5 +44,3 @@
|
||||
tools:ignore="PxUsage"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</layout>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
tools:viewBindingIgnore="true">
|
||||
<androidx.emoji.widget.EmojiEditText
|
||||
android:id="@android:id/edit"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
tools:viewBindingIgnore="true">
|
||||
<EditText
|
||||
android:id="@android:id/edit"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/swipeRefresher"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
@@ -16,4 +14,3 @@
|
||||
android:scrollbars="vertical"
|
||||
tools:listitem="@layout/listitem_client"/>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</layout>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<Button
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/donations__more_donate_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/settings_misc_donate_more"/>
|
||||
android:text="@string/settings_misc_donate_more"
|
||||
tools:viewBindingIgnore="true"/>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/interfaces"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbars="vertical"
|
||||
tools:listitem="@layout/listitem_interface"/>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user