From c7ec1530095dd90c041d6b5d340e9e66056c3b3b Mon Sep 17 00:00:00 2001 From: twyen Date: Tue, 5 Dec 2017 15:00:23 -0800 Subject: Ignore "new" voicemails that are too old for notifications Bug: 68049435 Test: CallLogNotificationQueryHelperTest PiperOrigin-RevId: 178016400 Change-Id: I6ddbebc9edce6830966072d42cf05eb21f26c8ac --- .../calllog/CallLogNotificationsQueryHelper.java | 56 +++++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java b/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java index f962e17ac..47457360d 100644 --- a/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java +++ b/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java @@ -28,6 +28,7 @@ import android.os.Build; import android.provider.CallLog.Calls; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.support.v4.os.UserManagerCompat; import android.telephony.PhoneNumberUtils; @@ -35,7 +36,9 @@ import android.text.TextUtils; import com.android.dialer.app.R; import com.android.dialer.calllogutils.PhoneNumberDisplayUtil; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.database.Selection; import com.android.dialer.compat.android.provider.VoicemailCompat; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.location.GeoUtil; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumbercache.ContactInfoHelper; @@ -43,11 +46,16 @@ import com.android.dialer.util.PermissionsUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; /** Helper class operating on call log notifications. */ @TargetApi(Build.VERSION_CODES.M) public class CallLogNotificationsQueryHelper { + @VisibleForTesting + static final String CONFIG_NEW_VOICEMAIL_NOTIFICATION_THRESHOLD_OFFSET = + "new_voicemail_notification_threshold"; + private final Context mContext; private final NewCallsQuery mNewCallsQuery; private final ContactInfoHelper mContactInfoHelper; @@ -147,7 +155,12 @@ public class CallLogNotificationsQueryHelper { */ @Nullable public List getNewVoicemails() { - return mNewCallsQuery.query(Calls.VOICEMAIL_TYPE); + return mNewCallsQuery.query( + Calls.VOICEMAIL_TYPE, + System.currentTimeMillis() + - ConfigProviderBindings.get(mContext) + .getLong( + CONFIG_NEW_VOICEMAIL_NOTIFICATION_THRESHOLD_OFFSET, TimeUnit.DAYS.toMillis(7))); } /** @@ -220,10 +233,21 @@ public class CallLogNotificationsQueryHelper { /** Allows determining the new calls for which a notification should be generated. */ public interface NewCallsQuery { + long NO_THRESHOLD = Long.MAX_VALUE; + /** Returns the new calls of a certain type for which a notification should be generated. */ @Nullable List query(int type); + /** + * Returns the new calls of a certain type for which a notification should be generated. + * + * @param thresholdMillis New calls added before this timestamp will be considered old, or + * {@link #NO_THRESHOLD} if threshold is not checked. + */ + @Nullable + List query(int type, long thresholdMillis); + /** Returns a {@link NewCall} pointed by the {@code callsUri} */ @Nullable NewCall query(Uri callsUri); @@ -317,6 +341,14 @@ public class CallLogNotificationsQueryHelper { @Nullable @TargetApi(Build.VERSION_CODES.M) public List query(int type) { + return query(type, NO_THRESHOLD); + } + + @Override + @Nullable + @TargetApi(Build.VERSION_CODES.M) + @SuppressWarnings("MissingPermission") + public List query(int type, long thresholdMillis) { if (!PermissionsUtil.hasPermission(mContext, Manifest.permission.READ_CALL_LOG)) { LogUtil.w( "CallLogNotificationsQueryHelper.DefaultNewCallsQuery.query", @@ -328,15 +360,27 @@ public class CallLogNotificationsQueryHelper { // TYPE matches the query type. // IS_READ is not 1. A call might be backed up and restored, so it will be "new" to the // call log, but the user has already read it on another device. - final String selection = - String.format("%s = 1 AND %s = ? AND %s IS NOT 1", Calls.NEW, Calls.TYPE, Calls.IS_READ); - final String[] selectionArgs = new String[] {Integer.toString(type)}; + Selection.Builder selectionBuilder = + Selection.builder() + .and(Selection.column(Calls.NEW).is("= 1")) + .and(Selection.column(Calls.TYPE).is("=", type)) + .and(Selection.column(Calls.IS_READ).is("IS NOT 1")); + if (thresholdMillis != NO_THRESHOLD) { + selectionBuilder = + selectionBuilder.and( + Selection.column(Calls.DATE) + .is("IS NULL") + .buildUpon() + .or(Selection.column(Calls.DATE).is(">=", thresholdMillis)) + .build()); + } + Selection selection = selectionBuilder.build(); try (Cursor cursor = mContentResolver.query( Calls.CONTENT_URI_WITH_VOICEMAIL, (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? PROJECTION_O : PROJECTION, - selection, - selectionArgs, + selection.getSelection(), + selection.getSelectionArgs(), Calls.DEFAULT_SORT_ORDER)) { if (cursor == null) { return null; -- cgit v1.2.3