Support new permission in Tiramisu

This commit is contained in:
Mygod
2022-07-12 10:18:52 -04:00
parent 77faca0dfb
commit 4e1f7c9c40
11 changed files with 59 additions and 38 deletions

View File

@@ -2,11 +2,16 @@ package be.mygod.vpnhotspot
import android.annotation.SuppressLint
import android.app.Application
import android.content.ActivityNotFoundException
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.location.LocationManager
import android.os.Build
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.annotation.Size
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
@@ -19,6 +24,7 @@ import be.mygod.vpnhotspot.room.AppDatabase
import be.mygod.vpnhotspot.root.RootManager
import be.mygod.vpnhotspot.util.DeviceStorageApp
import be.mygod.vpnhotspot.util.Services
import be.mygod.vpnhotspot.widget.SmartSnackbar
import com.google.firebase.analytics.ktx.ParametersBuilder
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
@@ -104,6 +110,26 @@ class App : Application() {
Firebase.analytics.logEvent(event, builder.bundle)
}
/**
* LOH also requires location to be turned on. So does p2p for some reason. Source:
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiServiceImpl.java#1204
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiSettingsStore.java#228
*/
inline fun <reified T> startServiceWithLocation(context: Context) {
if (BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33 || if (Build.VERSION.SDK_INT >= 28) {
location?.isLocationEnabled == true
} else @Suppress("DEPRECATION") {
Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE,
Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF
}) ContextCompat.startForegroundService(context, Intent(context, T::class.java)) else try {
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
Toast.makeText(context, R.string.tethering_location_off, Toast.LENGTH_LONG).show()
} catch (e: ActivityNotFoundException) {
app.logEvent("location_settings") { param("message", e.toString()) }
SmartSnackbar.make(R.string.tethering_location_off).show()
}
}
lateinit var deviceStorage: Application
val english by lazy {
createConfigurationContext(Configuration(resources.configuration).apply {

View File

@@ -364,7 +364,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
launch {
val filter = intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
if (Build.VERSION.SDK_INT >= 30) filter.addAction(LocationManager.MODE_CHANGED_ACTION)
if (Build.VERSION.SDK_INT in 30 until 33) filter.addAction(LocationManager.MODE_CHANGED_ACTION)
registerReceiver(receiver, filter)
receiverRegistered = true
val group = p2pManager.requestGroupInfo(channel)
@@ -397,7 +397,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
override fun onSuccess() {
// wait for WIFI_P2P_CONNECTION_CHANGED_ACTION to fire to go to step 3
// in order for this to happen, we need to make sure that the callbacks are firing
if (Build.VERSION.SDK_INT >= 30) onLocationModeChanged(app.location?.isLocationEnabled == true)
if (Build.VERSION.SDK_INT in 30 until 33) onLocationModeChanged(app.location?.isLocationEnabled == true)
}
}
val channel = channel ?: return listener.onFailure(WifiP2pManager.BUSY)

View File

@@ -4,26 +4,26 @@ import android.Manifest
import android.content.*
import android.os.Build
import android.os.IBinder
import android.provider.Settings
import android.view.View
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.BuildConfig
import be.mygod.vpnhotspot.LocalOnlyHotspotService
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
import be.mygod.vpnhotspot.util.ServiceForegroundConnector
import be.mygod.vpnhotspot.util.formatAddresses
import be.mygod.vpnhotspot.widget.SmartSnackbar
import java.net.NetworkInterface
@RequiresApi(26)
class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection {
companion object {
val permission = if (Build.VERSION.SDK_INT >= 29) {
Manifest.permission.ACCESS_FINE_LOCATION
} else Manifest.permission.ACCESS_COARSE_LOCATION
val permission = when {
BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33 -> Manifest.permission.NEARBY_WIFI_DEVICES
Build.VERSION.SDK_INT >= 29 -> Manifest.permission.ACCESS_FINE_LOCATION
else -> Manifest.permission.ACCESS_COARSE_LOCATION
}
}
class ViewHolder(val binding: ListitemInterfaceBinding) : RecyclerView.ViewHolder(binding.root),
@@ -55,23 +55,7 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
ServiceForegroundConnector(parent, this, LocalOnlyHotspotService::class)
}
/**
* LOH also requires location to be turned on. Source:
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiServiceImpl.java#1204
* https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiSettingsStore.java#228
*/
fun start(context: Context) {
if (if (Build.VERSION.SDK_INT < 28) @Suppress("DEPRECATION") {
Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE,
Settings.Secure.LOCATION_MODE_OFF) == Settings.Secure.LOCATION_MODE_OFF
} else app.location?.isLocationEnabled != true) try {
context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
Toast.makeText(context, R.string.tethering_temp_hotspot_location, Toast.LENGTH_LONG).show()
} catch (e: ActivityNotFoundException) {
app.logEvent("location_settings") { param("message", e.toString()) }
SmartSnackbar.make(R.string.tethering_temp_hotspot_location).show()
} else context.startForegroundService(Intent(context, LocalOnlyHotspotService::class.java))
}
fun start(context: Context) = app.startServiceWithLocation<LocalOnlyHotspotService>(context)
override val type get() = VIEW_TYPE_LOCAL_ONLY_HOTSPOT
private val data = Data()

View File

@@ -92,7 +92,9 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
when (binder?.service?.status) {
RepeaterService.Status.IDLE -> if (Build.VERSION.SDK_INT < 29) parent.requireContext().let { context ->
ContextCompat.startForegroundService(context, Intent(context, RepeaterService::class.java))
} else parent.startRepeater.launch(Manifest.permission.ACCESS_FINE_LOCATION)
} else parent.startRepeater.launch(if (BuildConfig.TARGET_SDK >= 33 && Build.VERSION.SDK_INT >= 33) {
Manifest.permission.NEARBY_WIFI_DEVICES
} else Manifest.permission.ACCESS_FINE_LOCATION)
RepeaterService.Status.ACTIVE -> binder.shutdown()
else -> { }
}

View File

@@ -24,6 +24,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import be.mygod.vpnhotspot.*
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.databinding.FragmentTetheringBinding
import be.mygod.vpnhotspot.net.TetherType
import be.mygod.vpnhotspot.net.TetheringManager
@@ -136,7 +137,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
@RequiresApi(29)
val startRepeater = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) requireActivity().startForegroundService(Intent(activity, RepeaterService::class.java)) else {
if (granted) app.startServiceWithLocation<RepeaterService>(requireContext()) else {
Snackbar.make((activity as MainActivity).binding.fragmentHolder,
R.string.repeater_missing_location_permissions, Snackbar.LENGTH_LONG).show()
}