Migrate to open source firebase-crashlytics
This commit is contained in:
@@ -7,15 +7,12 @@ buildscript {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
maven {
|
|
||||||
url 'https://maven.fabric.io/public'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.0.0-alpha09'
|
classpath 'com.android.tools.build:gradle:4.0.0-alpha09'
|
||||||
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
|
classpath 'com.github.ben-manes:gradle-versions-plugin:0.27.0'
|
||||||
|
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta01'
|
||||||
classpath 'com.google.gms:google-services:4.3.3'
|
classpath 'com.google.gms:google-services:4.3.3'
|
||||||
classpath 'io.fabric.tools:gradle:1.31.2'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,11 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
|
|
||||||
if (!getGradle().getStartParameter().getTaskRequests().toString().contains("Fdroid")) {
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
apply plugin: 'io.fabric'
|
|
||||||
}
|
|
||||||
|
|
||||||
def javaVersion = JavaVersion.VERSION_1_8
|
def javaVersion = JavaVersion.VERSION_1_8
|
||||||
def aux = [
|
|
||||||
'com.crashlytics.sdk.android:crashlytics:2.10.1',
|
|
||||||
'com.google.firebase:firebase-analytics:17.2.2',
|
|
||||||
]
|
|
||||||
def lifecycleVersion = '2.2.0'
|
|
||||||
def roomVersion = '2.2.3'
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
@@ -29,8 +20,8 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
resConfigs 'it', 'ru', 'zh-rCN'
|
resConfigs 'it', 'ru', 'zh-rCN'
|
||||||
versionCode 220
|
versionCode 221
|
||||||
versionName '2.7.1'
|
versionName '2.7.2'
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
javaCompileOptions.annotationProcessorOptions.arguments = [
|
javaCompileOptions.annotationProcessorOptions.arguments = [
|
||||||
"room.incremental": "true",
|
"room.incremental": "true",
|
||||||
@@ -55,12 +46,8 @@ android {
|
|||||||
flavorDimensions("freedom")
|
flavorDimensions("freedom")
|
||||||
packagingOptions.exclude '**/*.kotlin_*'
|
packagingOptions.exclude '**/*.kotlin_*'
|
||||||
productFlavors {
|
productFlavors {
|
||||||
fdroid {
|
|
||||||
dimension "freedom"
|
|
||||||
}
|
|
||||||
freedom {
|
freedom {
|
||||||
dimension "freedom"
|
dimension "freedom"
|
||||||
isDefault = true
|
|
||||||
}
|
}
|
||||||
google {
|
google {
|
||||||
dimension "freedom"
|
dimension "freedom"
|
||||||
@@ -76,6 +63,8 @@ androidExtensions {
|
|||||||
experimental = true
|
experimental = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def lifecycleVersion = '2.2.0'
|
||||||
|
def roomVersion = '2.2.3'
|
||||||
dependencies {
|
dependencies {
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
|
||||||
kapt "androidx.room:room-compiler:$roomVersion"
|
kapt "androidx.room:room-compiler:$roomVersion"
|
||||||
@@ -93,6 +82,8 @@ dependencies {
|
|||||||
implementation 'com.android.billingclient:billing-ktx:2.1.0'
|
implementation 'com.android.billingclient:billing-ktx:2.1.0'
|
||||||
implementation 'com.github.topjohnwu.libsu:core:2.5.1'
|
implementation 'com.github.topjohnwu.libsu:core:2.5.1'
|
||||||
implementation 'com.google.android.material:material:1.1.0-rc02'
|
implementation 'com.google.android.material:material:1.1.0-rc02'
|
||||||
|
implementation 'com.google.firebase:firebase-analytics:17.2.2'
|
||||||
|
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta01'
|
||||||
implementation 'com.google.zxing:core:3.4.0'
|
implementation 'com.google.zxing:core:3.4.0'
|
||||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||||
implementation 'com.linkedin.dexmaker:dexmaker:2.25.1'
|
implementation 'com.linkedin.dexmaker:dexmaker:2.25.1'
|
||||||
@@ -100,10 +91,6 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3'
|
implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3'
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
||||||
for (dep in aux) {
|
|
||||||
freedomImplementation dep
|
|
||||||
googleImplementation dep
|
|
||||||
}
|
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13'
|
||||||
androidTestImplementation "androidx.room:room-testing:$roomVersion"
|
androidTestImplementation "androidx.room:room-testing:$roomVersion"
|
||||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package be.mygod.vpnhotspot
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.annotation.Size
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
object DebugHelper {
|
|
||||||
fun init() = Timber.plant(Timber.DebugTree())
|
|
||||||
fun log(tag: String?, message: String?) = Timber.tag(tag).d(message)
|
|
||||||
fun setString(key: String, value: String?) = Timber.tag(key).d(value)
|
|
||||||
fun logEvent(@Size(min = 1L, max = 40L) event: String, extras: Bundle? = null) =
|
|
||||||
Timber.tag("logEvent").d("$event: $extras")
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package be.mygod.vpnhotspot
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.annotation.Size
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
|
||||||
import com.crashlytics.android.Crashlytics
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
|
||||||
import io.fabric.sdk.android.Fabric
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
object DebugHelper {
|
|
||||||
private val analytics by lazy { FirebaseAnalytics.getInstance(app.deviceStorage) }
|
|
||||||
|
|
||||||
fun init() {
|
|
||||||
Fabric.with(app.deviceStorage, Crashlytics())
|
|
||||||
Timber.plant(object : Timber.DebugTree() {
|
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
|
||||||
if (t == null) Crashlytics.log(priority, tag, message) else {
|
|
||||||
// Crashlytics.logException doesn't print to logcat
|
|
||||||
if (priority >= Log.WARN || priority == Log.DEBUG) Log.println(priority, tag, message)
|
|
||||||
if (priority >= Log.INFO) Crashlytics.logException(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun log(tag: String?, message: String?) {
|
|
||||||
if (BuildConfig.DEBUG) Timber.tag(tag).d(message) else Crashlytics.log("$tag: $message")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setString(key: String, value: String?) = Crashlytics.setString(key, value)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to log "expected" and well-handled errors, i.e. we care less about logs, etc.
|
|
||||||
* logException is inappropriate sometimes because it flushes all logs that could be used to investigate other bugs.
|
|
||||||
*/
|
|
||||||
fun logEvent(@Size(min = 1L, max = 40L) event: String, extras: Bundle? = null) {
|
|
||||||
Timber.i(if (extras == null) event else "$event, extras: $extras")
|
|
||||||
analytics.logEvent(event, extras)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
freedom
|
|
||||||
@@ -168,8 +168,7 @@
|
|||||||
android:resource="@xml/log_paths" />
|
android:resource="@xml/log_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<provider android:name="com.crashlytics.android.CrashlyticsInitProvider"
|
<provider android:name="com.google.firebase.provider.FirebaseInitProvider"
|
||||||
tools:ignore="MissingClass"
|
|
||||||
tools:node="remove"/>
|
tools:node="remove"/>
|
||||||
<service android:name="com.google.firebase.components.ComponentDiscoveryService"
|
<service android:name="com.google.firebase.components.ComponentDiscoveryService"
|
||||||
android:directBootAware="true"
|
android:directBootAware="true"
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import android.content.res.Configuration
|
|||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.Size
|
||||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
@@ -20,6 +23,9 @@ import be.mygod.vpnhotspot.net.DhcpWorkaround
|
|||||||
import be.mygod.vpnhotspot.room.AppDatabase
|
import be.mygod.vpnhotspot.room.AppDatabase
|
||||||
import be.mygod.vpnhotspot.util.DeviceStorageApp
|
import be.mygod.vpnhotspot.util.DeviceStorageApp
|
||||||
import be.mygod.vpnhotspot.util.RootSession
|
import be.mygod.vpnhotspot.util.RootSession
|
||||||
|
import com.google.firebase.FirebaseApp
|
||||||
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@@ -40,7 +46,18 @@ class App : Application() {
|
|||||||
deviceStorage.moveSharedPreferencesFrom(this, PreferenceManager(this).sharedPreferencesName)
|
deviceStorage.moveSharedPreferencesFrom(this, PreferenceManager(this).sharedPreferencesName)
|
||||||
deviceStorage.moveDatabaseFrom(this, AppDatabase.DB_NAME)
|
deviceStorage.moveDatabaseFrom(this, AppDatabase.DB_NAME)
|
||||||
} else deviceStorage = this
|
} else deviceStorage = this
|
||||||
DebugHelper.init()
|
FirebaseApp.initializeApp(deviceStorage)
|
||||||
|
Timber.plant(object : Timber.DebugTree() {
|
||||||
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
|
if (t == null) {
|
||||||
|
if (priority != Log.DEBUG || BuildConfig.DEBUG) Log.println(priority, tag, message)
|
||||||
|
crashlytics.log("${"XXVDIWEF".getOrElse(priority) { 'X' }}/$tag: $message")
|
||||||
|
} else {
|
||||||
|
if (priority >= Log.WARN || priority == Log.DEBUG) Log.println(priority, tag, message)
|
||||||
|
if (priority >= Log.INFO) crashlytics.recordException(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
ServiceNotification.updateNotificationChannels()
|
ServiceNotification.updateNotificationChannels()
|
||||||
EmojiCompat.init(FontRequestEmojiCompatConfig(deviceStorage, FontRequest(
|
EmojiCompat.init(FontRequestEmojiCompatConfig(deviceStorage, FontRequest(
|
||||||
"com.google.android.gms.fonts",
|
"com.google.android.gms.fonts",
|
||||||
@@ -49,7 +66,7 @@ class App : Application() {
|
|||||||
R.array.com_google_android_gms_fonts_certs)).apply {
|
R.array.com_google_android_gms_fonts_certs)).apply {
|
||||||
setEmojiSpanIndicatorEnabled(BuildConfig.DEBUG)
|
setEmojiSpanIndicatorEnabled(BuildConfig.DEBUG)
|
||||||
registerInitCallback(object : EmojiCompat.InitCallback() {
|
registerInitCallback(object : EmojiCompat.InitCallback() {
|
||||||
override fun onInitialized() = DebugHelper.log("EmojiCompat", "Initialized")
|
override fun onInitialized() = Timber.d("EmojiCompat initialized")
|
||||||
override fun onFailed(throwable: Throwable?) = Timber.d(throwable)
|
override fun onFailed(throwable: Throwable?) = Timber.d(throwable)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -67,7 +84,18 @@ class App : Application() {
|
|||||||
if (level >= TRIM_MEMORY_RUNNING_CRITICAL) GlobalScope.launch { RootSession.trimMemory() }
|
if (level >= TRIM_MEMORY_RUNNING_CRITICAL) GlobalScope.launch { RootSession.trimMemory() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to log "expected" and well-handled errors, i.e. we care less about logs, etc.
|
||||||
|
* logException is inappropriate sometimes because it flushes all logs that could be used to investigate other bugs.
|
||||||
|
*/
|
||||||
|
fun logEvent(@Size(min = 1L, max = 40L) event: String, extras: Bundle? = null) {
|
||||||
|
Timber.i(if (extras == null) event else "$event, extras: $extras")
|
||||||
|
analytics.logEvent(event, extras)
|
||||||
|
}
|
||||||
|
|
||||||
lateinit var deviceStorage: Application
|
lateinit var deviceStorage: Application
|
||||||
|
private val analytics by lazy { FirebaseAnalytics.getInstance(app.deviceStorage) }
|
||||||
|
val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
|
||||||
val english by lazy {
|
val english by lazy {
|
||||||
createConfigurationContext(Configuration(resources.configuration).apply {
|
createConfigurationContext(Configuration(resources.configuration).apply {
|
||||||
setLocale(Locale.ENGLISH)
|
setLocale(Locale.ENGLISH)
|
||||||
|
|||||||
@@ -17,13 +17,10 @@ import be.mygod.vpnhotspot.util.StickyEvent1
|
|||||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
@RequiresApi(26)
|
@RequiresApi(26)
|
||||||
class LocalOnlyHotspotService : IpNeighbourMonitoringService(), CoroutineScope {
|
class LocalOnlyHotspotService : IpNeighbourMonitoringService(), CoroutineScope {
|
||||||
companion object {
|
|
||||||
private const val TAG = "LocalOnlyHotspotService"
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class Binder : android.os.Binder() {
|
inner class Binder : android.os.Binder() {
|
||||||
/**
|
/**
|
||||||
* null represents IDLE, "" represents CONNECTING, "something" represents CONNECTED.
|
* null represents IDLE, "" represents CONNECTING, "something" represents CONNECTED.
|
||||||
@@ -60,7 +57,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService(), CoroutineScope {
|
|||||||
private var receiverRegistered = false
|
private var receiverRegistered = false
|
||||||
private val receiver = broadcastReceiver { _, intent ->
|
private val receiver = broadcastReceiver { _, intent ->
|
||||||
val ifaces = intent.localOnlyTetheredIfaces ?: return@broadcastReceiver
|
val ifaces = intent.localOnlyTetheredIfaces ?: return@broadcastReceiver
|
||||||
DebugHelper.log(TAG, "onTetherStateChangedLocked: $ifaces")
|
Timber.d("onTetherStateChangedLocked: $ifaces")
|
||||||
check(ifaces.size <= 1)
|
check(ifaces.size <= 1)
|
||||||
val iface = ifaces.singleOrNull()
|
val iface = ifaces.singleOrNull()
|
||||||
binder.iface = iface
|
binder.iface = iface
|
||||||
@@ -96,7 +93,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStopped() {
|
override fun onStopped() {
|
||||||
DebugHelper.log(TAG, "LOHCallback.onStopped")
|
Timber.d("LOHCallback.onStopped")
|
||||||
reservation = null
|
reservation = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import java.lang.reflect.InvocationTargetException
|
|||||||
class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListener,
|
class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListener,
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "RepeaterService"
|
|
||||||
private const val KEY_NETWORK_NAME = "service.repeater.networkName"
|
private const val KEY_NETWORK_NAME = "service.repeater.networkName"
|
||||||
private const val KEY_PASSPHRASE = "service.repeater.passphrase"
|
private const val KEY_PASSPHRASE = "service.repeater.passphrase"
|
||||||
private const val KEY_OPERATING_BAND = "service.repeater.band"
|
private const val KEY_OPERATING_BAND = "service.repeater.band"
|
||||||
@@ -347,7 +346,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
* Used during step 2, also called when connection changed
|
* Used during step 2, also called when connection changed
|
||||||
*/
|
*/
|
||||||
private fun onP2pConnectionChanged(info: WifiP2pInfo, group: WifiP2pGroup?) = launch {
|
private fun onP2pConnectionChanged(info: WifiP2pInfo, group: WifiP2pGroup?) = launch {
|
||||||
DebugHelper.log(TAG, "P2P connection changed: $info\n$group")
|
Timber.d("P2P connection changed: $info\n$group")
|
||||||
when {
|
when {
|
||||||
!info.groupFormed || !info.isGroupOwner || group?.isGroupOwner != true -> {
|
!info.groupFormed || !info.isGroupOwner || group?.isGroupOwner != true -> {
|
||||||
if (routingManager != null) cleanLocked()
|
if (routingManager != null) cleanLocked()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import android.widget.Toast
|
|||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.LocalOnlyHotspotService
|
import be.mygod.vpnhotspot.LocalOnlyHotspotService
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
||||||
@@ -61,7 +61,7 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
|
|||||||
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
|
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
|
||||||
Toast.makeText(context, R.string.tethering_temp_hotspot_location, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.tethering_temp_hotspot_location, Toast.LENGTH_LONG).show()
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
DebugHelper.logEvent("location_settings", bundleOf(Pair("message", e.message)))
|
app.logEvent("location_settings", bundleOf("message" to e.message))
|
||||||
SmartSnackbar.make(R.string.tethering_temp_hotspot_location).show()
|
SmartSnackbar.make(R.string.tethering_temp_hotspot_location).show()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import android.view.View
|
|||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.databinding.BaseObservable
|
import androidx.databinding.BaseObservable
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.databinding.ListitemManageBinding
|
import be.mygod.vpnhotspot.databinding.ListitemManageBinding
|
||||||
import be.mygod.vpnhotspot.net.TetherOffloadManager
|
import be.mygod.vpnhotspot.net.TetherOffloadManager
|
||||||
|
|
||||||
@@ -37,9 +37,9 @@ object ManageBar : Manager() {
|
|||||||
} catch (e1: RuntimeException) {
|
} catch (e1: RuntimeException) {
|
||||||
try {
|
try {
|
||||||
context.startActivity(Intent().setClassName(SETTINGS_PACKAGE, SETTINGS_2))
|
context.startActivity(Intent().setClassName(SETTINGS_PACKAGE, SETTINGS_2))
|
||||||
DebugHelper.logEvent(TAG, bundleOf(Pair(SETTINGS_1, e1.message)))
|
app.logEvent(TAG, bundleOf(SETTINGS_1 to e1.message))
|
||||||
} catch (e2: RuntimeException) {
|
} catch (e2: RuntimeException) {
|
||||||
DebugHelper.logEvent(TAG, bundleOf(Pair(SETTINGS_1, e1.message), Pair(SETTINGS_2, e2.message)))
|
app.logEvent(TAG, bundleOf(SETTINGS_1 to e1.message, SETTINGS_2 to e2.message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import androidx.lifecycle.DefaultLifecycleObserver
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import be.mygod.vpnhotspot.MainActivity
|
import be.mygod.vpnhotspot.MainActivity
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
||||||
@@ -49,7 +48,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
"package:${mainActivity.packageName}".toUri()))
|
"package:${mainActivity.packageName}".toUri()))
|
||||||
return
|
return
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
DebugHelper.logEvent("manage_write_settings", bundleOf(Pair("message", e.message)))
|
app.logEvent("manage_write_settings", bundleOf("message" to e.message))
|
||||||
}
|
}
|
||||||
val started = manager.isStarted
|
val started = manager.isStarted
|
||||||
try {
|
try {
|
||||||
@@ -93,7 +92,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
|
|
||||||
override fun onTetheringStarted() = data.notifyChange()
|
override fun onTetheringStarted() = data.notifyChange()
|
||||||
override fun onTetheringFailed() {
|
override fun onTetheringFailed() {
|
||||||
DebugHelper.log(javaClass.simpleName, "onTetheringFailed")
|
Timber.d(javaClass.simpleName, "onTetheringFailed")
|
||||||
data.notifyChange()
|
data.notifyChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import android.service.quicksettings.Tile
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
import be.mygod.vpnhotspot.TetheringService
|
import be.mygod.vpnhotspot.TetheringService
|
||||||
import be.mygod.vpnhotspot.net.TetherType
|
import be.mygod.vpnhotspot.net.TetherType
|
||||||
@@ -110,7 +109,7 @@ sealed class TetheringTileService : TetherListeningTileService(), TetheringManag
|
|||||||
|
|
||||||
override fun onTetheringStarted() = updateTile()
|
override fun onTetheringStarted() = updateTile()
|
||||||
override fun onTetheringFailed() {
|
override fun onTetheringFailed() {
|
||||||
DebugHelper.log(javaClass.simpleName, "onTetheringFailed")
|
Timber.d("onTetheringFailed")
|
||||||
updateTile()
|
updateTile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.net.monitor
|
|||||||
import android.system.ErrnoException
|
import android.system.ErrnoException
|
||||||
import android.system.OsConstants
|
import android.system.OsConstants
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
import be.mygod.vpnhotspot.util.RootSession
|
import be.mygod.vpnhotspot.util.RootSession
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
@@ -64,7 +63,7 @@ abstract class IpMonitor : Runnable {
|
|||||||
}
|
}
|
||||||
err.join()
|
err.join()
|
||||||
process.waitFor()
|
process.waitFor()
|
||||||
DebugHelper.log("IpMonitor", "Monitor process exited with ${process.exitValue()}")
|
Timber.d("Monitor process exited with ${process.exitValue()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -78,7 +77,7 @@ abstract class IpMonitor : Runnable {
|
|||||||
}
|
}
|
||||||
handleProcess(ProcessBuilder("su", "-c", "exec ip monitor $monitoredObject"))
|
handleProcess(ProcessBuilder("su", "-c", "exec ip monitor $monitoredObject"))
|
||||||
if (destroyed) return@thread
|
if (destroyed) return@thread
|
||||||
DebugHelper.logEvent("ip_monitor_failure")
|
app.logEvent("ip_monitor_failure")
|
||||||
}
|
}
|
||||||
val pool = Executors.newScheduledThreadPool(1)
|
val pool = Executors.newScheduledThreadPool(1)
|
||||||
pool.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS)
|
pool.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS)
|
||||||
@@ -113,7 +112,7 @@ abstract class IpMonitor : Runnable {
|
|||||||
if (currentMode != Mode.PollRoot) try {
|
if (currentMode != Mode.PollRoot) try {
|
||||||
return poll()
|
return poll()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
DebugHelper.logEvent("ip_poll_failure")
|
app.logEvent("ip_poll_failure")
|
||||||
Timber.d(e)
|
Timber.d(e)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -125,7 +124,7 @@ abstract class IpMonitor : Runnable {
|
|||||||
processLines(result.out.asSequence())
|
processLines(result.out.asSequence())
|
||||||
}
|
}
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
DebugHelper.logEvent("ip_su_poll_failure")
|
app.logEvent("ip_su_poll_failure")
|
||||||
Timber.w(e)
|
Timber.w(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package be.mygod.vpnhotspot.net.monitor
|
|||||||
|
|
||||||
import android.util.LongSparseArray
|
import android.util.LongSparseArray
|
||||||
import androidx.core.os.postDelayed
|
import androidx.core.os.postDelayed
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import be.mygod.vpnhotspot.net.Routing.Companion.IPTABLES
|
import be.mygod.vpnhotspot.net.Routing.Companion.IPTABLES
|
||||||
import be.mygod.vpnhotspot.room.AppDatabase
|
import be.mygod.vpnhotspot.room.AppDatabase
|
||||||
import be.mygod.vpnhotspot.room.TrafficRecord
|
import be.mygod.vpnhotspot.room.TrafficRecord
|
||||||
@@ -15,7 +14,6 @@ import java.net.InetAddress
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
object TrafficRecorder {
|
object TrafficRecorder {
|
||||||
private const val TAG = "TrafficRecorder"
|
|
||||||
private const val ANYWHERE = "0.0.0.0/0"
|
private const val ANYWHERE = "0.0.0.0/0"
|
||||||
|
|
||||||
private var scheduled = false
|
private var scheduled = false
|
||||||
@@ -27,14 +25,14 @@ object TrafficRecorder {
|
|||||||
val record = TrafficRecord(mac = mac, ip = ip, downstream = downstream)
|
val record = TrafficRecord(mac = mac, ip = ip, downstream = downstream)
|
||||||
AppDatabase.instance.trafficRecordDao.insert(record)
|
AppDatabase.instance.trafficRecordDao.insert(record)
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
DebugHelper.log(TAG, "Registering $ip%$downstream")
|
Timber.d("Registering $ip%$downstream")
|
||||||
check(records.putIfAbsent(Pair(ip, downstream), record) == null)
|
check(records.putIfAbsent(Pair(ip, downstream), record) == null)
|
||||||
scheduleUpdateLocked()
|
scheduleUpdateLocked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun unregister(ip: InetAddress, downstream: String) = synchronized(this) {
|
fun unregister(ip: InetAddress, downstream: String) = synchronized(this) {
|
||||||
update() // flush stats before removing
|
update() // flush stats before removing
|
||||||
DebugHelper.log(TAG, "Unregistering $ip%$downstream")
|
Timber.d("Unregistering $ip%$downstream")
|
||||||
if (records.remove(Pair(ip, downstream)) == null) Timber.w("Failed to find traffic record for $ip%$downstream.")
|
if (records.remove(Pair(ip, downstream)) == null) Timber.w("Failed to find traffic record for $ip%$downstream.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +140,7 @@ object TrafficRecorder {
|
|||||||
fun clean() = synchronized(this) {
|
fun clean() = synchronized(this) {
|
||||||
update()
|
update()
|
||||||
unscheduleUpdateLocked()
|
unscheduleUpdateLocked()
|
||||||
DebugHelper.log(TAG, "Cleaning records")
|
Timber.d("Cleaning records")
|
||||||
records.clear()
|
records.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,9 @@ package be.mygod.vpnhotspot.net.monitor
|
|||||||
|
|
||||||
import android.net.*
|
import android.net.*
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
object VpnMonitor : UpstreamMonitor() {
|
object VpnMonitor : UpstreamMonitor() {
|
||||||
private const val TAG = "VpnMonitor"
|
|
||||||
|
|
||||||
private val request = NetworkRequest.Builder()
|
private val request = NetworkRequest.Builder()
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
|
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
|
||||||
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
||||||
@@ -66,7 +63,7 @@ object VpnMonitor : UpstreamMonitor() {
|
|||||||
if (available.isNotEmpty()) {
|
if (available.isNotEmpty()) {
|
||||||
val next = available.entries.first()
|
val next = available.entries.first()
|
||||||
currentNetwork = next.key
|
currentNetwork = next.key
|
||||||
DebugHelper.log(TAG, "Switching to ${next.value.interfaceName} as VPN interface")
|
Timber.d("Switching to ${next.value.interfaceName} as VPN interface")
|
||||||
callbacks.forEach { it.onAvailable(next.value.interfaceName!!, next.value) }
|
callbacks.forEach { it.onAvailable(next.value.interfaceName!!, next.value) }
|
||||||
} else currentNetwork = null
|
} else currentNetwork = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.net.wifi.WpsInfo
|
import android.net.wifi.WpsInfo
|
||||||
import android.net.wifi.p2p.WifiP2pGroup
|
import android.net.wifi.p2p.WifiP2pGroup
|
||||||
import android.net.wifi.p2p.WifiP2pManager
|
import android.net.wifi.p2p.WifiP2pManager
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import com.android.dx.stock.ProxyBuilder
|
import com.android.dx.stock.ProxyBuilder
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.lang.reflect.Proxy
|
import java.lang.reflect.Proxy
|
||||||
@@ -30,7 +30,7 @@ object WifiP2pManagerHelper {
|
|||||||
try {
|
try {
|
||||||
setWifiP2pChannels.invoke(this, c, lc, oc, listener)
|
setWifiP2pChannels.invoke(this, c, lc, oc, listener)
|
||||||
} catch (_: NoSuchMethodException) {
|
} catch (_: NoSuchMethodException) {
|
||||||
DebugHelper.logEvent("NoSuchMethod_setWifiP2pChannels")
|
app.logEvent("NoSuchMethod_setWifiP2pChannels")
|
||||||
listener.onFailure(UNSUPPORTED)
|
listener.onFailure(UNSUPPORTED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ object WifiP2pManagerHelper {
|
|||||||
WifiP2pManager::class.java.getDeclaredMethod("startWps",
|
WifiP2pManager::class.java.getDeclaredMethod("startWps",
|
||||||
WifiP2pManager.Channel::class.java, WpsInfo::class.java, WifiP2pManager.ActionListener::class.java)
|
WifiP2pManager.Channel::class.java, WpsInfo::class.java, WifiP2pManager.ActionListener::class.java)
|
||||||
} catch (_: NoSuchMethodException) {
|
} catch (_: NoSuchMethodException) {
|
||||||
DebugHelper.logEvent("NoSuchMethod_startWps")
|
app.logEvent("NoSuchMethod_startWps")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ object WifiP2pManagerHelper {
|
|||||||
try {
|
try {
|
||||||
deletePersistentGroup.invoke(this, c, netId, listener)
|
deletePersistentGroup.invoke(this, c, netId, listener)
|
||||||
} catch (_: NoSuchMethodException) {
|
} catch (_: NoSuchMethodException) {
|
||||||
DebugHelper.logEvent("NoSuchMethod_deletePersistentGroup")
|
app.logEvent("NoSuchMethod_deletePersistentGroup")
|
||||||
listener.onFailure(UNSUPPORTED)
|
listener.onFailure(UNSUPPORTED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.net.wifi.configuration
|
|||||||
import android.net.wifi.p2p.WifiP2pGroup
|
import android.net.wifi.p2p.WifiP2pGroup
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
|
||||||
import be.mygod.vpnhotspot.RepeaterService
|
import be.mygod.vpnhotspot.RepeaterService
|
||||||
import be.mygod.vpnhotspot.util.RootSession
|
import be.mygod.vpnhotspot.util.RootSession
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -109,9 +108,9 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup, ownerAddress:
|
|||||||
}
|
}
|
||||||
Triple(result, target!!, shell.err.isNotEmpty())
|
Triple(result, target!!, shell.err.isNotEmpty())
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
DebugHelper.setString(TAG, parser.lines.joinToString("\n"))
|
app.crashlytics.setCustomKey(TAG, parser.lines.joinToString("\n"))
|
||||||
DebugHelper.setString("$TAG.ownerAddress", ownerAddress)
|
app.crashlytics.setCustomKey("$TAG.ownerAddress", ownerAddress.toString())
|
||||||
DebugHelper.setString("$TAG.p2pGroup", group.toString())
|
app.crashlytics.setCustomKey("$TAG.p2pGroup", group.toString())
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user