Add more logging

This commit is contained in:
Mygod
2018-06-10 20:26:36 +08:00
parent 55e8b684df
commit e2cbe18ea9
18 changed files with 76 additions and 18 deletions

View File

@@ -14,6 +14,7 @@
# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-dontobfuscate

View File

@@ -11,6 +11,7 @@ import be.mygod.vpnhotspot.net.IpNeighbourMonitor
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.util.broadcastReceiver
import be.mygod.vpnhotspot.util.debugLog
import com.crashlytics.android.Crashlytics
@RequiresApi(26)
class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
@@ -91,6 +92,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
}, app.handler)
} catch (e: IllegalStateException) {
e.printStackTrace()
Crashlytics.logException(e)
}
return START_STICKY
}

View File

@@ -4,6 +4,7 @@ import android.widget.Toast
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.net.Routing
import be.mygod.vpnhotspot.net.UpstreamMonitor
import com.crashlytics.android.Crashlytics
import java.net.InetAddress
import java.net.SocketException
@@ -49,6 +50,7 @@ class LocalOnlyInterfaceManager(val downstream: String, private val owner: InetA
app.toast(R.string.noisy_su_failure)
} catch (e: SocketException) {
Toast.makeText(app, e.message, Toast.LENGTH_SHORT).show()
Crashlytics.logException(e)
routing = null
}
}

View File

@@ -21,6 +21,7 @@ import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.requestPersistentGroupI
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.setWifiP2pChannels
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.startWps
import be.mygod.vpnhotspot.util.*
import com.crashlytics.android.Crashlytics
import java.lang.reflect.InvocationTargetException
import java.net.InetAddress
@@ -79,6 +80,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
})
} catch (e: ReflectiveOperationException) {
e.printStackTrace()
Crashlytics.logException(e)
Toast.makeText(this@RepeaterService, e.message, Toast.LENGTH_LONG).show()
}
}
@@ -129,6 +131,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
app.pref.registerOnSharedPreferenceChangeListener(this)
} catch (exc: TypeCastException) {
exc.printStackTrace()
Crashlytics.logException(exc)
}
}
@@ -147,6 +150,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
if (oc != 0)
Toast.makeText(this, getString(R.string.repeater_set_oc_failure, e.message), Toast.LENGTH_SHORT).show()
e.printStackTrace()
Crashlytics.logException(e)
}
override fun onChannelDisconnected() {
@@ -179,7 +183,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
it == null -> doStart()
it.isGroupOwner -> if (routingManager == null) doStart(it)
else -> {
Log.i(TAG, "Removing old group ($it)")
Crashlytics.log(Log.INFO, TAG, "Removing old group ($it)")
p2pManager.removeGroup(channel, object : WifiP2pManager.ActionListener {
override fun onSuccess() = doStart()
override fun onFailure(reason: Int) {

View File

@@ -17,6 +17,7 @@ import be.mygod.vpnhotspot.preference.AlwaysAutoCompleteEditTextPreferenceDialog
import be.mygod.vpnhotspot.preference.SharedPreferenceDataStore
import be.mygod.vpnhotspot.util.loggerSuStream
import be.mygod.vpnhotspot.util.put
import com.crashlytics.android.Crashlytics
import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompatDividers
import java.io.File
import java.io.IOException
@@ -53,6 +54,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompatDividers() {
Runtime.getRuntime().exec(arrayOf("logcat", "-d")).inputStream.use { it.copyTo(out) }
} catch (e: IOException) {
e.printStackTrace(writer)
Crashlytics.logException(e)
}
writer.write("\n")
writer.flush()
@@ -82,6 +84,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompatDividers() {
loggerSuStream(commands.toString())?.use { it.copyTo(out) }
} catch (e: IOException) {
e.printStackTrace(writer)
Crashlytics.logException(e)
writer.flush()
}
}
@@ -110,6 +113,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompatDividers() {
.map { it.name }.sorted().toList().toTypedArray()
} catch (e: SocketException) {
e.printStackTrace()
Crashlytics.logException(e)
emptyArray<String>()
}))
else -> super.onDisplayPreferenceDialog(preference)

View File

@@ -10,6 +10,7 @@ import be.mygod.vpnhotspot.net.Routing
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.net.UpstreamMonitor
import be.mygod.vpnhotspot.util.broadcastReceiver
import com.crashlytics.android.Crashlytics
import java.net.InetAddress
import java.net.SocketException
@@ -56,6 +57,7 @@ class TetheringService : IpNeighbourMonitoringService(), UpstreamMonitor.Callbac
if (!routing.start()) failed = true
} catch (e: SocketException) {
e.printStackTrace()
Crashlytics.logException(e)
routings.remove(downstream)
failed = true
}

View File

@@ -18,6 +18,7 @@ import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
import be.mygod.vpnhotspot.net.TetherType
import be.mygod.vpnhotspot.util.ServiceForegroundConnector
import be.mygod.vpnhotspot.util.formatAddresses
import com.crashlytics.android.Crashlytics
import java.net.NetworkInterface
@TargetApi(26)
@@ -52,6 +53,7 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
view.context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
} catch (exc: ActivityNotFoundException) {
exc.printStackTrace()
Crashlytics.logException(exc)
}
return
}

