Remove Bluetooth tethering if unsupported
This commit is contained in:
@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.manage
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.bluetooth.BluetoothAdapter
|
import android.bluetooth.BluetoothAdapter
|
||||||
import android.bluetooth.BluetoothManager
|
|
||||||
import android.bluetooth.BluetoothProfile
|
import android.bluetooth.BluetoothProfile
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -11,7 +10,6 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.content.getSystemService
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.net.TetheringManager
|
import be.mygod.vpnhotspot.net.TetheringManager
|
||||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||||
@@ -20,7 +18,7 @@ import be.mygod.vpnhotspot.widget.SmartSnackbar
|
|||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
|
|
||||||
class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
class BluetoothTethering(context: Context, private val adapter: BluetoothAdapter, val stateListener: () -> Unit) :
|
||||||
BluetoothProfile.ServiceListener, AutoCloseable {
|
BluetoothProfile.ServiceListener, AutoCloseable {
|
||||||
companion object : BroadcastReceiver() {
|
companion object : BroadcastReceiver() {
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +28,6 @@ class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
|||||||
private val clazz by lazy { Class.forName("android.bluetooth.BluetoothPan") }
|
private val clazz by lazy { Class.forName("android.bluetooth.BluetoothPan") }
|
||||||
private val isTetheringOn by lazy { clazz.getDeclaredMethod("isTetheringOn") }
|
private val isTetheringOn by lazy { clazz.getDeclaredMethod("isTetheringOn") }
|
||||||
|
|
||||||
private val adapter = app.getSystemService<BluetoothManager>()?.adapter
|
|
||||||
private val BluetoothProfile.isTetheringOn get() = isTetheringOn(this) as Boolean
|
private val BluetoothProfile.isTetheringOn get() = isTetheringOn(this) as Boolean
|
||||||
|
|
||||||
private fun registerBluetoothStateListener(receiver: BroadcastReceiver) =
|
private fun registerBluetoothStateListener(receiver: BroadcastReceiver) =
|
||||||
@@ -67,7 +64,7 @@ class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
|||||||
val pan = pan ?: return null
|
val pan = pan ?: return null
|
||||||
if (!connected) return null
|
if (!connected) return null
|
||||||
activeFailureCause = null
|
activeFailureCause = null
|
||||||
val on = adapter?.state == BluetoothAdapter.STATE_ON && try {
|
val on = adapter.state == BluetoothAdapter.STATE_ON && try {
|
||||||
pan.isTetheringOn
|
pan.isTetheringOn
|
||||||
} catch (e: InvocationTargetException) {
|
} catch (e: InvocationTargetException) {
|
||||||
activeFailureCause = e.cause ?: e
|
activeFailureCause = e.cause ?: e
|
||||||
@@ -84,7 +81,6 @@ class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
|||||||
private val receiver = broadcastReceiver { _, _ -> stateListener() }
|
private val receiver = broadcastReceiver { _, _ -> stateListener() }
|
||||||
|
|
||||||
fun ensureInit(context: Context) {
|
fun ensureInit(context: Context) {
|
||||||
val adapter = adapter ?: return
|
|
||||||
activeFailureCause = null
|
activeFailureCause = null
|
||||||
if (!proxyCreated) try {
|
if (!proxyCreated) try {
|
||||||
check(adapter.getProfileProxy(context, this, PAN))
|
check(adapter.getProfileProxy(context, this, PAN))
|
||||||
@@ -116,7 +112,7 @@ class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
|||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
fun start(callback: TetheringManager.StartTetheringCallback) {
|
fun start(callback: TetheringManager.StartTetheringCallback) {
|
||||||
if (pendingCallback == null) try {
|
if (pendingCallback == null) try {
|
||||||
if (adapter?.state == BluetoothAdapter.STATE_OFF) {
|
if (adapter.state == BluetoothAdapter.STATE_OFF) {
|
||||||
registerBluetoothStateListener(BluetoothTethering)
|
registerBluetoothStateListener(BluetoothTethering)
|
||||||
pendingCallback = callback
|
pendingCallback = callback
|
||||||
adapter.enable()
|
adapter.enable()
|
||||||
@@ -134,6 +130,6 @@ class BluetoothTethering(context: Context, val stateListener: () -> Unit) :
|
|||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
app.unregisterReceiver(receiver)
|
app.unregisterReceiver(receiver)
|
||||||
adapter!!.closeProfileProxy(PAN, pan)
|
adapter.closeProfileProxy(PAN, pan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package be.mygod.vpnhotspot.manage
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
@@ -306,8 +307,9 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
override fun stop() = TetheringManager.stopTethering(TetheringManager.TETHERING_USB, this::onException)
|
override fun stop() = TetheringManager.stopTethering(TetheringManager.TETHERING_USB, this::onException)
|
||||||
}
|
}
|
||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
class Bluetooth(parent: TetheringFragment) : TetherManager(parent), DefaultLifecycleObserver {
|
class Bluetooth(parent: TetheringFragment, adapter: BluetoothAdapter) :
|
||||||
private val tethering = BluetoothTethering(parent.requireContext()) { data.notifyChange() }
|
TetherManager(parent), DefaultLifecycleObserver {
|
||||||
|
private val tethering = BluetoothTethering(parent.requireContext(), adapter) { data.notifyChange() }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
parent.viewLifecycleOwner.lifecycle.addObserver(this)
|
parent.viewLifecycleOwner.lifecycle.addObserver(this)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package be.mygod.vpnhotspot.manage
|
package be.mygod.vpnhotspot.manage
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
import android.bluetooth.BluetoothManager
|
||||||
import android.content.*
|
import android.content.*
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -15,6 +16,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
@@ -49,12 +51,18 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
|
|||||||
@get:RequiresApi(26)
|
@get:RequiresApi(26)
|
||||||
internal val localOnlyHotspotManager by lazy @TargetApi(26) { LocalOnlyHotspotManager(this@TetheringFragment) }
|
internal val localOnlyHotspotManager by lazy @TargetApi(26) { LocalOnlyHotspotManager(this@TetheringFragment) }
|
||||||
@get:RequiresApi(24)
|
@get:RequiresApi(24)
|
||||||
internal val bluetoothManager by lazy @TargetApi(24) { TetherManager.Bluetooth(this@TetheringFragment) }
|
internal val bluetoothManager by lazy {
|
||||||
|
if (Build.VERSION.SDK_INT >= 24) requireContext().getSystemService<BluetoothManager>()?.adapter?.let {
|
||||||
|
TetherManager.Bluetooth(this@TetheringFragment, it)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
@get:RequiresApi(24)
|
@get:RequiresApi(24)
|
||||||
private val tetherManagers by lazy @TargetApi(24) {
|
private val tetherManagers by lazy @TargetApi(24) {
|
||||||
listOf(TetherManager.Wifi(this@TetheringFragment),
|
listOfNotNull(
|
||||||
TetherManager.Usb(this@TetheringFragment),
|
TetherManager.Wifi(this@TetheringFragment),
|
||||||
bluetoothManager)
|
TetherManager.Usb(this@TetheringFragment),
|
||||||
|
bluetoothManager,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@get:RequiresApi(30)
|
@get:RequiresApi(30)
|
||||||
private val tetherManagers30 by lazy @TargetApi(30) {
|
private val tetherManagers30 by lazy @TargetApi(30) {
|
||||||
@@ -139,7 +147,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
|
|||||||
}
|
}
|
||||||
@RequiresApi(31)
|
@RequiresApi(31)
|
||||||
val requestBluetooth = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
|
val requestBluetooth = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
|
||||||
if (granted) adapter.bluetoothManager.ensureInit(requireContext())
|
if (granted) adapter.bluetoothManager!!.ensureInit(requireContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
var ifaceLookup: Map<String, NetworkInterface> = emptyMap()
|
var ifaceLookup: Map<String, NetworkInterface> = emptyMap()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package be.mygod.vpnhotspot.manage
|
package be.mygod.vpnhotspot.manage
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothManager
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -11,6 +12,7 @@ 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 androidx.core.content.getSystemService
|
||||||
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
|
||||||
@@ -158,7 +160,9 @@ sealed class TetheringTileService : IpNeighbourMonitoringTileService(), Tetherin
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartListening() {
|
override fun onStartListening() {
|
||||||
tethering = BluetoothTethering(this) { updateTile() }
|
tethering = getSystemService<BluetoothManager>()?.adapter?.let {
|
||||||
|
BluetoothTethering(this, it) { updateTile() }
|
||||||
|
}
|
||||||
super.onStartListening()
|
super.onStartListening()
|
||||||
}
|
}
|
||||||
override fun onStopListening() {
|
override fun onStopListening() {
|
||||||
|
|||||||
Reference in New Issue
Block a user