diff --git a/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt b/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt index 676a7d20..e4e7f678 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt @@ -34,9 +34,9 @@ class BlockingManager @Inject constructor( override fun isAvailable(): Boolean = client.isAvailable() - override fun getClientCapability(): BlockingClientCapability = client.getClientCapability() + override fun getClientCapability(): BlockingClient.Capability = client.getClientCapability() - override fun isBlocked(address: String): Single = client.isBlocked(address) + override fun getAction(address: String): Single = client.getAction(address) override fun block(addresses: List): Completable = client.block(addresses) diff --git a/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt index debe6276..9abd7666 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt @@ -46,16 +46,19 @@ class CallControlBlockingClient @Inject constructor( override fun isAvailable(): Boolean = context.isInstalled("com.flexaspect.android.everycallcontrol") - override fun getClientCapability() = BlockingClientCapability.BLOCK_WITH_PERMISSION + override fun getClientCapability() = BlockingClient.Capability.BLOCK_WITH_PERMISSION - override fun isBlocked(address: String): Single { + override fun getAction(address: String): Single = Single.fromCallable { val uri = Uri.withAppendedPath(CallControl.LOOKUP_TEXT_URI, address) - return Single.fromCallable { - tryOrNull { - context.contentResolver.query(uri, projection, null, null, null) // Query URI - ?.use { cursor -> cursor.map(::LookupResult) } // Map to Result object - ?.any { result -> result.blockReason != null } // Check if any are blocked - } == true // If none are blocked or we errored at some point, return false + val blocked = tryOrNull { + context.contentResolver.query(uri, projection, null, null, null) // Query URI + ?.use { cursor -> cursor.map(::LookupResult) } // Map to Result object + ?.any { result -> result.blockReason != null } // Check if any are blocked + } == true // If none are blocked or we errored at some point, return false + + when (blocked) { + true -> BlockingClient.Action.BLOCK + false -> BlockingClient.Action.UNBLOCK } } diff --git a/data/src/main/java/com/moez/QKSMS/blocking/QksmsBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/QksmsBlockingClient.kt index da35b38c..191815c1 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/QksmsBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/QksmsBlockingClient.kt @@ -29,10 +29,13 @@ class QksmsBlockingClient @Inject constructor( override fun isAvailable(): Boolean = true - override fun getClientCapability() = BlockingClientCapability.BLOCK_WITHOUT_PERMISSION + override fun getClientCapability() = BlockingClient.Capability.BLOCK_WITHOUT_PERMISSION - override fun isBlocked(address: String): Single = Single.fromCallable { - blockingRepo.isBlocked(address) + override fun getAction(address: String): Single = Single.fromCallable { + when (blockingRepo.isBlocked(address)) { + true -> BlockingClient.Action.BLOCK + false -> BlockingClient.Action.UNBLOCK + } } override fun block(addresses: List): Completable = Completable.fromCallable { diff --git a/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt index ba605495..4b1ad8fc 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt @@ -53,13 +53,16 @@ class ShouldIAnswerBlockingClient @Inject constructor( "org.mistergroup.muzutozvednout") .any(context::isInstalled) - override fun getClientCapability() = BlockingClientCapability.CANT_BLOCK + override fun getClientCapability() = BlockingClient.Capability.CANT_BLOCK - /** - * Return a Single which emits whether or not the given [address] should be blocked - */ - override fun isBlocked(address: String): Single { + override fun getAction(address: String): Single { return Binder(context, address).isBlocked() + .map { blocked -> + when (blocked) { + true -> BlockingClient.Action.BLOCK + false -> BlockingClient.Action.DO_NOTHING + } + } } override fun block(addresses: List): Completable = Completable.fromCallable { openSettings() } diff --git a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt index 6d98a4fe..74741184 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt @@ -355,7 +355,7 @@ class ConversationRepositoryImpl @Inject constructor( } conversation.blocked = recipients.any { recipient -> - blockingClient.isBlocked(recipient.address).blockingGet() + blockingClient.getAction(recipient.address).blockingGet() == BlockingClient.Action.BLOCK } conversation.recipients.clear() diff --git a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt b/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt index 363ee9a0..42605f4a 100644 --- a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt +++ b/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt @@ -23,6 +23,22 @@ import io.reactivex.Single interface BlockingClient { + enum class Capability { + BLOCK_WITHOUT_PERMISSION, + BLOCK_WITH_PERMISSION , + CANT_BLOCK + } + + enum class Action { + BLOCK, + UNBLOCK, + + // We only need these for Should I Answer, because they don't allow us to block numbers in their app directly. + // This means there's a good chance that if a number is blocked in QK, it won't be blocked there, so we + // shouldn't unblock the conversation in that case + DO_NOTHING + } + /** * Returns true if the target blocking client is available for use, ie. it is installed */ @@ -31,12 +47,12 @@ interface BlockingClient { /** * Returns the level of access that the given blocking client provides to QKSMS */ - fun getClientCapability(): BlockingClientCapability + fun getClientCapability(): Capability /** - * Return a Single which emits whether or not the given [address] should be blocked + * Returns the recommendation action to perform given a message from the [address] */ - fun isBlocked(address: String): Single + fun getAction(address: String): Single /** * Blocks the numbers or opens the manager diff --git a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClientCapability.kt b/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClientCapability.kt deleted file mode 100644 index 7a971faf..00000000 --- a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClientCapability.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2019 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ -package com.moez.QKSMS.blocking - -enum class BlockingClientCapability { - BLOCK_WITHOUT_PERMISSION, - BLOCK_WITH_PERMISSION , - CANT_BLOCK -} diff --git a/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveMms.kt b/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveMms.kt index cc6861cd..0ec33921 100644 --- a/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveMms.kt +++ b/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveMms.kt @@ -57,19 +57,19 @@ class ReceiveMms @Inject constructor( // to check if it should be blocked after we've pulled it into realm. If it // turns out that it should be dropped, then delete it // TODO Don't store blocked messages in the first place - val shouldBlock = blockingClient.isBlocked(message.address).blockingGet() + val action = blockingClient.getAction(message.address).blockingGet() val shouldDrop = prefs.drop.get() - Timber.v("block=$shouldBlock, drop=$shouldDrop") + Timber.v("block=$action, drop=$shouldDrop") - if (shouldBlock && shouldDrop) { + if (action == BlockingClient.Action.BLOCK && shouldDrop) { messageRepo.deleteMessages(message.id) return@mapNotNull null } - if (shouldBlock) { - conversationRepo.markBlocked(message.threadId) - } else { - conversationRepo.markUnblocked(message.threadId) + when (action) { + BlockingClient.Action.BLOCK -> conversationRepo.markBlocked(message.threadId) + BlockingClient.Action.UNBLOCK -> conversationRepo.markUnblocked(message.threadId) + else -> Unit } message diff --git a/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveSms.kt b/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveSms.kt index bbcd352c..c15b2667 100644 --- a/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveSms.kt +++ b/domain/src/main/java/com/moez/QKSMS/interactor/ReceiveSms.kt @@ -49,12 +49,12 @@ class ReceiveSms @Inject constructor( // Don't continue if the sender is blocked val messages = it.messages val address = messages[0].displayOriginatingAddress - val shouldBlock = blockingClient.isBlocked(address).blockingGet() + val action = blockingClient.getAction(address).blockingGet() val shouldDrop = prefs.drop.get() - Timber.v("block=$shouldBlock, drop=$shouldDrop") + Timber.v("block=$action, drop=$shouldDrop") // If we should drop the message, don't even save it - if (shouldBlock && shouldDrop) { + if (action == BlockingClient.Action.BLOCK && shouldDrop) { return@mapNotNull null } @@ -66,10 +66,10 @@ class ReceiveSms @Inject constructor( // Add the message to the db val message = messageRepo.insertReceivedSms(it.subId, address, body, time) - if (shouldBlock) { - conversationRepo.markBlocked(message.threadId) - } else { - conversationRepo.markUnblocked(message.threadId) + when (action) { + BlockingClient.Action.BLOCK -> conversationRepo.markBlocked(message.threadId) + BlockingClient.Action.UNBLOCK -> conversationRepo.markUnblocked(message.threadId) + else -> Unit } message diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingDialog.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingDialog.kt index 26ea8f4e..e7d7c3c5 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingDialog.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingDialog.kt @@ -23,7 +23,6 @@ import android.app.AlertDialog import android.content.Context import com.moez.QKSMS.R import com.moez.QKSMS.blocking.BlockingClient -import com.moez.QKSMS.blocking.BlockingClientCapability import com.moez.QKSMS.interactor.MarkBlocked import com.moez.QKSMS.interactor.MarkUnblocked import com.moez.QKSMS.repository.ConversationRepository @@ -55,7 +54,7 @@ class BlockingDialog @Inject constructor( return@launch } - if (blockingManager.getClientCapability() == BlockingClientCapability.BLOCK_WITHOUT_PERMISSION) { + if (blockingManager.getClientCapability() == BlockingClient.Capability.BLOCK_WITHOUT_PERMISSION) { // If we can block/unblock in the external manager, then just fire that off and exit if (block) { markBlocked.execute(conversationIds) @@ -64,7 +63,7 @@ class BlockingDialog @Inject constructor( markUnblocked.execute(conversationIds) blockingManager.unblock(addresses).subscribe() } - } else if (addresses.all { address -> block == blockingManager.isBlocked(address).blockingGet() }) { + } else if (block == allBlocked(addresses)) { // If all of the addresses are already in their correct state in the blocking manager, just marked the // conversations blocked and exit when (block) { @@ -77,6 +76,10 @@ class BlockingDialog @Inject constructor( } } + private fun allBlocked(addresses: List): Boolean = addresses.all { address -> + blockingManager.getAction(address).blockingGet() == BlockingClient.Action.BLOCK + } + private suspend fun showDialog( activity: Activity, conversationIds: List, diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt index 1cd19e00..2c0d5d7c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt @@ -99,7 +99,7 @@ class BlockingManagerPresenter @Inject constructor( .switchMap { numbers -> callControl.block(numbers).andThen(Observable.just(Unit)) } // Hack .autoDisposable(view.scope()) .subscribe { - callControl.isBlocked("callcontrol").blockingGet() + callControl.getAction("callcontrol").blockingGet() analytics.setUserProperty("Blocking Manager", "Call Control") prefs.blockingManager.set(Preferences.BLOCKING_MANAGER_CC) } @@ -142,6 +142,6 @@ class BlockingManagerPresenter @Inject constructor( private fun getAddressesToBlock(client: BlockingClient) = conversationRepo.getBlockedConversations() .fold(listOf(), { numbers, conversation -> numbers + conversation.recipients.map { it.address } }) - .filter { number -> !client.isBlocked(number).blockingGet() } + .filter { number -> client.getAction(number).blockingGet() != BlockingClient.Action.BLOCK } }