View File

@@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.support.v7.widget.RecyclerView
import android.view.View
import com.crashlytics.android.Crashlytics
object ManageBar : Manager() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
@@ -25,8 +26,11 @@ object ManageBar : Manager() {
try {
context.startActivity(Intent()
.setClassName("com.android.settings", "com.android.settings.TetherSettings"))
e.printStackTrace()
Crashlytics.logException(e)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
Crashlytics.logException(e)
}
}
}

View File

@@ -26,6 +26,7 @@ import be.mygod.vpnhotspot.net.wifi.P2pSupplicantConfiguration
import be.mygod.vpnhotspot.net.wifi.WifiP2pDialog
import be.mygod.vpnhotspot.util.ServiceForegroundConnector
import be.mygod.vpnhotspot.util.formatAddresses
import com.crashlytics.android.Crashlytics
import java.net.NetworkInterface
import java.net.SocketException
@@ -49,6 +50,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
NetworkInterface.getByName(p2pInterface ?: return "")?.formatAddresses() ?: ""
} catch (e: SocketException) {
e.printStackTrace()
Crashlytics.logException(e)
""
}
}

View File

@@ -22,6 +22,7 @@ import be.mygod.vpnhotspot.databinding.ListitemManageTetherBinding
import be.mygod.vpnhotspot.net.TetherType
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.net.wifi.WifiApManager
import com.crashlytics.android.Crashlytics
import java.lang.reflect.InvocationTargetException
abstract class TetherManager private constructor(protected val parent: TetheringFragment) : Manager(),
@@ -47,12 +48,14 @@ abstract class TetherManager private constructor(protected val parent: Tethering
return
} catch (exc: ActivityNotFoundException) {
exc.printStackTrace()
Crashlytics.logException(exc)
}
val started = manager.isStarted
try {
if (started) manager.stop() else manager.start()
} catch (e: InvocationTargetException) {
e.printStackTrace()
Crashlytics.logException(e)
var cause: Throwable? = e
while (cause != null) {
cause = cause.cause

View File

@@ -26,6 +26,7 @@ import be.mygod.vpnhotspot.net.TetherType
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.util.ServiceForegroundConnector
import be.mygod.vpnhotspot.util.broadcastReceiver
import com.crashlytics.android.Crashlytics
import java.net.NetworkInterface
import java.net.SocketException
@@ -51,6 +52,7 @@ class TetheringFragment : Fragment(), ServiceConnection {
NetworkInterface.getNetworkInterfaces().asSequence().associateBy { it.name }
} catch (e: SocketException) {
e.printStackTrace()
Crashlytics.logException(e)
emptyMap()
}
this@TetheringFragment.enabledTypes =

View File

@@ -4,12 +4,15 @@ import android.util.Log
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.util.thread
import com.crashlytics.android.Crashlytics
import java.io.InterruptedIOException
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
abstract class IpMonitor : Runnable {
private class MonitorFailure : RuntimeException()
private class FlushFailure : RuntimeException()
protected abstract val monitoredObject: String
protected abstract fun processLine(line: String)
protected abstract fun processLines(lines: Sequence<String>)
@@ -27,14 +30,17 @@ abstract class IpMonitor : Runnable {
this.monitor = monitor
thread("${javaClass.simpleName}-error") {
try {
monitor.errorStream.bufferedReader().forEachLine { Log.e(javaClass.simpleName, it) }
monitor.errorStream.bufferedReader().forEachLine {
Crashlytics.log(Log.ERROR, javaClass.simpleName, it)
}
} catch (_: InterruptedIOException) { }
}
try {
monitor.inputStream.bufferedReader().forEachLine(this::processLine)
monitor.waitFor()
if (monitor.exitValue() == 0) return@thread
Log.w(javaClass.simpleName, "Failed to set up monitor, switching to polling")
Crashlytics.log(Log.WARN, javaClass.simpleName, "Failed to set up monitor, switching to polling")
Crashlytics.logException(MonitorFailure())
val pool = Executors.newScheduledThreadPool(1)
pool.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS)
this.pool = pool
@@ -52,7 +58,8 @@ abstract class IpMonitor : Runnable {
thread("${javaClass.simpleName}-flush-error") {
val err = process.errorStream.bufferedReader().readText()
if (err.isNotBlank()) {
Log.e(javaClass.simpleName, err)
Crashlytics.log(Log.ERROR, javaClass.simpleName, err)
Crashlytics.logException(FlushFailure())
app.toast(R.string.noisy_su_failure)
}
}

View File

@@ -1,6 +1,7 @@
package be.mygod.vpnhotspot.net
import android.util.Log
import com.crashlytics.android.Crashlytics
import java.io.File
import java.io.IOException
@@ -25,7 +26,7 @@ data class IpNeighbour(val ip: String, val dev: String, val lladdr: String, val
fun parse(line: String): IpNeighbour? {
val match = parser.matchEntire(line)
if (match == null) {
if (line.isNotEmpty()) Log.w(TAG, line)
if (line.isNotEmpty()) Crashlytics.log(Log.WARN, TAG, line)
return null
}
val ip = match.groupValues[2]
@@ -43,7 +44,7 @@ data class IpNeighbour(val ip: String, val dev: String, val lladdr: String, val
"FAILED" -> State.FAILED
"NOARP" -> return null // skip
else -> {
Log.w(TAG, "Unknown state encountered: ${match.groupValues[10]}")
Crashlytics.log(Log.WARN, TAG, "Unknown state encountered: ${match.groupValues[10]}")
return null
}
}
@@ -70,6 +71,7 @@ data class IpNeighbour(val ip: String, val dev: String, val lladdr: String, val
}
} catch (e: IOException) {
e.printStackTrace()
Crashlytics.logException(e)
}
return arpCache
}

View File

@@ -9,6 +9,7 @@ import android.support.annotation.RequiresApi
import android.util.Log
import be.mygod.vpnhotspot.App.Companion.app
import com.android.dx.stock.ProxyBuilder
import com.crashlytics.android.Crashlytics
/**
* Heavily based on:
@@ -91,7 +92,7 @@ object TetheringManager {
val proxy = ProxyBuilder.forClass(classOnStartTetheringCallback)
.dexCache(app.cacheDir)
.handler { proxy, method, args ->
if (args.isNotEmpty()) Log.w(TAG, "Unexpected args for ${method.name}: $args")
if (args.isNotEmpty()) Crashlytics.log(Log.WARN, TAG, "Unexpected args for ${method.name}: $args")
when (method.name) {
"onTetheringStarted" -> {
callback.onTetheringStarted()
@@ -102,7 +103,7 @@ object TetheringManager {
null
}
else -> {
Log.w(TAG, "Unexpected method, calling super: $method")
Crashlytics.log(Log.WARN, TAG, "Unexpected method, calling super: $method")
ProxyBuilder.callSuper(proxy, method, args)
}
}

View File

@@ -7,6 +7,7 @@ import android.widget.Toast
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.util.loggerSu
import be.mygod.vpnhotspot.util.noisySu
import com.crashlytics.android.Crashlytics
import java.io.File
class P2pSupplicantConfiguration {
@@ -34,8 +35,9 @@ class P2pSupplicantConfiguration {
check(result.length in 8..63)
result
} catch (e: RuntimeException) {
Log.w(TAG, content)
Crashlytics.log(Log.WARN, TAG, content)
e.printStackTrace()
Crashlytics.logException(e)
Toast.makeText(app, e.message, Toast.LENGTH_LONG).show()
null
}
@@ -61,7 +63,9 @@ class P2pSupplicantConfiguration {
else -> line // do nothing
})
}
if (ssidFound != 1 || pskFound != 1) Log.w(TAG, "Invalid conf ($ssidFound, $pskFound): $content")
if (ssidFound != 1 || pskFound != 1) {
Crashlytics.log(Log.WARN, TAG, "Invalid conf ($ssidFound, $pskFound): $content")
}
if (ssidFound == 0 || pskFound == 0) return false
// pkill not available on Lollipop. Source: https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md
return noisySu("cat ${tempFile.absolutePath} > /data/misc/wifi/p2p_supplicant.conf",

View File

@@ -6,6 +6,7 @@ import android.net.wifi.p2p.WifiP2pGroup
import android.net.wifi.p2p.WifiP2pManager
import android.util.Log
import com.android.dx.stock.ProxyBuilder
import com.crashlytics.android.Crashlytics
import java.lang.reflect.Proxy
import java.util.regex.Pattern
@@ -88,11 +89,11 @@ object WifiP2pManagerHelper {
val proxy = Proxy.newProxyInstance(interfacePersistentGroupInfoListener.classLoader,
arrayOf(interfacePersistentGroupInfoListener), { proxy, method, args ->
if (method.name == "onPersistentGroupInfoAvailable") {
if (args.size != 1) Log.w(TAG, "Unexpected args: $args")
if (args.size != 1) Crashlytics.log(Log.WARN, TAG, "Unexpected args: $args")
listener(getGroupList.invoke(args[0]) as Collection<WifiP2pGroup>)
null
} else {
Log.w(TAG, "Unexpected method, calling super: $method")
Crashlytics.log(Log.WARN, TAG, "Unexpected method, calling super: $method")
ProxyBuilder.callSuper(proxy, method, args)
}
})

View File

@@ -1,29 +1,34 @@
package be.mygod.vpnhotspot.util
import android.util.Log
import be.mygod.vpnhotspot.App
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.R
import com.crashlytics.android.Crashlytics
import java.io.IOException
import java.io.InputStream
private const val NOISYSU_TAG = "NoisySU"
private const val NOISYSU_SUFFIX = "SUCCESS\n"
private class SuFailure : RuntimeException()
fun loggerSuStream(command: String): InputStream? {
val process = try {
ProcessBuilder("su", "-c", command)
.redirectErrorStream(true)
.directory(App.app.deviceContext.cacheDir)
.directory(app.deviceContext.cacheDir)
.start()
} catch (e: IOException) {
e.printStackTrace()
Crashlytics.logException(e)
return null
}
thread("LoggerSU-error") {
val err = process.errorStream.bufferedReader().readText()
if (err.isNotBlank()) {
Log.e(NOISYSU_TAG, err)
App.app.toast(R.string.noisy_su_failure)
Crashlytics.log(Log.ERROR, NOISYSU_TAG, err)
Crashlytics.logException(SuFailure())
app.toast(R.string.noisy_su_failure)
}
}
return process.inputStream
@@ -35,6 +40,7 @@ fun loggerSu(command: String): String? {
stream.bufferedReader().readText()
} catch (e: IOException) {
e.printStackTrace()
Crashlytics.logException(e)
null
}
}
@@ -45,7 +51,10 @@ ${commands.joinToString("\n") { if (it.startsWith("quiet ")) it.substring(6) els
echo $NOISYSU_SUFFIX""")
val result = if (out == null) null else out == NOISYSU_SUFFIX
out = out?.removeSuffix(NOISYSU_SUFFIX)
if (!out.isNullOrBlank()) Log.i(NOISYSU_TAG, out)
if (!out.isNullOrBlank()) {
Crashlytics.log(Log.INFO, NOISYSU_TAG, out)
Crashlytics.logException(SuFailure())
}
return result
}
fun noisySu(vararg commands: String) = noisySu(commands.asIterable())

View File

@@ -10,11 +10,13 @@ import android.widget.ImageView
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.BuildConfig
import be.mygod.vpnhotspot.R
import com.crashlytics.android.Crashlytics
import java.net.NetworkInterface
import java.net.SocketException
fun debugLog(tag: String?, message: String?) {
if (BuildConfig.DEBUG) Log.d(tag, message)
Crashlytics.log("$tag: $message")
}
fun broadcastReceiver(receiver: (Context, Intent) -> Unit) = object : BroadcastReceiver() {
@@ -48,6 +50,7 @@ fun NetworkInterface.formatAddresses() =
hardwareAddress?.joinToString(":") { "%02x".format(it) }
} catch (e: SocketException) {
e.printStackTrace()
Crashlytics.logException(e)
null
}))
.joinToString("\n")
@@ -58,7 +61,10 @@ fun NetworkInterface.formatAddresses() =
fun thread(name: String? = null, start: Boolean = true, isDaemon: Boolean = false,
contextClassLoader: ClassLoader? = null, priority: Int = -1, block: () -> Unit): Thread {
val thread = kotlin.concurrent.thread(false, isDaemon, contextClassLoader, name, priority, block)
thread.setUncaughtExceptionHandler { _, _ -> app.toast(R.string.noisy_su_failure) }
thread.setUncaughtExceptionHandler { _, e ->
app.toast(R.string.noisy_su_failure)
Crashlytics.logException(e)
}
if (start) thread.start()
return thread
}