Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block calls with failed verification #26

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [UNRELEASED]

- Added ability to block calls with failed verification (requires Android >= 11 and advanced blocking mode)
- Added icon to en-US fastlane metadata
- Fixed fastlane folder names for language nb-NO
- Fixed fastlane folder names for language pt-BR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public void onScreenCall(@NonNull Call.Details callDetails) {
String number = null;

if (!ignore) {

Uri handle = callDetails.getHandle();
LOG.trace("onScreenCall() handle: {}", handle);

Expand Down Expand Up @@ -98,8 +99,31 @@ public void onScreenCall(@NonNull Call.Details callDetails) {
}

if (!ignore) {
numberInfo = numberInfoService.getNumberInfo(number,
App.getSettings().getCachedAutoDetectedCountryCode(), false);
boolean isFailedVerification = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (callDetails.getCallerNumberVerificationStatus() ==
Connection.VERIFICATION_STATUS_FAILED
) {
LOG.trace("onScreenCall() verification failed");
isFailedVerification = true;
}
if (callDetails.getCallerNumberVerificationStatus() ==
Connection.VERIFICATION_STATUS_NOT_VERIFIED
) {
LOG.trace("onScreenCall() not verified");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you live in France like me, mobile phone numbers always return NOT_VERIFIED.
So, to test the feature, you could add isFailedVerification = true; here and have someone call you (remember to remove it afterwards).

}
if (callDetails.getCallerNumberVerificationStatus() ==
Connection.VERIFICATION_STATUS_PASSED
) {
LOG.trace("onScreenCall() verification passed");
}
}
numberInfo = numberInfoService.getNumberInfo(
number,
App.getSettings().getCachedAutoDetectedCountryCode(),
false,
isFailedVerification
);

shouldBlock = numberInfoService.shouldBlock(numberInfo);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,22 @@ private static String getInfoDescription(Context context, NumberInfo numberInfo)
private static String getBlockedDescription(Context context, NumberInfo numberInfo) {
String text = numberInfo.name;

text = concat(text, "\n", getFailedVerificationDescriptionPart(context, numberInfo));
text = concat(text, "\n", getCommunityDescriptionPart(context, numberInfo));
text = concat(text, "\n", getDenylistDescriptionPart(context, numberInfo));
text = concat(text, "\n", getNumberDescriptionPart(context, numberInfo));

return text;
}

private static String getFailedVerificationDescriptionPart(Context context, NumberInfo numberInfo) {
if (numberInfo.isFailedVerification) {
return context.getString(R.string.info_failed_verification);
}

return null;
}

private static String getNumberDescriptionPart(Context context, NumberInfo numberInfo) {
return numberInfo.noNumber ? context.getString(R.string.no_number) : numberInfo.number;
}
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/fr/vinetos/tranquille/NumberInfoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
public class NumberInfoUtils {

public static String getShortDescription(Context context, NumberInfo numberInfo) {
if (numberInfo.isFailedVerification) {
return context.getString(R.string.info_failed_verification);
}

if (numberInfo.communityDatabaseItem != null) {
NumberCategory category = NumberCategory.getById(
numberInfo.communityDatabaseItem.getCategory());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ protected void initScreen() {
return true;
};
setPrefChangeListener(Settings.PREF_BLOCK_NEGATIVE_SIA_NUMBERS, callBlockingListener);
setPrefChangeListener(Settings.PREF_BLOCK_FAILED_VERIFICATION, callBlockingListener);
setPrefChangeListener(Settings.PREF_BLOCK_HIDDEN_NUMBERS, callBlockingListener);
setPrefChangeListener(Settings.PREF_BLOCK_DENYLISTED, callBlockingListener);

Expand All @@ -129,6 +130,11 @@ protected void initScreen() {
callScreeningPref.setVisible(false);
}

SwitchPreferenceCompat blockFailedVerificationPref =
requirePreference(Settings.PREF_BLOCK_FAILED_VERIFICATION);
blockFailedVerificationPref.setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R);
blockFailedVerificationPref.setEnabled(callScreeningPref.isChecked());

setPrefChangeListener(Settings.PREF_USE_MONITORING_SERVICE, (pref, newValue) -> {
boolean enabled = Boolean.TRUE.equals(newValue);
Context context = requireContext();
Expand Down Expand Up @@ -211,8 +217,17 @@ protected void initScreen() {
private void updateCallScreeningPreference() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return;

boolean isCallScreeningHeld = PermissionHelper.isCallScreeningHeld(requireContext());
this.<SwitchPreferenceCompat>requirePreference(PREF_USE_CALL_SCREENING_SERVICE)
.setChecked(PermissionHelper.isCallScreeningHeld(requireContext()));
.setChecked(isCallScreeningHeld);

this.<SwitchPreferenceCompat>requirePreference(Settings.PREF_BLOCK_FAILED_VERIFICATION)
.setEnabled(isCallScreeningHeld);

this.<SwitchPreferenceCompat>requirePreference(Settings.PREF_BLOCK_FAILED_VERIFICATION)
.setChecked(
isCallScreeningHeld && App.getSettings().getBlockFailedVerificationEnabled()
);
}

private void updateBlockedCallNotificationsPreference() {
Expand Down
20 changes: 19 additions & 1 deletion app/src/main/java/fr/vinetos/tranquille/Settings.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.vinetos.tranquille;

import android.content.Context;
import android.os.Build;
import android.text.TextUtils;

import androidx.appcompat.app.AppCompatDelegate;
Expand All @@ -21,6 +22,7 @@ public class Settings extends GenericSettings {

public static final String PREF_INCOMING_CALL_NOTIFICATIONS = "incomingCallNotifications";
public static final String PREF_BLOCK_NEGATIVE_SIA_NUMBERS = "blockNegativeSiaNumbers";
public static final String PREF_BLOCK_FAILED_VERIFICATION = "blockFailedVerification";
public static final String PREF_BLOCK_HIDDEN_NUMBERS = "blockHiddenNumbers";
public static final String PREF_BLOCK_DENYLISTED = "blockDenylisted";
public static final String PREF_DENYLIST_IS_NOT_EMPTY = "denylistIsNotEmpty";
Expand Down Expand Up @@ -124,7 +126,10 @@ public void setIncomingCallNotifications(boolean show) {
}

public boolean getCallBlockingEnabled() {
return getBlockNegativeSiaNumbers() || getBlockHiddenNumbers() || getDenylistEnabled();
return getBlockNegativeSiaNumbers() ||
getBlockHiddenNumbers() ||
getDenylistEnabled() ||
getBlockFailedVerificationEnabled();
}

public boolean getBlockNegativeSiaNumbers() {
Expand All @@ -135,6 +140,19 @@ public void setBlockNegativeSiaNumbers(boolean block) {
setBoolean(PREF_BLOCK_NEGATIVE_SIA_NUMBERS, block);
}

/**
* STIR verification is only available from Android 11
*/
public boolean getBlockFailedVerificationEnabled() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
PermissionHelper.isCallScreeningHeld(context) &&
getBoolean(PREF_BLOCK_FAILED_VERIFICATION);
}

public void setBlockFailedVerificationEnabled(boolean block) {
setBoolean(PREF_BLOCK_FAILED_VERIFICATION, block);
}

public boolean getBlockHiddenNumbers() {
return getBoolean(PREF_BLOCK_HIDDEN_NUMBERS);
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/fr/vinetos/tranquille/data/NumberInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
public class NumberInfo {

public enum BlockingReason {
HIDDEN_NUMBER, SIA_RATING, DENYLISTED
HIDDEN_NUMBER, SIA_RATING, DENYLISTED, FAILED_VERIFICATION
}

public enum Rating {
Expand All @@ -19,6 +19,7 @@ public enum Rating {

// info from various sources
public boolean isHiddenNumber;
public boolean isFailedVerification;
public ContactItem contactItem;
public CommunityDatabaseItem communityDatabaseItem;
public FeaturedDatabaseItem featuredDatabaseItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,25 @@ public NumberInfoService(Settings settings, HiddenNumberDetector hiddenNumberDet
this.denylistService = denylistService;
}

public NumberInfo getNumberInfo(String number, String countryCode, boolean full) {
public NumberInfo getNumberInfo(
String number,
String countryCode,
boolean full
) {
return getNumberInfo(number, countryCode, full, false);
}

public NumberInfo getNumberInfo(
String number,
String countryCode,
boolean full,
boolean isFailedVerification
) {
LOG.debug("getNumberInfo({}, {}, {}) started", number, countryCode, full);

NumberInfo numberInfo = new NumberInfo();
numberInfo.number = number;
numberInfo.isFailedVerification = isFailedVerification;

if (hiddenNumberDetector != null) {
numberInfo.isHiddenNumber = hiddenNumberDetector.isHiddenNumber(number);
Expand Down Expand Up @@ -130,6 +144,12 @@ public NumberInfo getNumberInfo(String number, String countryCode, boolean full)
}

protected NumberInfo.BlockingReason getBlockingReason(NumberInfo numberInfo) {
// We must do that prior to contact checking as we don't want someone to impersonate a
// contact
if (numberInfo.isFailedVerification && settings.getBlockFailedVerificationEnabled()) {
return NumberInfo.BlockingReason.FAILED_VERIFICATION;
}

if (numberInfo.contactItem != null) return null;

if (numberInfo.isHiddenNumber && settings.getBlockHiddenNumbers()) {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
<string name="block_negative_sia_short">Bloquer selon la notation</string>
<string name="block_negative_sia">Blocage en fonction de la notation</string>
<string name="block_negative_sia_numbers_summary">Bloquer les appels provenant de numéros ayant une note négative (sur la base d\'une base de données communautaire))</string>
<string name="block_failed_verification">Bloquer en cas d’échec de vérification</string>
<string name="block_failed_verification_summary">Bloquer les appels échouant la vérification STIR, indiquant que l’appel entrant pourrait ne pas être véritablement du numéro indiqué. Cela peut se produire si, par exemple, l’appelant utilise un numéro usurpé. Nécessite le mode de blocage d’appel avancé.</string>
<string name="block_hidden_number">Bloquer les numéros masqués</string>
<string name="block_hidden_number_summary">Bloquer les appels provenant de numéros masqués. Peut fonctionner différemment (meilleur ou pire) en « Mode de blocage d\'appel avancé »</string>
<string name="use_call_screening_service">Mode de blocage d\'appel avancé</string>
Expand Down Expand Up @@ -122,6 +124,7 @@
<string name="open_db_management_activity">Gérer la base de données</string>
<string name="add_to_denylist">Ajouter à la liste de blocage</string>
<string name="info_in_denylist_contact">Sur la liste de blocage (les contacts ne sont pas bloqués)</string>
<string name="info_failed_verification">Vérification échouée</string>
<string name="info_in_denylist">Sur la liste de blocage</string>
<string name="number_pattern_hint">Entrez le numéro au format +INDICATIF-PAYS (comme Android l’indique dans votre clavier). Utilisez « * » comme caractère générique pour zéro ou plus de chiffres, et « # » pour exactement un chiffre.</string>
<string name="number_pattern_empty">Modèle vide</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@
<string name="block_negative_sia_short">Block by rating</string>
<string name="block_negative_sia">Block based on rating</string>
<string name="block_negative_sia_numbers_summary">Block calls from numbers with negative rating (based on a community database)</string>
<string name="block_failed_verification">Block failed verification</string>
<string name="block_failed_verification_summary">Block calls failing the STIR verification, indicating that the incoming call may not actually be from the indicated number. This could occur if, for example, the caller is using an impersonated phone number. Requires “Advanced call blocking mode”.</string>
<string name="block_hidden_number">Block hidden numbers</string>
<string name="block_hidden_number_summary">Block calls from hidden numbers. May work differently (better or worse) in \"Advanced call blocking mode\"</string>
<string name="block_denylisted_short">Enable denylist</string>
Expand Down Expand Up @@ -205,6 +207,7 @@
<string name="contacts_are_not_blocked_denylist_notice">Calls from contacts are never blocked (even on pattern match)</string>
<string name="contacts_are_not_blocked_not_enabled">Calls from contacts may be blocked because the \"Use contacts\" option is not enabled!</string>
<string name="contacts_are_not_blocked_no_permission">Calls from contacts may be blocked because the \"Contacts\" permission is not granted!</string>
<string name="info_failed_verification">Failed verification</string>
<string name="info_in_denylist">In denylist</string>
<string name="info_in_denylist_contact">In denylist (contacts are not blocked)</string>
<string name="add_to_denylist">Add to denylist</string>
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/xml/root_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
app:persistent="false"
app:summary="@string/use_call_screening_service_summary"
app:title="@string/use_call_screening_service" />
<SwitchPreferenceCompat
app:key="blockFailedVerification"
app:summary="@string/block_failed_verification_summary"
app:title="@string/block_failed_verification" />
</PreferenceCategory>

<SwitchPreferenceCompat
Expand Down