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