Ignore repeating events
This commit is contained in:
parent
29f36b883a
commit
24f4dd5881
|
@ -26,7 +26,7 @@ public class CallMonitoringService extends Service {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CallMonitoringService.class);
|
||||
|
||||
private final MyPhoneStateListener phoneStateListener = new MyPhoneStateListener(this);
|
||||
private final MyPhoneStateListener phoneStateListener = new MyPhoneStateListener();
|
||||
private final CallReceiver callReceiver = new CallReceiver(true);
|
||||
|
||||
private boolean monitoringStarted;
|
||||
|
@ -122,12 +122,6 @@ public class CallMonitoringService extends Service {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MyPhoneStateListener.class);
|
||||
|
||||
private final Context context;
|
||||
|
||||
public MyPhoneStateListener(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String phoneNumber) {
|
||||
LOG.info("onCallStateChanged({}, \"{}\")", state, phoneNumber);
|
||||
|
@ -143,13 +137,13 @@ public class CallMonitoringService extends Service {
|
|||
PhoneStateHandler phoneStateHandler = YacbHolder.getPhoneStateHandler();
|
||||
switch (state) {
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
phoneStateHandler.onIdle(context, phoneNumber);
|
||||
phoneStateHandler.onIdle(phoneNumber);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
phoneStateHandler.onRinging(context, phoneNumber);
|
||||
phoneStateHandler.onRinging(phoneNumber);
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
phoneStateHandler.onOffHook(context, phoneNumber);
|
||||
phoneStateHandler.onOffHook(phoneNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,11 +58,11 @@ public class CallReceiver extends BroadcastReceiver {
|
|||
|
||||
PhoneStateHandler phoneStateHandler = YacbHolder.getPhoneStateHandler();
|
||||
if (TelephonyManager.EXTRA_STATE_RINGING.equals(telephonyExtraState)) {
|
||||
phoneStateHandler.onRinging(context, incomingNumber);
|
||||
phoneStateHandler.onRinging(incomingNumber);
|
||||
} else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(telephonyExtraState)) {
|
||||
phoneStateHandler.onOffHook(context, incomingNumber);
|
||||
phoneStateHandler.onOffHook(incomingNumber);
|
||||
} else if (TelephonyManager.EXTRA_STATE_IDLE.equals(telephonyExtraState)) {
|
||||
phoneStateHandler.onIdle(context, incomingNumber);
|
||||
phoneStateHandler.onIdle(incomingNumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
package dummydomain.yetanothercallblocker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import dummydomain.yetanothercallblocker.data.NumberInfo;
|
||||
import dummydomain.yetanothercallblocker.data.NumberInfoService;
|
||||
import dummydomain.yetanothercallblocker.event.CallEndedEvent;
|
||||
|
@ -17,30 +23,50 @@ public class PhoneStateHandler {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PhoneStateHandler.class);
|
||||
|
||||
private final Context context;
|
||||
private final Settings settings;
|
||||
private final NumberInfoService numberInfoService;
|
||||
private final NotificationService notificationService;
|
||||
|
||||
private boolean isOffHook;
|
||||
|
||||
public PhoneStateHandler(Settings settings, NumberInfoService numberInfoService,
|
||||
private List<CallEvent> lastEvents = new ArrayList<>();
|
||||
private long lastEventTimestamp;
|
||||
|
||||
public PhoneStateHandler(Context context, Settings settings,
|
||||
NumberInfoService numberInfoService,
|
||||
NotificationService notificationService) {
|
||||
this.context = context;
|
||||
this.settings = settings;
|
||||
this.numberInfoService = numberInfoService;
|
||||
this.notificationService = notificationService;
|
||||
}
|
||||
|
||||
public void onRinging(Context context, String phoneNumber) {
|
||||
public void onRinging(String phoneNumber) {
|
||||
LOG.debug("onRinging({})", phoneNumber);
|
||||
|
||||
boolean ignore = false;
|
||||
|
||||
if (phoneNumber == null) {
|
||||
if (!PermissionHelper.hasNumberInfoPermissions(context)) {
|
||||
LOG.warn("No info permissions");
|
||||
LOG.warn("onRinging() no info permissions");
|
||||
return;
|
||||
}
|
||||
return; // TODO: check
|
||||
|
||||
// TODO: check
|
||||
LOG.debug("onRinging() ignoring null");
|
||||
ignore = true;
|
||||
}
|
||||
|
||||
if (!ignore && !shouldProcess(phoneNumber)) {
|
||||
LOG.debug("onRinging() ignoring repeated event");
|
||||
ignore = true;
|
||||
}
|
||||
|
||||
recordEvent(phoneNumber);
|
||||
|
||||
if (ignore) return;
|
||||
|
||||
boolean blockingEnabled = settings.getCallBlockingEnabled();
|
||||
boolean showNotifications = settings.getIncomingCallNotifications();
|
||||
|
||||
|
@ -53,7 +79,7 @@ public class PhoneStateHandler {
|
|||
|
||||
boolean blocked = false;
|
||||
if (blockingEnabled && !isOffHook && numberInfoService.shouldBlock(numberInfo)) {
|
||||
blocked = PhoneUtils.rejectCall(context);
|
||||
blocked = PhoneUtils.endCall(context);
|
||||
|
||||
if (blocked) {
|
||||
notificationService.notifyCallBlocked(numberInfo);
|
||||
|
@ -69,7 +95,7 @@ public class PhoneStateHandler {
|
|||
}
|
||||
}
|
||||
|
||||
public void onOffHook(Context context, String phoneNumber) {
|
||||
public void onOffHook(String phoneNumber) {
|
||||
LOG.debug("onOffHook({})", phoneNumber);
|
||||
|
||||
isOffHook = true;
|
||||
|
@ -77,7 +103,7 @@ public class PhoneStateHandler {
|
|||
postEvent(new CallOngoingEvent());
|
||||
}
|
||||
|
||||
public void onIdle(Context context, String phoneNumber) {
|
||||
public void onIdle(String phoneNumber) {
|
||||
LOG.debug("onIdle({})", phoneNumber);
|
||||
|
||||
isOffHook = false;
|
||||
|
@ -87,4 +113,41 @@ public class PhoneStateHandler {
|
|||
postEvent(new CallEndedEvent());
|
||||
}
|
||||
|
||||
private boolean shouldProcess(String phoneNumber) {
|
||||
// using 1 second ago as the cutoff point - consider everything older as unrelated events
|
||||
long cutoff = System.nanoTime() - TimeUnit.SECONDS.toNanos(1);
|
||||
|
||||
if (lastEventTimestamp - cutoff < 0) { // no events in the last second
|
||||
lastEvents.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
for (ListIterator<CallEvent> it = lastEvents.listIterator(); it.hasNext(); ) {
|
||||
CallEvent event = it.next();
|
||||
if (event.timestamp - cutoff < 0) { // event is older than the cutoff point
|
||||
it.remove();
|
||||
} else if (TextUtils.equals(event.number, phoneNumber)) {
|
||||
return false; // don't process same event
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void recordEvent(String phoneNumber) {
|
||||
long currentTimestamp = System.nanoTime();
|
||||
lastEvents.add(new CallEvent(phoneNumber, currentTimestamp));
|
||||
lastEventTimestamp = currentTimestamp;
|
||||
}
|
||||
|
||||
private static class CallEvent {
|
||||
final String number;
|
||||
final long timestamp;
|
||||
|
||||
public CallEvent(String number, long timestamp) {
|
||||
this.number = number;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class Config {
|
|||
YacbHolder.setNotificationService(notificationService);
|
||||
|
||||
YacbHolder.setPhoneStateHandler(
|
||||
new PhoneStateHandler(settings, numberInfoService, notificationService));
|
||||
new PhoneStateHandler(context, settings, numberInfoService, notificationService));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class YacbHolder {
|
|||
@SuppressLint("StaticFieldLeak")
|
||||
private static NotificationService notificationService;
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static PhoneStateHandler phoneStateHandler;
|
||||
|
||||
static void setWebService(WebService webService) {
|
||||
|
|
|
@ -22,7 +22,7 @@ public class PhoneUtils {
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PhoneUtils.class);
|
||||
|
||||
public static boolean rejectCall(@NonNull Context context) {
|
||||
public static boolean endCall(@NonNull Context context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
try {
|
||||
TelecomManager telecomManager = requireNonNull(
|
||||
|
|
Loading…
Reference in New Issue