Add manual MAC lookup

This commit is contained in:
Mygod
2019-01-31 17:10:26 +08:00
parent 73d29cba20
commit 509511461c
5 changed files with 32 additions and 9 deletions

View File

@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot
import android.annotation.SuppressLint
import android.app.Application
import android.app.UiModeManager
import android.content.SharedPreferences
import android.content.res.Configuration
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
@@ -16,6 +15,7 @@ import be.mygod.vpnhotspot.room.AppDatabase
import be.mygod.vpnhotspot.util.DeviceStorageApp
import be.mygod.vpnhotspot.util.Event0
import be.mygod.vpnhotspot.util.RootSession
import java.util.*
class App : Application() {
companion object {
@@ -48,7 +48,12 @@ class App : Application() {
}
lateinit var deviceStorage: Application
val pref: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(deviceStorage) }
val english by lazy {
createConfigurationContext(Configuration(resources.configuration).apply {
setLocale(Locale.ENGLISH)
})
}
val pref by lazy { PreferenceManager.getDefaultSharedPreferences(deviceStorage) }
val connectivity by lazy { getSystemService<ConnectivityManager>()!! }
val uiMode by lazy { getSystemService<UiModeManager>()!! }
val wifi by lazy { getSystemService<WifiManager>()!! }

View File

@@ -55,6 +55,7 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
setTitle(getString(R.string.clients_nickname_title, arg.mac.macToString()))
setPositiveButton(android.R.string.ok, listener)
setNegativeButton(android.R.string.cancel, null)
setNeutralButton(R.string.clients_nickname_set_to_vendor, listener)
}
override fun onCreateDialog(savedInstanceState: Bundle?) = super.onCreateDialog(savedInstanceState).apply {
@@ -63,11 +64,14 @@ class ClientsFragment : Fragment(), MainScope by MainScope.Supervisor() {
}
override fun onClick(dialog: DialogInterface?, which: Int) {
GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {
MacLookup.abort(arg.mac)
AppDatabase.instance.clientRecordDao.upsert(arg.mac) {
nickname = this@NicknameDialogFragment.dialog!!.findViewById<EditText>(android.R.id.edit).text
when (which) {
DialogInterface.BUTTON_POSITIVE -> GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) {
MacLookup.abort(arg.mac)
AppDatabase.instance.clientRecordDao.upsert(arg.mac) {
nickname = this@NicknameDialogFragment.dialog!!.findViewById<EditText>(android.R.id.edit).text
}
}
DialogInterface.BUTTON_NEUTRAL -> MacLookup.perform(arg.mac, true)
}
}
}

View File

@@ -1,8 +1,12 @@
package be.mygod.vpnhotspot.client
import android.content.Context
import androidx.annotation.MainThread
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.room.AppDatabase
import be.mygod.vpnhotspot.room.macToString
import be.mygod.vpnhotspot.widget.SmartSnackbar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
@@ -18,8 +22,12 @@ import java.net.URL
* This class generates a default nickname for new clients.
*/
object MacLookup {
class UnexpectedError(mac: Long, val error: String) :
JSONException("Server returned error for ${mac.macToString()}: $error")
class UnexpectedError(val mac: Long, val error: String) : JSONException("") {
private fun formatMessage(context: Context) =
context.getString(R.string.clients_mac_lookup_unexpected_error, mac.macToString(), error)
override val message get() = formatMessage(app.english)
override fun getLocalizedMessage() = formatMessage(app)
}
private val macLookupBusy = mutableMapOf<Long, Pair<HttpURLConnection, Job>>()
private val countryCodeRegex = "[A-Z]{2}".toRegex() // http://en.wikipedia.org/wiki/ISO_3166-1
@@ -31,7 +39,7 @@ object MacLookup {
}
@MainThread
fun perform(mac: Long) {
fun perform(mac: Long, explicit: Boolean = false) {
abort(mac)
val conn = URL("https://macvendors.co/api/" + mac.macToString()).openConnection() as HttpURLConnection
macLookupBusy[mac] = conn to GlobalScope.launch(Dispatchers.IO) {
@@ -50,11 +58,13 @@ object MacLookup {
}
} catch (e: IOException) {
Timber.d(e)
if (explicit) SmartSnackbar.make(e).show()
} catch (e: JSONException) {
if ((e as? UnexpectedError)?.error == "no result") {
// no vendor found, we should not retry in the future
AppDatabase.instance.clientRecordDao.upsert(mac) { macLookupPending = false }
} else Timber.w(e)
if (explicit) SmartSnackbar.make(e).show()
}
}
}