2020-03-30 13:14:24 +02:00
|
|
|
package info.nightscout.androidaps.utils
|
|
|
|
|
|
|
|
import android.Manifest
|
|
|
|
import android.annotation.SuppressLint
|
|
|
|
import android.content.ActivityNotFoundException
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
|
|
|
import android.content.pm.PackageManager
|
|
|
|
import android.net.Uri
|
|
|
|
import android.os.Build
|
|
|
|
import android.os.PowerManager
|
|
|
|
import android.provider.Settings
|
|
|
|
import androidx.core.content.ContextCompat
|
2020-10-19 18:40:17 +02:00
|
|
|
import androidx.fragment.app.FragmentActivity
|
2020-03-30 13:14:24 +02:00
|
|
|
import dagger.android.HasAndroidInjector
|
|
|
|
import info.nightscout.androidaps.R
|
2021-01-18 22:47:55 +01:00
|
|
|
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
|
2020-03-30 13:14:24 +02:00
|
|
|
import info.nightscout.androidaps.interfaces.PluginType
|
|
|
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
|
|
|
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
|
|
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
2021-02-09 17:57:28 +01:00
|
|
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
2020-03-30 13:14:24 +02:00
|
|
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
|
|
|
import javax.inject.Inject
|
|
|
|
import javax.inject.Singleton
|
|
|
|
|
|
|
|
@Singleton
|
|
|
|
class AndroidPermission @Inject constructor(
|
|
|
|
val resourceHelper: ResourceHelper,
|
|
|
|
val rxBus: RxBusWrapper,
|
|
|
|
val injector: HasAndroidInjector
|
|
|
|
) {
|
|
|
|
|
2021-01-18 22:47:55 +01:00
|
|
|
private var permissionBatteryOptimizationFailed = false
|
2020-03-30 13:14:24 +02:00
|
|
|
|
|
|
|
@SuppressLint("BatteryLife")
|
2021-01-18 22:47:55 +01:00
|
|
|
fun askForPermission(activity: FragmentActivity, permissions: Array<String>) {
|
2020-03-30 13:14:24 +02:00
|
|
|
var test = false
|
|
|
|
var testBattery = false
|
2021-01-18 22:47:55 +01:00
|
|
|
for (s in permissions) {
|
2020-03-30 13:14:24 +02:00
|
|
|
test = test || ContextCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED
|
|
|
|
if (s == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
|
|
|
|
val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
|
|
val packageName = activity.packageName
|
|
|
|
testBattery = testBattery || !powerManager.isIgnoringBatteryOptimizations(packageName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (test) {
|
2021-01-18 22:47:55 +01:00
|
|
|
if (activity is DaggerAppCompatActivityWithResult)
|
|
|
|
activity.requestMultiplePermissions.launch(permissions)
|
2020-03-30 13:14:24 +02:00
|
|
|
}
|
|
|
|
if (testBattery) {
|
|
|
|
try {
|
2021-01-18 22:47:55 +01:00
|
|
|
if (activity is DaggerAppCompatActivityWithResult)
|
|
|
|
activity.callForBatteryOptimization.launch(null)
|
2020-03-30 13:14:24 +02:00
|
|
|
} catch (e: ActivityNotFoundException) {
|
2021-01-18 22:47:55 +01:00
|
|
|
permissionBatteryOptimizationFailed = true
|
2021-02-09 17:57:28 +01:00
|
|
|
OKDialog.show(activity, resourceHelper.gs(R.string.permission), resourceHelper.gs(R.string.alert_dialog_permission_battery_optimization_failed), Runnable { activity.recreate() })
|
2020-03-30 13:14:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-18 22:47:55 +01:00
|
|
|
fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission))
|
2020-03-30 13:14:24 +02:00
|
|
|
|
|
|
|
fun permissionNotGranted(context: Context, permission: String): Boolean {
|
|
|
|
var selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
|
|
|
if (permission == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
|
2021-01-18 22:47:55 +01:00
|
|
|
if (!permissionBatteryOptimizationFailed) {
|
2020-03-30 13:14:24 +02:00
|
|
|
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
|
|
val packageName = context.packageName
|
|
|
|
selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return !selfCheck
|
|
|
|
}
|
|
|
|
|
|
|
|
@Synchronized
|
2020-10-19 18:40:17 +02:00
|
|
|
fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicatorPlugin: SmsCommunicatorPlugin) {
|
2020-03-30 13:14:24 +02:00
|
|
|
if (smsCommunicatorPlugin.isEnabled(PluginType.GENERAL)) {
|
|
|
|
if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) {
|
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_SMS, resourceHelper.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) {
|
2020-03-30 13:14:24 +02:00
|
|
|
askForPermission(activity, arrayOf(Manifest.permission.RECEIVE_SMS,
|
|
|
|
Manifest.permission.SEND_SMS,
|
2021-01-18 22:47:55 +01:00
|
|
|
Manifest.permission.RECEIVE_MMS))
|
|
|
|
}
|
2020-03-30 13:14:24 +02:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS))
|
|
|
|
// Following is a bug in Android 8
|
2021-01-16 18:29:18 +01:00
|
|
|
if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) {
|
2021-03-07 17:46:21 +01:00
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_PHONE_STATE, resourceHelper.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_PHONE_STATE)) }
|
2021-01-16 18:29:18 +01:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
2021-03-07 17:46:21 +01:00
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONE_STATE))
|
2020-03-30 13:14:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Synchronized
|
2020-10-19 18:40:17 +02:00
|
|
|
fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) {
|
2020-03-30 13:14:24 +02:00
|
|
|
if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) {
|
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_BATTERY, String.format(resourceHelper.gs(R.string.needwhitelisting), resourceHelper.gs(R.string.app_name)), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) }
|
2020-03-30 13:14:24 +02:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_BATTERY))
|
|
|
|
}
|
|
|
|
|
2020-10-19 18:40:17 +02:00
|
|
|
@Synchronized fun notifyForStoragePermission(activity: FragmentActivity) {
|
2020-03-30 13:14:24 +02:00
|
|
|
if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_STORAGE, resourceHelper.gs(R.string.needstoragepermission), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) {
|
2020-03-30 13:14:24 +02:00
|
|
|
askForPermission(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,
|
2021-01-18 22:47:55 +01:00
|
|
|
Manifest.permission.WRITE_EXTERNAL_STORAGE))
|
|
|
|
}
|
2020-03-30 13:14:24 +02:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_STORAGE))
|
|
|
|
}
|
|
|
|
|
2020-10-19 18:40:17 +02:00
|
|
|
@Synchronized fun notifyForLocationPermissions(activity: FragmentActivity) {
|
2020-03-30 13:14:24 +02:00
|
|
|
if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
|
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_LOCATION, resourceHelper.gs(R.string.needlocationpermission), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) }
|
2020-03-30 13:14:24 +02:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_LOCATION))
|
|
|
|
}
|
|
|
|
|
2020-10-19 18:40:17 +02:00
|
|
|
@Synchronized fun notifyForSystemWindowPermissions(activity: FragmentActivity) {
|
2020-03-30 13:14:24 +02:00
|
|
|
// Check if Android Q or higher
|
|
|
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
|
|
|
|
if (!Settings.canDrawOverlays(activity)) {
|
|
|
|
val notification = NotificationWithAction(injector, Notification.PERMISSION_SYSTEM_WINDOW, resourceHelper.gs(R.string.needsystemwindowpermission), Notification.URGENT)
|
2021-01-18 22:47:55 +01:00
|
|
|
notification.action(R.string.request) {
|
2020-03-30 13:14:24 +02:00
|
|
|
// Check if Android Q or higher
|
|
|
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
|
|
|
|
// Show alert dialog to the user saying a separate permission is needed
|
|
|
|
// Launch the settings activity if the user prefers
|
|
|
|
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
|
|
|
Uri.parse("package:" + activity.packageName))
|
|
|
|
activity.startActivity(intent)
|
|
|
|
}
|
2021-01-18 22:47:55 +01:00
|
|
|
}
|
2020-03-30 13:14:24 +02:00
|
|
|
rxBus.send(EventNewNotification(notification))
|
|
|
|
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|