summaryrefslogtreecommitdiff
path: root/java/com/android/incallui
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-05-10 01:14:47 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-05-10 01:14:47 +0000
commitced93f2d22bffce3b4cfb9c3bfce862b385537dd (patch)
tree2b4715070bcf45b8a8395ee0ae5c7fbb0ef8274c /java/com/android/incallui
parentc49c914e53500fc661ec47e365621c9d33e046ca (diff)
parent2f4a0075e9f546514359eda60a24ac9cd49ea80a (diff)
Merge changes Ia54e3421,Id2176e6e,I0311770e,I79f99c34,I8579afff, ...
* changes: Add some annotations that won't influence aosp. Update answer button logic. Hide new after call spam blocking promo behind an additional flag. Allow the TextView for call log primary text to adjust size when recycled. Format callback phone number. Added getLoggingName() to CallLogDataSource and PhoneLookup interfaces. Do not show bubble for outgoing call if it's not a background call. Always fetch status onResume and add logging for voicemail status in OldMainPeer and Place Duo calls with PreCall Creating CallIntent, AutoValue builder, to replace CallIntentBuilder. Set the DisplayNameSource to PHONE in DefaultLookupUriGenerator. Config correct layout boundaries to accommodate long text (call log & bottom sheet) Use info from EmergencyPhoneLookup to render UI for an emergency number. Implement EmergencyPhoneLookup for checking if a number is an emergency number. Add GlobalSpamListStatus and UserSpamListStatus Move SpamStatus classes into subpackage Delete obsolete checkSpamStatus(Listener) API Update callers of checkSpamStatus to use Future based API Fix bug that showing block option for private number. Add a null check for digitsHint. Don't commit fragment transactions if it's not safe. Add ListenableFuture based APIs for checkSpamStatus Pass activity between new call log's adapter/view holder. Replace assert checks with safety checks instead. Add SimpleSpamStatus and use it in FakeSpam and SpamStub Show calls to/from emergency numbers as "Emergency number" in call log & call details
Diffstat (limited to 'java/com/android/incallui')
-rw-r--r--java/com/android/incallui/AnswerScreenPresenter.java38
-rw-r--r--java/com/android/incallui/NotificationBroadcastReceiver.java47
-rw-r--r--java/com/android/incallui/ReturnToCallController.java3
-rw-r--r--java/com/android/incallui/call/CallList.java90
-rw-r--r--java/com/android/incallui/contactgrid/ContactGridManager.java6
-rw-r--r--java/com/android/incallui/spam/SpamNotificationActivity.java2
-rw-r--r--java/com/android/incallui/spam/SpamNotificationService.java2
-rw-r--r--java/com/android/incallui/speakeasy/SpeakEasyCallManager.java8
-rw-r--r--java/com/android/incallui/speakeasy/SpeakEasyCallManagerStub.java7
-rw-r--r--java/com/android/incallui/videotech/duo/DuoVideoTech.java8
10 files changed, 160 insertions, 51 deletions
diff --git a/java/com/android/incallui/AnswerScreenPresenter.java b/java/com/android/incallui/AnswerScreenPresenter.java
index 0b79e4be7..e41bac606 100644
--- a/java/com/android/incallui/AnswerScreenPresenter.java
+++ b/java/com/android/incallui/AnswerScreenPresenter.java
@@ -24,6 +24,7 @@ import android.support.v4.os.UserManagerCompat;
import android.telecom.VideoProfile;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
@@ -35,6 +36,9 @@ import com.android.incallui.call.CallList;
import com.android.incallui.call.DialerCall;
import com.android.incallui.call.DialerCallListener;
import com.android.incallui.incalluilock.InCallUiLock;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
/** Manages changes for an incoming call screen. */
public class AnswerScreenPresenter
@@ -90,6 +94,39 @@ public class AnswerScreenPresenter
@Override
public void onAnswer(boolean answerVideoAsAudio) {
+
+ DialerCall incomingCall = CallList.getInstance().getIncomingCall();
+ InCallActivity inCallActivity =
+ (InCallActivity) answerScreen.getAnswerScreenFragment().getActivity();
+ ListenableFuture<Void> answerPrecondition;
+
+ if (incomingCall != null && inCallActivity != null) {
+ answerPrecondition = inCallActivity.getSpeakEasyCallManager().onNewIncomingCall(incomingCall);
+ } else {
+ answerPrecondition = Futures.immediateFuture(null);
+ }
+
+ Futures.addCallback(
+ answerPrecondition,
+ new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void result) {
+ onAnswerCallback(answerVideoAsAudio);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ onAnswerCallback(answerVideoAsAudio);
+ // TODO(erfanian): Enumerate all error states and specify recovery strategies.
+ throw new RuntimeException("Failed to successfully complete pre call tasks.", t);
+ }
+ },
+ DialerExecutorComponent.get(context).uiExecutor());
+ addTimeoutCheck();
+ }
+
+ private void onAnswerCallback(boolean answerVideoAsAudio) {
+
if (answerScreen.isVideoUpgradeRequest()) {
if (answerVideoAsAudio) {
Logger.get(context)
@@ -113,7 +150,6 @@ public class AnswerScreenPresenter
call.answer();
}
}
- addTimeoutCheck();
}
@Override
diff --git a/java/com/android/incallui/NotificationBroadcastReceiver.java b/java/com/android/incallui/NotificationBroadcastReceiver.java
index 52d01f5c4..602eb5c5a 100644
--- a/java/com/android/incallui/NotificationBroadcastReceiver.java
+++ b/java/com/android/incallui/NotificationBroadcastReceiver.java
@@ -20,15 +20,21 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
+import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.telecom.CallAudioState;
import android.telecom.VideoProfile;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.incallui.call.CallList;
import com.android.incallui.call.DialerCall;
import com.android.incallui.call.TelecomAdapter;
+import com.android.incallui.speakeasy.SpeakEasyCallManager;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
/**
* Accepts broadcast Intents which will be prepared by {@link StatusBarNotifier} and thus sent from
@@ -72,9 +78,9 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
// TODO: Commands of this nature should exist in the CallList.
if (action.equals(ACTION_ANSWER_VIDEO_INCOMING_CALL)) {
- answerIncomingCall(VideoProfile.STATE_BIDIRECTIONAL);
+ answerIncomingCall(VideoProfile.STATE_BIDIRECTIONAL, context);
} else if (action.equals(ACTION_ANSWER_VOICE_INCOMING_CALL)) {
- answerIncomingCall(VideoProfile.STATE_AUDIO_ONLY);
+ answerIncomingCall(VideoProfile.STATE_AUDIO_ONLY, context);
} else if (action.equals(ACTION_DECLINE_INCOMING_CALL)) {
Logger.get(context)
.logImpression(DialerImpression.Type.REJECT_INCOMING_CALL_FROM_NOTIFICATION);
@@ -140,7 +146,7 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
}
}
- private void answerIncomingCall(int videoState) {
+ private void answerIncomingCall(int videoState, @NonNull Context context) {
CallList callList = InCallPresenter.getInstance().getCallList();
if (callList == null) {
StatusBarNotifier.clearAllCallNotifications();
@@ -148,13 +154,42 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
} else {
DialerCall call = callList.getIncomingCall();
if (call != null) {
- call.answer(videoState);
- InCallPresenter.getInstance()
- .showInCall(false /* showDialpad */, false /* newOutgoingCall */);
+
+ SpeakEasyCallManager speakEasyCallManager =
+ InCallPresenter.getInstance().getSpeakEasyCallManager();
+ ListenableFuture<Void> answerPrecondition;
+
+ if (speakEasyCallManager != null) {
+ answerPrecondition = speakEasyCallManager.onNewIncomingCall(call);
+ } else {
+ answerPrecondition = Futures.immediateFuture(null);
+ }
+
+ Futures.addCallback(
+ answerPrecondition,
+ new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void result) {
+ answerIncomingCallCallback(call, videoState);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ answerIncomingCallCallback(call, videoState);
+ // TODO(erfanian): Enumerate all error states and specify recovery strategies.
+ throw new RuntimeException("Failed to successfully complete pre call tasks.", t);
+ }
+ },
+ DialerExecutorComponent.get(context).uiExecutor());
}
}
}
+ private void answerIncomingCallCallback(@NonNull DialerCall call, int videoState) {
+ call.answer(videoState);
+ InCallPresenter.getInstance().showInCall(false /* showDialpad */, false /* newOutgoingCall */);
+ }
+
private void declineIncomingCall() {
CallList callList = InCallPresenter.getInstance().getCallList();
if (callList == null) {
diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java
index 96bdda1ba..7c4585ca1 100644
--- a/java/com/android/incallui/ReturnToCallController.java
+++ b/java/com/android/incallui/ReturnToCallController.java
@@ -196,12 +196,13 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio
newInCallState != inCallState
&& newInCallState == InCallState.OUTGOING
&& shouldStartInBubbleMode;
+ boolean bubbleNeverVisible = (bubble == null || !(bubble.isVisible() || bubble.isDismissed()));
if (bubble != null && isNewBackgroundCall) {
// If new outgoing call is in bubble mode, update bubble info.
// We don't update if new call is not in bubble mode even if the existing call is.
bubble.setBubbleInfo(generateBubbleInfoForBackgroundCalling());
}
- if ((bubble == null || !(bubble.isVisible() || bubble.isDismissed()) || isNewBackgroundCall)
+ if (((bubbleNeverVisible && newInCallState != InCallState.OUTGOING) || isNewBackgroundCall)
&& getCall() != null
&& !InCallPresenter.getInstance().isShowingInCallUi()) {
LogUtil.i("ReturnToCallController.onCallListChange", "going to show bubble");
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index 5d9db32d9..0e89ac75d 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -32,6 +32,7 @@ import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
import com.android.dialer.blocking.FilteredNumbersUtil;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.enrichedcall.EnrichedCallManager;
import com.android.dialer.logging.DialerImpression;
@@ -41,10 +42,14 @@ import com.android.dialer.metrics.MetricsComponent;
import com.android.dialer.shortcuts.ShortcutUsageReporter;
import com.android.dialer.spam.Spam;
import com.android.dialer.spam.SpamComponent;
+import com.android.dialer.spam.status.SpamStatus;
import com.android.dialer.telecom.TelecomCallUtil;
import com.android.incallui.call.state.DialerCallState;
import com.android.incallui.latencyreport.LatencyReport;
import com.android.incallui.videotech.utils.SessionModificationState;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -146,46 +151,53 @@ public class CallList implements DialerCallDelegate {
LogUtil.d("CallList.onCallAdded", "callState=" + call.getState());
if (SpamComponent.get(context).spamSettings().isSpamEnabled()) {
String number = TelecomCallUtil.getNumber(telecomCall);
- SpamComponent.get(context)
- .spam()
- .checkSpamStatus(
- number,
- call.getCountryIso(),
- new Spam.Listener() {
- @Override
- public void onComplete(boolean isSpam) {
- boolean isIncomingCall =
- call.getState() == DialerCallState.INCOMING
- || call.getState() == DialerCallState.CALL_WAITING;
- if (isSpam) {
- if (!isIncomingCall) {
- LogUtil.i(
- "CallList.onCallAdded",
- "marking spam call as not spam because it's not an incoming call");
- isSpam = false;
- } else if (isPotentialEmergencyCallback(context, call)) {
- LogUtil.i(
- "CallList.onCallAdded",
- "marking spam call as not spam because an emergency call was made on this"
- + " device recently");
- isSpam = false;
- }
- }
-
- if (isIncomingCall) {
- Logger.get(context)
- .logCallImpression(
- isSpam
- ? DialerImpression.Type.INCOMING_SPAM_CALL
- : DialerImpression.Type.INCOMING_NON_SPAM_CALL,
- call.getUniqueCallId(),
- call.getTimeAddedMs());
- }
- call.setSpam(isSpam);
- onUpdateCall(call);
- notifyGenericListeners();
+ ListenableFuture<SpamStatus> futureSpamStatus =
+ SpamComponent.get(context).spam().checkSpamStatus(number, call.getCountryIso());
+
+ Futures.addCallback(
+ futureSpamStatus,
+ new FutureCallback<SpamStatus>() {
+ @Override
+ public void onSuccess(@Nullable SpamStatus result) {
+ boolean isIncomingCall =
+ call.getState() == DialerCallState.INCOMING
+ || call.getState() == DialerCallState.CALL_WAITING;
+ boolean isSpam = result.isSpam();
+ if (isSpam) {
+ if (!isIncomingCall) {
+ LogUtil.i(
+ "CallList.onCallAdded",
+ "marking spam call as not spam because it's not an incoming call");
+ isSpam = false;
+ } else if (isPotentialEmergencyCallback(context, call)) {
+ LogUtil.i(
+ "CallList.onCallAdded",
+ "marking spam call as not spam because an emergency call was made on this"
+ + " device recently");
+ isSpam = false;
}
- });
+ }
+
+ if (isIncomingCall) {
+ Logger.get(context)
+ .logCallImpression(
+ isSpam
+ ? DialerImpression.Type.INCOMING_SPAM_CALL
+ : DialerImpression.Type.INCOMING_NON_SPAM_CALL,
+ call.getUniqueCallId(),
+ call.getTimeAddedMs());
+ }
+ call.setSpam(isSpam);
+ onUpdateCall(call);
+ notifyGenericListeners();
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LogUtil.e("CallList.onFailure", "unable to query spam status", t);
+ }
+ },
+ DialerExecutorComponent.get(context).uiExecutor());
Trace.beginSection("updateUserMarkedSpamStatus");
updateUserMarkedSpamStatus(call, context, number);
diff --git a/java/com/android/incallui/contactgrid/ContactGridManager.java b/java/com/android/incallui/contactgrid/ContactGridManager.java
index d8b1f5004..493f2d583 100644
--- a/java/com/android/incallui/contactgrid/ContactGridManager.java
+++ b/java/com/android/incallui/contactgrid/ContactGridManager.java
@@ -23,6 +23,8 @@ import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.telephony.PhoneNumberUtils;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
@@ -416,7 +418,9 @@ public class ContactGridManager {
// This is used for carriers like Project Fi to show the callback number for emergency calls.
deviceNumberTextView.setText(
context.getString(
- R.string.contact_grid_callback_number, primaryCallState.callbackNumber()));
+ R.string.contact_grid_callback_number,
+ BidiFormatter.getInstance()
+ .unicodeWrap(primaryCallState.callbackNumber(), TextDirectionHeuristics.LTR)));
deviceNumberTextView.setVisibility(View.VISIBLE);
if (primaryInfo.shouldShowLocation()) {
deviceNumberDivider.setVisibility(View.VISIBLE);
diff --git a/java/com/android/incallui/spam/SpamNotificationActivity.java b/java/com/android/incallui/spam/SpamNotificationActivity.java
index e10dea381..2cf486874 100644
--- a/java/com/android/incallui/spam/SpamNotificationActivity.java
+++ b/java/com/android/incallui/spam/SpamNotificationActivity.java
@@ -528,7 +528,7 @@ public class SpamNotificationActivity extends FragmentActivity {
}
private void maybeShowSpamBlockingPromoAndFinish() {
- if (!spamBlockingPromoHelper.shouldShowSpamBlockingPromo()) {
+ if (!spamBlockingPromoHelper.shouldShowAfterCallSpamBlockingPromo()) {
finish();
return;
}
diff --git a/java/com/android/incallui/spam/SpamNotificationService.java b/java/com/android/incallui/spam/SpamNotificationService.java
index b418ea23e..82a943da7 100644
--- a/java/com/android/incallui/spam/SpamNotificationService.java
+++ b/java/com/android/incallui/spam/SpamNotificationService.java
@@ -122,7 +122,7 @@ public class SpamNotificationService extends Service {
ReportingLocation.Type.FEEDBACK_PROMPT,
contactLookupResultType);
new FilteredNumberAsyncQueryHandler(this).blockNumber(null, number, countryIso);
- if (spamBlockingPromoHelper.shouldShowSpamBlockingPromo()) {
+ if (spamBlockingPromoHelper.shouldShowAfterCallSpamBlockingPromo()) {
spamBlockingPromoHelper.showSpamBlockingPromoNotification(
notificationTag,
notificationId,
diff --git a/java/com/android/incallui/speakeasy/SpeakEasyCallManager.java b/java/com/android/incallui/speakeasy/SpeakEasyCallManager.java
index 8a815d385..b060f64cb 100644
--- a/java/com/android/incallui/speakeasy/SpeakEasyCallManager.java
+++ b/java/com/android/incallui/speakeasy/SpeakEasyCallManager.java
@@ -21,6 +21,7 @@ import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import com.android.incallui.call.DialerCall;
import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
/** Provides operations necessary to SpeakEasy. */
public interface SpeakEasyCallManager {
@@ -40,6 +41,13 @@ public interface SpeakEasyCallManager {
void onCallRemoved(@NonNull DialerCall call);
/**
+ * Indicates there is a new incoming call that is about to be answered.
+ *
+ * @param call The call which is about to become active.
+ */
+ ListenableFuture<Void> onNewIncomingCall(@NonNull DialerCall call);
+
+ /**
* Indicates the feature is available.
*
* @param context The application context.
diff --git a/java/com/android/incallui/speakeasy/SpeakEasyCallManagerStub.java b/java/com/android/incallui/speakeasy/SpeakEasyCallManagerStub.java
index a0409737b..da5e88aa3 100644
--- a/java/com/android/incallui/speakeasy/SpeakEasyCallManagerStub.java
+++ b/java/com/android/incallui/speakeasy/SpeakEasyCallManagerStub.java
@@ -22,6 +22,8 @@ import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import com.android.incallui.call.DialerCall;
import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import javax.inject.Inject;
/** Default implementation of SpeakEasyCallManager. */
@@ -41,6 +43,11 @@ public class SpeakEasyCallManagerStub implements SpeakEasyCallManager {
@Override
public void onCallRemoved(DialerCall call) {}
+ @Override
+ public ListenableFuture<Void> onNewIncomingCall(@NonNull DialerCall call) {
+ return Futures.immediateFuture(null);
+ }
+
/** Always returns false. */
@Override
public boolean isAvailable(@NonNull Context unused) {
diff --git a/java/com/android/incallui/videotech/duo/DuoVideoTech.java b/java/com/android/incallui/videotech/duo/DuoVideoTech.java
index fdaed077b..ac74e54df 100644
--- a/java/com/android/incallui/videotech/duo/DuoVideoTech.java
+++ b/java/com/android/incallui/videotech/duo/DuoVideoTech.java
@@ -23,6 +23,7 @@ import android.telecom.Call;
import android.telecom.PhoneAccountHandle;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DefaultFutureCallback;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.duo.Duo;
import com.android.dialer.duo.DuoListener;
@@ -33,6 +34,8 @@ import com.android.incallui.videotech.VideoTech;
import com.android.incallui.videotech.utils.SessionModificationState;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
public class DuoVideoTech implements VideoTech, DuoListener {
private final Duo duo;
@@ -77,7 +80,10 @@ public class DuoVideoTech implements VideoTech, DuoListener {
if (!isRemoteUpgradeAvailabilityQueried) {
LogUtil.v("DuoVideoTech.isAvailable", "reachability unknown, starting remote query");
isRemoteUpgradeAvailabilityQueried = true;
- duo.updateReachability(context, ImmutableList.of(callingNumber));
+ Futures.addCallback(
+ duo.updateReachability(context, ImmutableList.of(callingNumber)),
+ new DefaultFutureCallback<>(),
+ MoreExecutors.directExecutor());
}
return false;