2020-09-17 19:49:50 +02:00
|
|
|
package com.geeksville.mesh.android
|
|
|
|
|
|
2021-06-10 10:58:45 -07:00
|
|
|
import android.Manifest
|
2023-04-01 07:58:37 -03:00
|
|
|
import android.annotation.SuppressLint
|
2020-10-01 22:20:19 +02:00
|
|
|
import android.app.NotificationManager
|
2020-09-17 19:49:50 +02:00
|
|
|
import android.bluetooth.BluetoothManager
|
2022-10-10 17:47:21 -03:00
|
|
|
import android.location.LocationManager
|
2022-04-28 23:09:06 -03:00
|
|
|
import android.companion.CompanionDeviceManager
|
2020-09-17 19:49:50 +02:00
|
|
|
import android.content.Context
|
2021-06-10 10:58:45 -07:00
|
|
|
import android.content.pm.PackageManager
|
2020-09-17 19:49:50 +02:00
|
|
|
import android.hardware.usb.UsbManager
|
2021-06-10 10:58:45 -07:00
|
|
|
import androidx.core.content.ContextCompat
|
2022-11-04 18:31:18 -03:00
|
|
|
import com.geeksville.mesh.R
|
2020-09-17 19:49:50 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return null on platforms without a BlueTooth driver (i.e. the emulator)
|
|
|
|
|
*/
|
2022-11-04 18:31:18 -03:00
|
|
|
val Context.bluetoothManager: BluetoothManager?
|
|
|
|
|
get() = getSystemService(Context.BLUETOOTH_SERVICE).takeIf { hasBluetoothPermission() } as? BluetoothManager?
|
2020-09-17 19:49:50 +02:00
|
|
|
|
2023-04-01 07:58:37 -03:00
|
|
|
val Context.companionDeviceManager: CompanionDeviceManager?
|
|
|
|
|
@SuppressLint("NewApi")
|
|
|
|
|
get() = getSystemService(Context.COMPANION_DEVICE_SERVICE).takeIf { hasCompanionDeviceApi() } as? CompanionDeviceManager?
|
2022-04-28 23:09:06 -03:00
|
|
|
|
2020-09-17 19:55:36 +02:00
|
|
|
val Context.usbManager: UsbManager get() = requireNotNull(getSystemService(Context.USB_SERVICE) as? UsbManager?) { "USB_SERVICE is not available"}
|
2020-10-01 22:20:19 +02:00
|
|
|
|
|
|
|
|
val Context.notificationManager: NotificationManager get() = requireNotNull(getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager?)
|
2021-06-10 10:58:45 -07:00
|
|
|
|
2022-10-10 17:47:21 -03:00
|
|
|
val Context.locationManager: LocationManager get() = requireNotNull(getSystemService(Context.LOCATION_SERVICE) as? LocationManager?)
|
|
|
|
|
|
2022-04-28 21:40:34 -03:00
|
|
|
/**
|
|
|
|
|
* @return true if CompanionDeviceManager API is present
|
|
|
|
|
*/
|
|
|
|
|
fun Context.hasCompanionDeviceApi(): Boolean =
|
2022-11-04 18:31:18 -03:00
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
|
2022-04-28 21:40:34 -03:00
|
|
|
packageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)
|
|
|
|
|
else false
|
|
|
|
|
|
2022-05-31 18:31:14 -03:00
|
|
|
/**
|
|
|
|
|
* @return true if the device has a GPS receiver
|
|
|
|
|
*/
|
2022-10-10 17:47:21 -03:00
|
|
|
fun Context.hasGps(): Boolean = locationManager.allProviders.contains(LocationManager.GPS_PROVIDER)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return true if the device has a GPS receiver and it is disabled (location turned off)
|
|
|
|
|
*/
|
|
|
|
|
fun Context.gpsDisabled(): Boolean =
|
|
|
|
|
if (hasGps()) !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) else false
|
2022-05-31 18:31:14 -03:00
|
|
|
|
2022-11-04 18:31:18 -03:00
|
|
|
/**
|
|
|
|
|
* return the text string of the permissions missing
|
|
|
|
|
*/
|
|
|
|
|
val Context.permissionMissing: String
|
|
|
|
|
get() = if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S) {
|
|
|
|
|
getString(R.string.permission_missing)
|
|
|
|
|
} else {
|
|
|
|
|
getString(R.string.permission_missing_31)
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-10 10:58:45 -07:00
|
|
|
/**
|
|
|
|
|
* return a list of the permissions we don't have
|
|
|
|
|
*/
|
2022-06-01 00:04:31 -03:00
|
|
|
fun Context.getMissingPermissions(perms: List<String>): Array<String> = perms.filter {
|
2021-06-10 10:58:45 -07:00
|
|
|
ContextCompat.checkSelfPermission(
|
|
|
|
|
this,
|
|
|
|
|
it
|
|
|
|
|
) != PackageManager.PERMISSION_GRANTED
|
2022-06-01 00:04:31 -03:00
|
|
|
}.toTypedArray()
|
2021-06-10 10:58:45 -07:00
|
|
|
|
2022-01-31 21:19:54 -03:00
|
|
|
/**
|
2022-09-03 11:07:10 -03:00
|
|
|
* Bluetooth permissions (or empty if we already have what we need)
|
2022-01-31 21:19:54 -03:00
|
|
|
*/
|
2022-09-03 11:07:10 -03:00
|
|
|
fun Context.getBluetoothPermissions(): Array<String> {
|
2022-01-31 21:19:54 -03:00
|
|
|
val perms = mutableListOf<String>()
|
|
|
|
|
|
2022-11-04 18:31:18 -03:00
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
2022-09-03 11:07:10 -03:00
|
|
|
perms.add(Manifest.permission.BLUETOOTH_SCAN)
|
2022-01-31 21:19:54 -03:00
|
|
|
perms.add(Manifest.permission.BLUETOOTH_CONNECT)
|
2022-11-04 18:31:18 -03:00
|
|
|
} else if (!hasCompanionDeviceApi()) {
|
|
|
|
|
perms.add(Manifest.permission.ACCESS_FINE_LOCATION)
|
2022-01-31 21:19:54 -03:00
|
|
|
}
|
|
|
|
|
return getMissingPermissions(perms)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @return true if the user already has Bluetooth connect permission */
|
2022-09-03 11:07:10 -03:00
|
|
|
fun Context.hasBluetoothPermission() = getBluetoothPermissions().isEmpty()
|
2022-01-25 18:14:10 -03:00
|
|
|
|
2021-11-19 01:20:54 -03:00
|
|
|
/**
|
|
|
|
|
* Camera permission (or empty if we already have what we need)
|
|
|
|
|
*/
|
2022-06-01 00:04:31 -03:00
|
|
|
fun Context.getCameraPermissions(): Array<String> {
|
2021-11-19 01:20:54 -03:00
|
|
|
val perms = mutableListOf(Manifest.permission.CAMERA)
|
|
|
|
|
|
|
|
|
|
return getMissingPermissions(perms)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @return true if the user already has camera permission */
|
|
|
|
|
fun Context.hasCameraPermission() = getCameraPermissions().isEmpty()
|
|
|
|
|
|
2021-12-15 09:04:44 -03:00
|
|
|
/**
|
2022-01-25 15:59:45 -03:00
|
|
|
* Location permission (or empty if we already have what we need)
|
2021-12-15 09:04:44 -03:00
|
|
|
*/
|
2022-06-01 00:04:31 -03:00
|
|
|
fun Context.getLocationPermissions(): Array<String> {
|
2021-12-15 09:04:44 -03:00
|
|
|
val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION)
|
|
|
|
|
|
|
|
|
|
return getMissingPermissions(perms)
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-25 18:14:10 -03:00
|
|
|
/** @return true if the user already has location permission */
|
2021-12-15 09:04:44 -03:00
|
|
|
fun Context.hasLocationPermission() = getLocationPermissions().isEmpty()
|
|
|
|
|
|
2021-06-10 10:58:45 -07:00
|
|
|
/**
|
|
|
|
|
* A list of missing background location permissions (or empty if we already have what we need)
|
|
|
|
|
*/
|
2022-06-01 00:04:31 -03:00
|
|
|
fun Context.getBackgroundPermissions(): Array<String> {
|
|
|
|
|
val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION)
|
2021-06-10 10:58:45 -07:00
|
|
|
|
2022-11-04 18:31:18 -03:00
|
|
|
if (android.os.Build.VERSION.SDK_INT >= 29) // only added later
|
2021-06-10 10:58:45 -07:00
|
|
|
perms.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
|
|
|
|
|
|
|
|
|
return getMissingPermissions(perms)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @return true if the user already has background location permission */
|
2021-11-19 01:20:54 -03:00
|
|
|
fun Context.hasBackgroundPermission() = getBackgroundPermissions().isEmpty()
|