Added permission request event

This commit is contained in:
Viktor De Pasquale 2019-04-24 19:34:40 +02:00
parent d4058175b4
commit 07eb7dda2d
4 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1,40 @@
package com.topjohnwu.magisk.model.permissions
typealias SimpleCallback = () -> Unit
typealias PermissionRationaleCallback = (List<String>) -> Unit
class PermissionRequestBuilder {
private var onSuccessCallback: SimpleCallback = {}
private var onFailureCallback: SimpleCallback = {}
private var onShowRationaleCallback: PermissionRationaleCallback = {}
fun onSuccess(callback: SimpleCallback) {
onSuccessCallback = callback
}
fun onFailure(callback: SimpleCallback) {
onFailureCallback = callback
}
fun onShowRationale(callback: PermissionRationaleCallback) {
onShowRationaleCallback = callback
}
fun build(): PermissionRequest {
return PermissionRequest(onSuccessCallback, onFailureCallback, onShowRationaleCallback)
}
}
class PermissionRequest(
private val onSuccessCallback: SimpleCallback,
private val onFailureCallback: SimpleCallback,
private val onShowRationaleCallback: PermissionRationaleCallback
) {
fun onSuccess() = onSuccessCallback()
fun onFailure() = onFailureCallback()
fun onShowRationale(permissions: List<String>) = onShowRationaleCallback(permissions)
}

View File

@ -7,14 +7,21 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.ncapdevi.fragnav.FragNavController import com.ncapdevi.fragnav.FragNavController
import com.ncapdevi.fragnav.FragNavTransactionOptions import com.ncapdevi.fragnav.FragNavTransactionOptions
import com.skoumal.teanity.viewevents.ViewEvent import com.skoumal.teanity.viewevents.ViewEvent
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.model.events.PermissionEvent
import com.topjohnwu.magisk.model.events.ViewActionEvent import com.topjohnwu.magisk.model.events.ViewActionEvent
import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder import com.topjohnwu.magisk.model.navigation.MagiskAnimBuilder
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
import com.topjohnwu.magisk.model.navigation.Navigator import com.topjohnwu.magisk.model.navigation.Navigator
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import timber.log.Timber import timber.log.Timber
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -64,6 +71,13 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
when (event) { when (event) {
is MagiskNavigationEvent -> navigateTo(event) is MagiskNavigationEvent -> navigateTo(event)
is ViewActionEvent -> event.action(this) is ViewActionEvent -> event.action(this)
is PermissionEvent -> withPermissions(*event.permissions.toTypedArray()) {
onSuccess { event.callback.onNext(true) }
onFailure {
event.callback.onNext(false)
event.callback.onError(SecurityException("User refused permissions"))
}
}
} }
} }
@ -135,6 +149,26 @@ abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBin
fun openUrl(url: String) = Utils.openLink(this, url.toUri()) fun openUrl(url: String) = Utils.openLink(this, url.toUri())
fun withPermissions(vararg permissions: String, builder: PermissionRequestBuilder.() -> Unit) {
val request = PermissionRequestBuilder().apply(builder).build()
Dexter.withActivity(this)
.withPermissions(*permissions)
.withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) =
if (report?.areAllPermissionsGranted() == true) {
request.onSuccess()
} else {
request.onFailure()
}
override fun onPermissionRationaleShouldBeShown(
permissions: MutableList<PermissionRequest>?,
token: PermissionToken?
) = request.onShowRationale(permissions.orEmpty().map { it.name })
})
.check()
}
private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) = private fun FragNavTransactionOptions.Builder.customAnimations(options: MagiskAnimBuilder) =
customAnimations(options.enter, options.exit, options.popEnter, options.popExit) customAnimations(options.enter, options.exit, options.popEnter, options.popExit)

View File

@ -5,9 +5,11 @@ import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.skoumal.teanity.view.TeanityFragment import com.skoumal.teanity.view.TeanityFragment
import com.skoumal.teanity.viewevents.ViewEvent import com.skoumal.teanity.viewevents.ViewEvent
import com.topjohnwu.magisk.model.events.PermissionEvent
import com.topjohnwu.magisk.model.events.ViewActionEvent import com.topjohnwu.magisk.model.events.ViewActionEvent
import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent import com.topjohnwu.magisk.model.navigation.MagiskNavigationEvent
import com.topjohnwu.magisk.model.navigation.Navigator import com.topjohnwu.magisk.model.navigation.Navigator
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -27,9 +29,20 @@ abstract class MagiskFragment<ViewModel : MagiskViewModel, Binding : ViewDataBin
when (event) { when (event) {
is MagiskNavigationEvent -> navigateTo(event) is MagiskNavigationEvent -> navigateTo(event)
is ViewActionEvent -> event.action(requireActivity()) is ViewActionEvent -> event.action(requireActivity())
is PermissionEvent -> magiskActivity.withPermissions(*event.permissions.toTypedArray()) {
onSuccess { event.callback.onNext(true) }
onFailure {
event.callback.onNext(false)
event.callback.onError(SecurityException("User refused permissions"))
}
}
} }
} }
fun withPermissions(vararg permissions: String, builder: PermissionRequestBuilder.() -> Unit) {
magiskActivity.withPermissions(*permissions, builder = builder)
}
fun openLink(url: String) = magiskActivity.openUrl(url) fun openLink(url: String) = magiskActivity.openUrl(url)
open fun onBackPressed(): Boolean = false open fun onBackPressed(): Boolean = false

View File

@ -2,8 +2,11 @@ package com.topjohnwu.magisk.ui.base
import android.app.Activity import android.app.Activity
import com.skoumal.teanity.viewmodel.LoadingViewModel import com.skoumal.teanity.viewmodel.LoadingViewModel
import com.topjohnwu.magisk.model.events.PermissionEvent
import com.topjohnwu.magisk.model.events.ViewActionEvent import com.topjohnwu.magisk.model.events.ViewActionEvent
import com.topjohnwu.magisk.utils.Event import com.topjohnwu.magisk.utils.Event
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import timber.log.Timber import timber.log.Timber
@ -16,4 +19,8 @@ abstract class MagiskViewModel : LoadingViewModel(), Event.AutoListener {
ViewActionEvent(action).publish() ViewActionEvent(action).publish()
} }
fun withPermissions(vararg permissions: String): Observable<Boolean> {
val subject = PublishSubject.create<Boolean>()
return subject.doOnSubscribe { PermissionEvent(permissions.toList(), subject).publish() }
}
} }