From 0839b1eccc8e373e01d96cc97f079b1ce44b5d33 Mon Sep 17 00:00:00 2001 From: Sarmad Hashmi Date: Sat, 9 Apr 2016 22:18:12 -0700 Subject: Add after call notification code in InCallUI. +Add asynchronous call to update inCallHistory boolean variable which specifies whether the number is in the call history (has previously called before) +Add CallHistoryStatus enum and variable to Call object to determine if the number is present in the call history +Added SpamCallListListener object which listens for changes in the CallList +Update the CallHistoryStatus for the call whenever an incoming call comes in +Added 11 tests for new listener BUG=27323295 Change-Id: I242cd4a53b3aeca69fbce972221a2c941d9d37ce --- InCallUI/src/com/android/incallui/Call.java | 45 ++++++-- .../src/com/android/incallui/InCallPresenter.java | 7 ++ .../incallui/spam/SpamCallListListener.java | 117 +++++++++++++++++++++ 3 files changed, 159 insertions(+), 10 deletions(-) create mode 100644 InCallUI/src/com/android/incallui/spam/SpamCallListListener.java (limited to 'InCallUI/src') diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java index a27efec76..252c7016d 100644 --- a/InCallUI/src/com/android/incallui/Call.java +++ b/InCallUI/src/com/android/incallui/Call.java @@ -21,6 +21,7 @@ import android.hardware.camera2.CameraCharacteristics; import android.net.Uri; import android.os.Bundle; import android.os.Trace; +import android.support.annotation.IntDef; import android.telecom.Call.Details; import android.telecom.Connection; import android.telecom.DisconnectCause; @@ -41,6 +42,8 @@ import com.android.contacts.common.testing.NeededForTesting; import com.android.dialer.util.IntentUtil; import com.android.incallui.util.TelecomCallUtil; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -51,6 +54,19 @@ import java.util.Objects; */ @NeededForTesting public class Call { + + /** + * Specifies whether a number is in the call history or not. + * {@link #CALL_HISTORY_STATUS_UNKNOWN} means there is no result. + */ + @IntDef({CALL_HISTORY_STATUS_UNKNOWN, CALL_HISTORY_STATUS_PRESENT, + CALL_HISTORY_STATUS_NOT_PRESENT}) + @Retention(RetentionPolicy.SOURCE) + public @interface CallHistoryStatus {} + public static final int CALL_HISTORY_STATUS_UNKNOWN = 0; + public static final int CALL_HISTORY_STATUS_PRESENT = 1; + public static final int CALL_HISTORY_STATUS_NOT_PRESENT = 2; + /* Defines different states of this call */ public static class State { public static final int INVALID = 0; @@ -381,6 +397,8 @@ public class Call { private String mLastForwardedNumber; private String mCallSubject; private PhoneAccountHandle mPhoneAccountHandle; + @CallHistoryStatus private int mCallHistoryStatus = CALL_HISTORY_STATUS_UNKNOWN; + private boolean mIsSpam; /** * Indicates whether the phone account associated with this call supports specifying a call @@ -392,16 +410,6 @@ public class Call { private LogState mLogState = new LogState(); - private boolean mIsSpam; - - public void setSpam(boolean isSpam) { - mIsSpam = isSpam; - } - - public boolean isSpam() { - return mIsSpam; - } - /** * Used only to create mock calls for testing */ @@ -987,4 +995,21 @@ public class Call { public String toSimpleString() { return super.toString(); } + + public void setCallHistoryStatus(@CallHistoryStatus int callHistoryStatus) { + mCallHistoryStatus = callHistoryStatus; + } + + @CallHistoryStatus + public int getCallHistoryStatus() { + return mCallHistoryStatus; + } + + public void setSpam(boolean isSpam) { + mIsSpam = isSpam; + } + + public boolean isSpam() { + return mIsSpam; + } } diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java index 189049c47..4442cbcd2 100644 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ b/InCallUI/src/com/android/incallui/InCallPresenter.java @@ -56,6 +56,7 @@ import com.android.dialer.filterednumber.FilteredNumbersUtil; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; import com.android.dialer.util.TelecomUtil; +import com.android.incallui.spam.SpamCallListListener; import com.android.incallui.util.TelecomCallUtil; import com.android.incalluibind.ObjectFactory; @@ -123,6 +124,7 @@ public class InCallPresenter implements CallList.Listener, private InCallCameraManager mInCallCameraManager = null; private AnswerPresenter mAnswerPresenter = new AnswerPresenter(); private FilteredNumberAsyncQueryHandler mFilteredQueryHandler; + private CallList.Listener mSpamCallListListener; /** * Whether or not we are currently bound and waiting for Telecom to send us a new call. @@ -345,6 +347,10 @@ public class InCallPresenter implements CallList.Listener, // will kick off an update and the whole process can start. mCallList.addListener(this); + // Create spam call list listener and add it to the list of listeners + mSpamCallListListener = new SpamCallListListener(context); + mCallList.addListener(mSpamCallListListener); + VideoPauseController.getInstance().setUp(this); InCallVideoCallCallbackNotifier.getInstance().addSessionModificationListener(this); @@ -1532,6 +1538,7 @@ public class InCallPresenter implements CallList.Listener, if (mCallList != null) { mCallList.removeListener(this); + mCallList.removeListener(mSpamCallListListener); } mCallList = null; diff --git a/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java b/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java new file mode 100644 index 000000000..b97f4d099 --- /dev/null +++ b/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.incallui.spam; + +import com.google.common.annotations.VisibleForTesting; + +import android.content.Context; +import android.telecom.DisconnectCause; +import android.text.TextUtils; + +import com.android.dialer.calllog.CallLogAsyncTaskUtil; +import com.android.incallui.Call; +import com.android.incallui.CallList; +import com.android.incallui.Log; + +public class SpamCallListListener implements CallList.Listener { + private static final String TAG = "SpamCallListListener"; + + private final Context mContext; + + public SpamCallListListener(Context context) { + mContext = context; + } + + @Override + public void onIncomingCall(final Call call) { + String number = call.getNumber(); + if (TextUtils.isEmpty(number)) { + return; + } + CallLogAsyncTaskUtil.getNumberInCallHistory(mContext, number, + new CallLogAsyncTaskUtil.OnGetNumberInCallHistoryListener() { + @Override + public void onComplete(boolean inCallHistory) { + call.setCallHistoryStatus(inCallHistory ? + Call.CALL_HISTORY_STATUS_PRESENT + : Call.CALL_HISTORY_STATUS_NOT_PRESENT); + } + }); + } + + @Override + public void onUpgradeToVideo(Call call) {} + + @Override + public void onCallListChange(CallList callList) {} + + @Override + public void onDisconnect(Call call) { + if (shouldShowAfterCallNotification(call)) { + showNotification(call.getNumber()); + } + } + + /** + * Posts the intent for displaying the after call spam notification to the user. + */ + @VisibleForTesting + /* package */ void showNotification(String number) { + //TODO(mhashmi): build and show notifications here + } + + /** + * Determines if the after call notification should be shown for the specified call. + */ + private boolean shouldShowAfterCallNotification(Call call) { + String number = call.getNumber(); + if (TextUtils.isEmpty(number)) { + return false; + } + + Call.LogState logState = call.getLogState(); + if (!logState.isIncoming) { + return false; + } + + if (logState.duration <= 0) { + return false; + } + + if (logState.contactLookupResult != Call.LogState.LOOKUP_NOT_FOUND + && logState.contactLookupResult != Call.LogState.LOOKUP_UNKNOWN) { + return false; + } + + int callHistoryStatus = call.getCallHistoryStatus(); + if (callHistoryStatus == Call.CALL_HISTORY_STATUS_PRESENT) { + return false; + } else if (callHistoryStatus == Call.CALL_HISTORY_STATUS_UNKNOWN) { + Log.i(TAG, "Call history status is unknown, returning false"); + return false; + } + + // Check if call disconnected because of either user hanging up + int disconnectCause = call.getDisconnectCause().getCode(); + if (disconnectCause != DisconnectCause.LOCAL && disconnectCause != DisconnectCause.REMOTE) { + return false; + } + + Log.i(TAG, "shouldShowAfterCallNotification, returning true"); + return true; + } +} \ No newline at end of file -- cgit v1.2.3