Remove Bluetooth tethering if unsupported

This commit is contained in:
Mygod
2021-07-27 14:53:23 -04:00
parent 5f6e33c852
commit 018682e2f5
4 changed files with 26 additions and 16 deletions

View File

@@ -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)
} }
} }

View File

@@ -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)

View File

@@ -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.Wifi(this@TetheringFragment),
TetherManager.Usb(this@TetheringFragment), TetherManager.Usb(this@TetheringFragment),
bluetoothManager) 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()

View File

@@ -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() {