Skip to content

Commit

Permalink
Fix permissions bug
Browse files Browse the repository at this point in the history
  • Loading branch information
ismartcoding committed Feb 9, 2024
1 parent e5888f7 commit 48c94a5
Show file tree
Hide file tree
Showing 83 changed files with 265 additions and 224 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ android {
else -> 0
}

val vCode = 241
val vCode = 244
versionCode = vCode - singleAbiNum
versionName = "1.2.36"
versionName = "1.2.37"

ndk {
//noinspection ChromeOsAbiSupport
Expand Down
54 changes: 34 additions & 20 deletions app/src/main/java/com/ismartcoding/plain/features/Permissions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,16 @@ enum class Permission {
}
}

data class PermissionItem(val icon: ImageVector?, val permission: Permission, val permissions: Set<Permission>, val granted: Boolean)
data class PermissionItem(val icon: ImageVector?, val permission: Permission, val permissions: Set<Permission>, var granted: Boolean = false) {

companion object {
fun create(context: Context, icon: ImageVector?, permission: Permission, permissions: Set<Permission> = setOf(permission)): PermissionItem {
return PermissionItem(icon, permission, permissions).apply {
granted = permissions.all { it.can(context) }
}
}
}
}

object Permissions {
private val launcherMap = mutableMapOf<Permission, ActivityResultLauncher<String>>()
Expand All @@ -252,46 +261,51 @@ object Permissions {
private lateinit var multipleLauncher: ActivityResultLauncher<Array<String>>

suspend fun checkAsync(context: Context, permissions: Set<Permission>) {
val ps = permissions.map { it.toString() }
val apiPermissions = ApiPermissionsPreference.getAsync(context)
if (!apiPermissions.all { ps.contains(it) }) {
throw Exception("no_permission")
val apiPermissions = ApiPermissionsPreference.getAsync(context).toMutableSet()
if (apiPermissions.contains(Permission.WRITE_CONTACTS.toString())) {
apiPermissions.add(Permission.READ_CONTACTS.toString())
}
if (apiPermissions.contains(Permission.WRITE_CALL_LOG.toString())) {
apiPermissions.add(Permission.READ_CALL_LOG.toString())
}
for (item in permissions.map { it.toString() }) {
if (!apiPermissions.contains(item)) {
throw Exception("no_permission")
}
}
}

fun anyCan(context: Context, permissions: Set<Permission>): Boolean {
return permissions.any { it.can(context) }
fun allCan(context: Context, permissions: Set<Permission>): Boolean {
return permissions.all { it.can(context) }
}

fun getWebList(context: Context): List<PermissionItem> {
val list = mutableListOf<PermissionItem>()
list.add(
PermissionItem(Icons.Outlined.Folder, Permission.WRITE_EXTERNAL_STORAGE, setOf(Permission.WRITE_EXTERNAL_STORAGE),
setOf(Permission.WRITE_EXTERNAL_STORAGE).all { it.can(context) })
PermissionItem.create(
context, Icons.Outlined.Folder, Permission.WRITE_EXTERNAL_STORAGE
)
)
if (AppFeatureType.NOTIFICATIONS.has()) {
list.add(
PermissionItem(Icons.Outlined.Notifications, Permission.NOTIFICATION_LISTENER, setOf(Permission.NOTIFICATION_LISTENER),
setOf(Permission.NOTIFICATION_LISTENER).all { it.can(context) })
PermissionItem.create(context, Icons.Outlined.Notifications, Permission.NOTIFICATION_LISTENER)
)
}
list.add(
PermissionItem(Icons.Outlined.Contacts, Permission.WRITE_CONTACTS, setOf(Permission.WRITE_CONTACTS),
setOf(Permission.WRITE_CONTACTS).all { it.can(context) })
PermissionItem.create(context, Icons.Outlined.Contacts, Permission.WRITE_CONTACTS, setOf(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS))
)

if (AppFeatureType.SOCIAL.has()) {
list.add(PermissionItem(Icons.Outlined.Sms, Permission.READ_SMS, setOf(Permission.READ_SMS), setOf(Permission.READ_SMS).all { it.can(context) }))
list.add(PermissionItem(Icons.AutoMirrored.Outlined.List, Permission.WRITE_CALL_LOG, setOf(Permission.WRITE_CALL_LOG), setOf(Permission.WRITE_CALL_LOG).all { it.can(context) }))
list.add(PermissionItem.create(context, Icons.Outlined.Sms, Permission.READ_SMS))
list.add(PermissionItem.create(context, Icons.AutoMirrored.Outlined.List, Permission.WRITE_CALL_LOG, setOf(Permission.READ_CALL_LOG, Permission.WRITE_CALL_LOG)))
}
list.add(
PermissionItem(Icons.Outlined.Call, Permission.CALL_PHONE, setOf(Permission.CALL_PHONE),
setOf(Permission.CALL_PHONE).all { it.can(context) })
PermissionItem.create(context, Icons.Outlined.Call, Permission.CALL_PHONE)
)
list.add(
PermissionItem(Icons.Outlined.Numbers, Permission.READ_PHONE_NUMBERS, setOf(Permission.READ_PHONE_STATE, Permission.READ_PHONE_NUMBERS),
setOf(Permission.READ_PHONE_STATE, Permission.READ_PHONE_NUMBERS).all { it.can(context) })
PermissionItem.create(context, Icons.Outlined.Numbers, Permission.READ_PHONE_NUMBERS, setOf(Permission.READ_PHONE_STATE, Permission.READ_PHONE_NUMBERS))
)
list.add(PermissionItem(null, Permission.NONE, setOf(Permission.NONE), false))
list.add(PermissionItem(null, Permission.NONE, setOf(Permission.NONE)))
return list
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import com.ismartcoding.plain.R
import com.ismartcoding.plain.packageManager
import com.ismartcoding.plain.ui.helpers.DialogHelper
import com.ismartcoding.plain.ui.helpers.WebHelper
import java.util.regex.Matcher
import java.util.regex.Pattern
Expand Down Expand Up @@ -93,13 +96,21 @@ fun AnnotatedString.urlAt(

"EMAIL" -> {
val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:${it.item}"))
context.startActivity(emailIntent)
if (emailIntent.resolveActivity(packageManager) != null) {
context.startActivity(emailIntent)
} else {
DialogHelper.showMessage(R.string.not_supported_error)
}
return
}

"PHONE" -> {
val phoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${it.item}"))
context.startActivity(phoneIntent)
if (phoneIntent.resolveActivity(packageManager) != null) {
context.startActivity(phoneIntent)
} else {
DialogHelper.showMessage(R.string.not_supported_error)
}
return
}
}
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/com/ismartcoding/plain/ui/call/CallsDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.ismartcoding.plain.extensions.formatDateTime
import com.ismartcoding.plain.features.ActionEvent
import com.ismartcoding.plain.features.Permission
import com.ismartcoding.plain.features.PermissionResultEvent
import com.ismartcoding.plain.features.PermissionsResultEvent
import com.ismartcoding.plain.features.call.CallHelper
import com.ismartcoding.plain.features.call.DCall
import com.ismartcoding.plain.features.tag.TagHelper
Expand Down Expand Up @@ -57,6 +58,7 @@ class CallsDialog : BaseListDrawerDialog() {
}
}
}

R.id.delete -> {
if (!Permission.WRITE_CALL_LOG.can(requireContext())) {
Permission.WRITE_CALL_LOG.grant(requireContext())
Expand All @@ -78,6 +80,7 @@ class CallsDialog : BaseListDrawerDialog() {
}
}
}

else -> {
BottomMenuHelper.onMenuItemClick(viewModel, binding, this)
}
Expand All @@ -87,16 +90,17 @@ class CallsDialog : BaseListDrawerDialog() {

override fun initEvents() {
receiveEvent<PermissionResultEvent> { event ->
if (setOf(Permission.READ_CALL_LOG, Permission.WRITE_CALL_LOG).contains(event.permission)) {
checkPermission()
} else if (event.permission == Permission.CALL_PHONE) {
if (event.permission == Permission.CALL_PHONE) {
if (Permission.CALL_PHONE.can(requireContext())) {
CallHelper.call(requireContext(), phoneNumberToCall)
} else {
DialogHelper.showMessage(R.string.call_phone_permission_required)
}
}
}
receiveEvent<PermissionsResultEvent> { event ->
checkPermission()
}
receiveEvent<ActionEvent> { event ->
if (event.source == ActionSourceType.CALL) {
binding.list.page.refresh()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.ismartcoding.plain.data.enums.DataType
import com.ismartcoding.plain.features.ActionEvent
import com.ismartcoding.plain.features.Permission
import com.ismartcoding.plain.features.PermissionResultEvent
import com.ismartcoding.plain.features.PermissionsResultEvent
import com.ismartcoding.plain.features.call.CallHelper
import com.ismartcoding.plain.features.contact.ContactHelper
import com.ismartcoding.plain.features.contact.DContact
Expand Down Expand Up @@ -62,6 +63,7 @@ class ContactsDialog : BaseListDrawerDialog() {
}
}
}

R.id.delete -> {
if (!Permission.WRITE_CONTACTS.can(requireContext())) {
Permission.WRITE_CONTACTS.grant(requireContext())
Expand All @@ -83,6 +85,7 @@ class ContactsDialog : BaseListDrawerDialog() {
}
}
}

else -> {
BottomMenuHelper.onMenuItemClick(viewModel, binding, this)
}
Expand All @@ -97,16 +100,17 @@ class ContactsDialog : BaseListDrawerDialog() {

override fun initEvents() {
receiveEvent<PermissionResultEvent> { event ->
if (event.permission == Permission.READ_CONTACTS) {
checkPermission()
} else if (event.permission == Permission.CALL_PHONE) {
if (event.permission == Permission.CALL_PHONE) {
if (Permission.CALL_PHONE.can(requireContext())) {
CallHelper.call(requireContext(), phoneNumberToCall)
} else {
DialogHelper.showMessage(R.string.call_phone_permission_required)
}
}
}
receiveEvent<PermissionsResultEvent> { event ->
checkPermission()
}
receiveEvent<ActionEvent> { event ->
if (event.source == ActionSourceType.CONTACT) {
binding.list.page.refresh()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package com.ismartcoding.plain.ui.extensions
import android.content.Context
import android.view.View
import androidx.core.view.isVisible
import com.ismartcoding.lib.channel.sendEvent
import com.ismartcoding.plain.R
import com.ismartcoding.plain.databinding.ViewPageListBinding
import com.ismartcoding.plain.features.Permission
import com.ismartcoding.plain.features.Permissions
import com.ismartcoding.plain.features.RequestPermissionsEvent
import com.ismartcoding.plain.features.locale.LocaleHelper.getString

fun ViewPageListBinding.checkPermission(
context: Context,
permissions: Set<Permission>,
permission: Permission,
) {
if (Permissions.anyCan(context, permissions)) {
if (Permissions.allCan(context, permissions)) {
page.visibility = View.VISIBLE
empty.root.isVisible = false
page.showLoading()
Expand All @@ -26,7 +28,7 @@ fun ViewPageListBinding.checkPermission(
button.text = getString(R.string.grant_access)
button.isVisible = true
button.setSafeClick {
permission.grant(context)
sendEvent(RequestPermissionsEvent(permissions.toSet()))
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/com/ismartcoding/plain/ui/sms/SmsDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.ismartcoding.plain.extensions.formatDateTime
import com.ismartcoding.plain.features.ActionEvent
import com.ismartcoding.plain.features.Permission
import com.ismartcoding.plain.features.PermissionResultEvent
import com.ismartcoding.plain.features.PermissionsResultEvent
import com.ismartcoding.plain.features.sms.DMessage
import com.ismartcoding.plain.features.sms.SmsHelper
import com.ismartcoding.plain.ui.BaseListDrawerDialog
Expand Down Expand Up @@ -45,7 +46,7 @@ class SmsDialog : BaseListDrawerDialog() {
}

override fun initEvents() {
receiveEvent<PermissionResultEvent> {
receiveEvent<PermissionsResultEvent> {
checkPermission()
}
receiveEvent<ActionEvent> { event ->
Expand Down
33 changes: 19 additions & 14 deletions app/src/main/java/com/ismartcoding/plain/web/SXGraphQL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,9 @@ class SXGraphQL(val schema: Schema) {
}
query("imageCount") {
resolver { query: String ->
if (Permission.WRITE_EXTERNAL_STORAGE.can(MainApp.instance)) {
ImageHelper.count(MainApp.instance, QueryHelper.prepareQuery(query))
val context = MainApp.instance
if (Permission.WRITE_EXTERNAL_STORAGE.can(context)) {
ImageHelper.count(context, QueryHelper.prepareQuery(query))
} else {
0
}
Expand Down Expand Up @@ -374,9 +375,10 @@ class SXGraphQL(val schema: Schema) {
executor = Executor.DataLoaderPrepared
}
resolver { offset: Int, limit: Int, query: String ->
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS))
val context = MainApp.instance
Permissions.checkAsync(context, setOf(Permission.READ_CONTACTS))
try {
ContactHelper.search(MainApp.instance, QueryHelper.prepareQuery(query), limit, offset).map { it.toModel() }
ContactHelper.search(context, QueryHelper.prepareQuery(query), limit, offset).map { it.toModel() }
} catch (ex: Exception) {
LogCat.e(ex)
emptyList()
Expand All @@ -393,22 +395,23 @@ class SXGraphQL(val schema: Schema) {
}
query("contactCount") {
resolver { query: String ->
if (Permissions.anyCan(MainApp.instance, setOf(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS))) {
ContactHelper.count(MainApp.instance, QueryHelper.prepareQuery(query))
val context = MainApp.instance
if (Permission.READ_CONTACTS.can(context)) {
ContactHelper.count(context, QueryHelper.prepareQuery(query))
} else {
0
}
}
}
query("contactSources") {
resolver { ->
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS))
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CONTACTS))
SourceHelper.getAll().map { it.toModel() }
}
}
query("contactGroups") {
resolver { node: Execution.Node ->
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CONTACTS, Permission.WRITE_CONTACTS))
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CONTACTS))
val groups = GroupHelper.getAll().map { it.toModel() }
val fields = node.getFields()
if (fields.contains(ContactGroup::contactCount.name)) {
Expand All @@ -422,7 +425,7 @@ class SXGraphQL(val schema: Schema) {
executor = Executor.DataLoaderPrepared
}
resolver { offset: Int, limit: Int, query: String ->
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CALL_LOG, Permission.WRITE_CALL_LOG))
Permissions.checkAsync(MainApp.instance, setOf(Permission.READ_CALL_LOG))
CallHelper.search(MainApp.instance, QueryHelper.prepareQuery(query), limit, offset).map { it.toModel() }
}
type<Call> {
Expand All @@ -436,8 +439,9 @@ class SXGraphQL(val schema: Schema) {
}
query("callCount") {
resolver { query: String ->
if (Permissions.anyCan(MainApp.instance, setOf(Permission.READ_CALL_LOG, Permission.WRITE_CALL_LOG))) {
CallHelper.count(MainApp.instance, QueryHelper.prepareQuery(query))
val context = MainApp.instance
if (Permission.READ_CALL_LOG.can(context)) {
CallHelper.count(context, QueryHelper.prepareQuery(query))
} else {
0
}
Expand Down Expand Up @@ -606,9 +610,10 @@ class SXGraphQL(val schema: Schema) {
}
query("deviceInfo") {
resolver { ->
val apiPermissions = ApiPermissionsPreference.getAsync(MainApp.instance)
val readPhoneNumber = apiPermissions.contains(Permission.READ_PHONE_STATE.toString()) && apiPermissions.contains(Permission.READ_PHONE_NUMBERS.toString())
DeviceInfoHelper.getDeviceInfo(MainApp.instance, readPhoneNumber).toModel()
val context = MainApp.instance
val apiPermissions = ApiPermissionsPreference.getAsync(context)
val readPhoneNumber = apiPermissions.contains(Permission.READ_PHONE_NUMBERS.toString())
DeviceInfoHelper.getDeviceInfo(context, readPhoneNumber).toModel()
}
}
query("battery") {
Expand Down
Loading

0 comments on commit 48c94a5

Please sign in to comment.