Merge "Added support for writing Calls.FEATURES_WIFI and Calls.FEATURES_HD_CALL to the Call Log."
diff --git a/proto/telecom.proto b/proto/telecom.proto
index 2f4fae8..73eba87 100644
--- a/proto/telecom.proto
+++ b/proto/telecom.proto
@@ -16,6 +16,9 @@
// Hardware revision (EVT, DVT, PVT etc.)
optional string hardware_revision = 3;
+
+ // Carrier ID that the device is associated to
+ optional int32 carrier_id = 4;
}
message LogSessionTiming {
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 1d3a90e..2997454 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -16,6 +16,7 @@
package com.android.server.telecom;
+import android.content.Context;
import android.os.SystemProperties;
import android.telecom.Connection;
@@ -23,6 +24,8 @@
import android.telecom.Logging.EventManager;
import android.telecom.ParcelableCallAnalytics;
import android.telecom.TelecomAnalytics;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.util.Base64;
import android.telecom.Log;
@@ -37,10 +40,12 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.PriorityQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;
@@ -628,7 +633,7 @@
return new TelecomAnalytics(sessionTimings, calls);
}
- public static void dumpToEncodedProto(PrintWriter pw, String[] args) {
+ public static void dumpToEncodedProto(Context context, PrintWriter pw, String[] args) {
TelecomLogClass.TelecomLog result = new TelecomLogClass.TelecomLog();
synchronized (sLock) {
@@ -642,6 +647,7 @@
.setTimeMillis(timing.getTime()))
.toArray(TelecomLogClass.LogSessionTiming[]::new);
result.setHardwareRevision(SystemProperties.get("ro.boot.revision", ""));
+ result.setCarrierId(getCarrierId(context));
if (args.length > 1 && CLEAR_ANALYTICS_ARG.equals(args[1])) {
sCallIdToInfo.clear();
sSessionTimings.clear();
@@ -652,6 +658,29 @@
pw.write(encodedProto);
}
+ private static int getCarrierId(Context context) {
+ SubscriptionManager subscriptionManager =
+ context.getSystemService(SubscriptionManager.class);
+ List<SubscriptionInfo> subInfos = subscriptionManager.getActiveSubscriptionInfoList();
+ if (subInfos == null) {
+ return -1;
+ }
+ return subInfos.stream()
+ .max(Comparator.comparing(Analytics::scoreSubscriptionInfo))
+ .map(SubscriptionInfo::getCarrierId).orElse(-1);
+ }
+
+ // Copied over from Telephony's server-side logic for consistency
+ private static int scoreSubscriptionInfo(SubscriptionInfo subInfo) {
+ final int scoreCarrierId = 0b100;
+ final int scoreNotOpportunistic = 0b010;
+ final int scoreSlot0 = 0b001;
+
+ return ((subInfo.getCarrierId() >= 0) ? scoreCarrierId : 0)
+ + (subInfo.isOpportunistic() ? 0 : scoreNotOpportunistic)
+ + ((subInfo.getSimSlotIndex() == 0) ? scoreSlot0 : 0);
+ }
+
public static void dump(IndentingPrintWriter writer) {
synchronized (sLock) {
int prefixLength = CallsManager.TELECOM_CALL_ID_PREFIX.length();
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index e73d623..b507758 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -47,6 +47,8 @@
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;
import android.util.StatsLog;
import android.os.UserHandle;
@@ -62,11 +64,13 @@
import java.lang.String;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -336,6 +340,10 @@
private boolean mIsEmergencyCall;
+ // The Call is considered an emergency call for testing, but will not actually connect to
+ // emergency services.
+ private boolean mIsTestEmergencyCall;
+
private boolean mSpeakerphoneOn;
private boolean mIsDisconnectingChildCall = false;
@@ -1073,10 +1081,13 @@
// call, it will remain so for the rest of it's lifetime.
if (!mIsEmergencyCall) {
mIsEmergencyCall = mHandle != null &&
- mPhoneNumberUtilsAdapter.isLocalEmergencyNumber(mContext,
- mHandle.getSchemeSpecificPart());
+ getTelephonyManager().isEmergencyNumber(mHandle.getSchemeSpecificPart());
mAnalytics.setCallIsEmergency(mIsEmergencyCall);
}
+ if (!mIsTestEmergencyCall) {
+ mIsTestEmergencyCall = mHandle != null &&
+ isTestEmergencyCall(mHandle.getSchemeSpecificPart());
+ }
startCallerInfoLookup();
for (Listener l : mListeners) {
l.onHandleChanged(this);
@@ -1084,6 +1095,14 @@
}
}
+ private boolean isTestEmergencyCall(String number) {
+ Map<Integer, List<EmergencyNumber>> eMap = getTelephonyManager().getEmergencyNumberList();
+ return eMap.values().stream().flatMap(Collection::stream)
+ .anyMatch(eNumber ->
+ eNumber.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST) &&
+ number.equals(eNumber.getNumber()));
+ }
+
public String getCallerDisplayName() {
return mCallerDisplayName;
}
@@ -1144,6 +1163,15 @@
}
/**
+ * @return {@code true} if this an outgoing call to a test emergency number (and NOT to
+ * emergency services). Used for testing purposes to differentiate between a real and fake
+ * emergency call for safety reasons during testing.
+ */
+ public boolean isTestEmergencyCall() {
+ return mIsTestEmergencyCall;
+ }
+
+ /**
* @return {@code true} if the network has identified this call as an emergency call.
*/
public boolean isNetworkIdentifiedEmergencyCall() {
@@ -3163,6 +3191,10 @@
}
}
+ private TelephonyManager getTelephonyManager() {
+ return mContext.getSystemService(TelephonyManager.class);
+ }
+
/**
* Sets whether this {@link Call} is a conference or not.
* @param isConference
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 7e4c3ba..c01c9aa 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -26,6 +26,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
import java.util.Collection;
@@ -44,6 +45,7 @@
private final LinkedHashSet<Call> mActiveDialingOrConnectingCalls;
private final LinkedHashSet<Call> mRingingCalls;
private final LinkedHashSet<Call> mHoldingCalls;
+ private final LinkedHashSet<Call> mAudioProcessingCalls;
private final Set<Call> mCalls;
private final SparseArray<LinkedHashSet<Call>> mCallStateToCalls;
@@ -69,9 +71,10 @@
RingbackPlayer ringbackPlayer,
BluetoothStateReceiver bluetoothStateReceiver,
DtmfLocalTonePlayer dtmfLocalTonePlayer) {
- mActiveDialingOrConnectingCalls = new LinkedHashSet<>();
- mRingingCalls = new LinkedHashSet<>();
- mHoldingCalls = new LinkedHashSet<>();
+ mActiveDialingOrConnectingCalls = new LinkedHashSet<>(1);
+ mRingingCalls = new LinkedHashSet<>(1);
+ mHoldingCalls = new LinkedHashSet<>(1);
+ mAudioProcessingCalls = new LinkedHashSet<>(1);
mCalls = new HashSet<>();
mCallStateToCalls = new SparseArray<LinkedHashSet<Call>>() {{
put(CallState.CONNECTING, mActiveDialingOrConnectingCalls);
@@ -80,6 +83,8 @@
put(CallState.PULLING, mActiveDialingOrConnectingCalls);
put(CallState.RINGING, mRingingCalls);
put(CallState.ON_HOLD, mHoldingCalls);
+ put(CallState.SIMULATED_RINGING, mRingingCalls);
+ put(CallState.AUDIO_PROCESSING, mAudioProcessingCalls);
}};
mCallAudioRouteStateMachine = callAudioRouteStateMachine;
@@ -511,6 +516,13 @@
pw.increaseIndent();
mCallAudioRouteStateMachine.dumpPendingMessages(pw);
pw.decreaseIndent();
+
+ pw.println("BluetoothDeviceManager:");
+ pw.increaseIndent();
+ if (mBluetoothStateReceiver.getBluetoothDeviceManager() != null) {
+ mBluetoothStateReceiver.getBluetoothDeviceManager().dump(pw);
+ }
+ pw.decreaseIndent();
}
@VisibleForTesting
@@ -534,6 +546,7 @@
onCallLeavingActiveDialingOrConnecting();
break;
case CallState.RINGING:
+ case CallState.SIMULATED_RINGING:
case CallState.ANSWERED:
onCallLeavingRinging();
break;
@@ -547,6 +560,9 @@
stopRingbackForCall(call);
onCallLeavingActiveDialingOrConnecting();
break;
+ case CallState.AUDIO_PROCESSING:
+ onCallLeavingAudioProcessing();
+ break;
}
}
@@ -557,6 +573,7 @@
onCallEnteringActiveDialingOrConnecting();
break;
case CallState.RINGING:
+ case CallState.SIMULATED_RINGING:
onCallEnteringRinging();
break;
case CallState.ON_HOLD:
@@ -574,6 +591,25 @@
onCallEnteringActiveDialingOrConnecting();
}
break;
+ case CallState.AUDIO_PROCESSING:
+ onCallEnteringAudioProcessing();
+ break;
+ }
+ }
+
+ private void onCallLeavingAudioProcessing() {
+ if (mAudioProcessingCalls.size() == 0) {
+ mCallAudioModeStateMachine.sendMessageWithArgs(
+ CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS,
+ makeArgsForModeStateMachine());
+ }
+ }
+
+ private void onCallEnteringAudioProcessing() {
+ if (mAudioProcessingCalls.size() == 1) {
+ mCallAudioModeStateMachine.sendMessageWithArgs(
+ CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL,
+ makeArgsForModeStateMachine());
}
}
@@ -655,13 +691,15 @@
@NonNull
private CallAudioModeStateMachine.MessageArgs makeArgsForModeStateMachine() {
- return new CallAudioModeStateMachine.MessageArgs(
- mActiveDialingOrConnectingCalls.size() > 0,
- mRingingCalls.size() > 0,
- mHoldingCalls.size() > 0,
- mIsTonePlaying,
- mForegroundCall != null && mForegroundCall.getIsVoipAudioMode(),
- Log.createSubsession());
+ return new Builder()
+ .setHasActiveOrDialingCalls(mActiveDialingOrConnectingCalls.size() > 0)
+ .setHasRingingCalls(mRingingCalls.size() > 0)
+ .setHasHoldingCalls(mHoldingCalls.size() > 0)
+ .setHasAudioProcessingCalls(mAudioProcessingCalls.size() > 0)
+ .setIsTonePlaying(mIsTonePlaying)
+ .setForegroundCallIsVoip(
+ mForegroundCall != null && mForegroundCall.getIsVoipAudioMode())
+ .setSession(Log.createSubsession()).build();
}
private HashSet<Call> getBinForCall(Call call) {
diff --git a/src/com/android/server/telecom/CallAudioModeStateMachine.java b/src/com/android/server/telecom/CallAudioModeStateMachine.java
index e5c4617..06be216 100644
--- a/src/com/android/server/telecom/CallAudioModeStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioModeStateMachine.java
@@ -41,53 +41,108 @@
public boolean hasActiveOrDialingCalls;
public boolean hasRingingCalls;
public boolean hasHoldingCalls;
+ public boolean hasAudioProcessingCalls;
public boolean isTonePlaying;
public boolean foregroundCallIsVoip;
public Session session;
- public MessageArgs(boolean hasActiveOrDialingCalls, boolean hasRingingCalls,
- boolean hasHoldingCalls, boolean isTonePlaying, boolean foregroundCallIsVoip,
- Session session) {
+ private MessageArgs(boolean hasActiveOrDialingCalls, boolean hasRingingCalls,
+ boolean hasHoldingCalls, boolean hasAudioProcessingCalls, boolean isTonePlaying,
+ boolean foregroundCallIsVoip, Session session) {
this.hasActiveOrDialingCalls = hasActiveOrDialingCalls;
this.hasRingingCalls = hasRingingCalls;
this.hasHoldingCalls = hasHoldingCalls;
+ this.hasAudioProcessingCalls = hasAudioProcessingCalls;
this.isTonePlaying = isTonePlaying;
this.foregroundCallIsVoip = foregroundCallIsVoip;
this.session = session;
}
- public MessageArgs() {
- this.session = Log.createSubsession();
- }
-
@Override
public String toString() {
return "MessageArgs{" +
"hasActiveCalls=" + hasActiveOrDialingCalls +
", hasRingingCalls=" + hasRingingCalls +
", hasHoldingCalls=" + hasHoldingCalls +
+ ", hasAudioProcessingCalls=" + hasAudioProcessingCalls +
", isTonePlaying=" + isTonePlaying +
", foregroundCallIsVoip=" + foregroundCallIsVoip +
", session=" + session +
'}';
}
+
+ public static class Builder {
+ private boolean mHasActiveOrDialingCalls;
+ private boolean mHasRingingCalls;
+ private boolean mHasHoldingCalls;
+ private boolean mHasAudioProcessingCalls;
+ private boolean mIsTonePlaying;
+ private boolean mForegroundCallIsVoip;
+ private Session mSession;
+
+ public Builder setHasActiveOrDialingCalls(boolean hasActiveOrDialingCalls) {
+ mHasActiveOrDialingCalls = hasActiveOrDialingCalls;
+ return this;
+ }
+
+ public Builder setHasRingingCalls(boolean hasRingingCalls) {
+ mHasRingingCalls = hasRingingCalls;
+ return this;
+ }
+
+ public Builder setHasHoldingCalls(boolean hasHoldingCalls) {
+ mHasHoldingCalls = hasHoldingCalls;
+ return this;
+ }
+
+ public Builder setHasAudioProcessingCalls(boolean hasAudioProcessingCalls) {
+ mHasAudioProcessingCalls = hasAudioProcessingCalls;
+ return this;
+ }
+
+ public Builder setIsTonePlaying(boolean isTonePlaying) {
+ mIsTonePlaying = isTonePlaying;
+ return this;
+ }
+
+ public Builder setForegroundCallIsVoip(boolean foregroundCallIsVoip) {
+ mForegroundCallIsVoip = foregroundCallIsVoip;
+ return this;
+ }
+
+ public Builder setSession(Session session) {
+ mSession = session;
+ return this;
+ }
+
+ public MessageArgs build() {
+ return new MessageArgs(mHasActiveOrDialingCalls, mHasRingingCalls, mHasHoldingCalls,
+ mHasAudioProcessingCalls, mIsTonePlaying, mForegroundCallIsVoip, mSession);
+ }
+ }
}
+ // TODO: remove this and replace when the new audio mode gets checked in.
+ public static final int NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING = AudioManager.MODE_NORMAL;
+
public static final int INITIALIZE = 1;
// These ENTER_*_FOCUS commands are for testing.
public static final int ENTER_CALL_FOCUS_FOR_TESTING = 2;
public static final int ENTER_COMMS_FOCUS_FOR_TESTING = 3;
public static final int ENTER_RING_FOCUS_FOR_TESTING = 4;
public static final int ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING = 5;
- public static final int ABANDON_FOCUS_FOR_TESTING = 6;
+ public static final int ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING = 6;
+ public static final int ABANDON_FOCUS_FOR_TESTING = 7;
public static final int NO_MORE_ACTIVE_OR_DIALING_CALLS = 1001;
public static final int NO_MORE_RINGING_CALLS = 1002;
public static final int NO_MORE_HOLDING_CALLS = 1003;
+ public static final int NO_MORE_AUDIO_PROCESSING_CALLS = 1004;
public static final int NEW_ACTIVE_OR_DIALING_CALL = 2001;
public static final int NEW_RINGING_CALL = 2002;
public static final int NEW_HOLDING_CALL = 2003;
+ public static final int NEW_AUDIO_PROCESSING_CALL = 2004;
public static final int TONE_STARTED_PLAYING = 3001;
public static final int TONE_STOPPED_PLAYING = 3002;
@@ -102,14 +157,17 @@
put(ENTER_CALL_FOCUS_FOR_TESTING, "ENTER_CALL_FOCUS_FOR_TESTING");
put(ENTER_COMMS_FOCUS_FOR_TESTING, "ENTER_COMMS_FOCUS_FOR_TESTING");
put(ENTER_RING_FOCUS_FOR_TESTING, "ENTER_RING_FOCUS_FOR_TESTING");
+ put(ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING, "ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING");
put(ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, "ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING");
put(ABANDON_FOCUS_FOR_TESTING, "ABANDON_FOCUS_FOR_TESTING");
put(NO_MORE_ACTIVE_OR_DIALING_CALLS, "NO_MORE_ACTIVE_OR_DIALING_CALLS");
put(NO_MORE_RINGING_CALLS, "NO_MORE_RINGING_CALLS");
put(NO_MORE_HOLDING_CALLS, "NO_MORE_HOLDING_CALLS");
+ put(NO_MORE_AUDIO_PROCESSING_CALLS, "NO_MORE_AUDIO_PROCESSING_CALLS");
put(NEW_ACTIVE_OR_DIALING_CALL, "NEW_ACTIVE_OR_DIALING_CALL");
put(NEW_RINGING_CALL, "NEW_RINGING_CALL");
put(NEW_HOLDING_CALL, "NEW_HOLDING_CALL");
+ put(NEW_AUDIO_PROCESSING_CALL, "NEW_AUDIO_PROCESSING_CALL");
put(TONE_STARTED_PLAYING, "TONE_STARTED_PLAYING");
put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING");
put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE");
@@ -120,6 +178,8 @@
public static final String TONE_HOLD_STATE_NAME = OtherFocusState.class.getSimpleName();
public static final String UNFOCUSED_STATE_NAME = UnfocusedState.class.getSimpleName();
+ public static final String AUDIO_PROCESSING_STATE_NAME =
+ AudioProcessingFocusState.class.getSimpleName();
public static final String CALL_STATE_NAME = SimCallFocusState.class.getSimpleName();
public static final String RING_STATE_NAME = RingingFocusState.class.getSimpleName();
public static final String COMMS_STATE_NAME = VoipCallFocusState.class.getSimpleName();
@@ -140,6 +200,9 @@
case ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING:
transitionTo(mOtherFocusState);
return HANDLED;
+ case ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING:
+ transitionTo(mAudioProcessingFocusState);
+ return HANDLED;
case ABANDON_FOCUS_FOR_TESTING:
transitionTo(mUnfocusedState);
return HANDLED;
@@ -161,8 +224,8 @@
public void enter() {
if (mIsInitialized) {
Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED");
- mAudioManager.abandonAudioFocusForCall();
mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mAudioManager.abandonAudioFocusForCall();
mMostRecentMode = AudioManager.MODE_NORMAL;
mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS);
@@ -185,6 +248,73 @@
case NO_MORE_HOLDING_CALLS:
// Do nothing.
return HANDLED;
+ case NO_MORE_AUDIO_PROCESSING_CALLS:
+ // Do nothing.
+ return HANDLED;
+ case NEW_ACTIVE_OR_DIALING_CALL:
+ transitionTo(args.foregroundCallIsVoip
+ ? mVoipCallFocusState : mSimCallFocusState);
+ return HANDLED;
+ case NEW_RINGING_CALL:
+ transitionTo(mRingingFocusState);
+ return HANDLED;
+ case NEW_AUDIO_PROCESSING_CALL:
+ transitionTo(mAudioProcessingFocusState);
+ return HANDLED;
+ case NEW_HOLDING_CALL:
+ // This really shouldn't happen, but transition to the focused state anyway.
+ Log.w(LOG_TAG, "Call was surprisingly put into hold from an unknown state." +
+ " Args are: \n" + args.toString());
+ transitionTo(mOtherFocusState);
+ return HANDLED;
+ case TONE_STARTED_PLAYING:
+ // This shouldn't happen either, but perform the action anyway.
+ Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n"
+ + args.toString());
+ return HANDLED;
+ default:
+ // The forced focus switch commands are handled by BaseState.
+ return NOT_HANDLED;
+ }
+ }
+ }
+
+ private class AudioProcessingFocusState extends BaseState {
+ @Override
+ public void enter() {
+ if (mIsInitialized) {
+ Log.i(LOG_TAG, "Abandoning audio focus: now audio processing");
+ mAudioManager.setMode(NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING);
+ mAudioManager.abandonAudioFocusForCall();
+
+ mMostRecentMode = NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING;
+ mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS);
+ }
+ }
+
+ @Override
+ public boolean processMessage(Message msg) {
+ if (super.processMessage(msg) == HANDLED) {
+ return HANDLED;
+ }
+ MessageArgs args = (MessageArgs) msg.obj;
+ switch (msg.what) {
+ case NO_MORE_ACTIVE_OR_DIALING_CALLS:
+ // Do nothing.
+ return HANDLED;
+ case NO_MORE_RINGING_CALLS:
+ // Do nothing.
+ return HANDLED;
+ case NO_MORE_HOLDING_CALLS:
+ // Do nothing.
+ return HANDLED;
+ case NO_MORE_AUDIO_PROCESSING_CALLS:
+ BaseState destState = calculateProperStateFromArgs(args);
+ if (destState == this) {
+ Log.w(LOG_TAG, "Got spurious NO_MORE_AUDIO_PROCESSING_CALLS");
+ }
+ transitionTo(destState);
+ return HANDLED;
case NEW_ACTIVE_OR_DIALING_CALL:
transitionTo(args.foregroundCallIsVoip
? mVoipCallFocusState : mSimCallFocusState);
@@ -193,11 +323,15 @@
transitionTo(mRingingFocusState);
return HANDLED;
case NEW_HOLDING_CALL:
- // This really shouldn't happen, but transition to the focused state anyway.
+ // This really shouldn't happen, but recalculate from args and do the transition
Log.w(LOG_TAG, "Call was surprisingly put into hold from an unknown state." +
" Args are: \n" + args.toString());
transitionTo(mOtherFocusState);
return HANDLED;
+ case NEW_AUDIO_PROCESSING_CALL:
+ Log.w(LOG_TAG, "Unexpected behavior! New audio processing call appeared while"
+ + " in audio processing state.");
+ return HANDLED;
case TONE_STARTED_PLAYING:
// This shouldn't happen either, but perform the action anyway.
Log.w(LOG_TAG, "Tone started playing unexpectedly. Args are: \n"
@@ -250,25 +384,25 @@
// Do nothing and keep ringing.
return HANDLED;
case NO_MORE_RINGING_CALLS:
- // If there are active or holding calls, switch to the appropriate focus.
- // Otherwise abandon focus.
- if (args.hasActiveOrDialingCalls) {
- if (args.foregroundCallIsVoip) {
- transitionTo(mVoipCallFocusState);
- } else {
- transitionTo(mSimCallFocusState);
- }
- } else if (args.hasHoldingCalls || args.isTonePlaying) {
- transitionTo(mOtherFocusState);
- } else {
- transitionTo(mUnfocusedState);
+ BaseState destState = calculateProperStateFromArgs(args);
+ if (destState == this) {
+ Log.w(LOG_TAG, "Got spurious NO_MORE_RINGING_CALLS");
}
+ transitionTo(destState);
return HANDLED;
case NEW_ACTIVE_OR_DIALING_CALL:
// If a call becomes active suddenly, give it priority over ringing.
transitionTo(args.foregroundCallIsVoip
? mVoipCallFocusState : mSimCallFocusState);
return HANDLED;
+ case NEW_AUDIO_PROCESSING_CALL:
+ // If we don't have any more ringing calls, transition to audio processing.
+ if (!args.hasRingingCalls) {
+ transitionTo(mAudioProcessingFocusState);
+ } else {
+ Log.w(LOG_TAG, "Got a audio processing call while there's still a call "
+ + "ringing");
+ }
case NEW_RINGING_CALL:
Log.w(LOG_TAG, "Unexpected behavior! New ringing call appeared while in " +
"ringing state.");
@@ -311,7 +445,7 @@
switch (msg.what) {
case NO_MORE_ACTIVE_OR_DIALING_CALLS:
// Switch to either ringing, holding, or inactive
- transitionTo(destinationStateAfterNoMoreActiveCalls(args));
+ transitionTo(calculateProperStateFromArgs(args));
return HANDLED;
case NO_MORE_RINGING_CALLS:
// Don't transition state, but stop any call-waiting tones that may have been
@@ -324,7 +458,7 @@
// indicating that a ringing call has disconnected while this state machine
// is in the SimCallFocusState.
if (!args.hasActiveOrDialingCalls) {
- transitionTo(destinationStateAfterNoMoreActiveCalls(args));
+ transitionTo(calculateProperStateFromArgs(args));
}
return HANDLED;
case NO_MORE_HOLDING_CALLS:
@@ -348,6 +482,14 @@
transitionTo(mVoipCallFocusState);
}
return HANDLED;
+ case NEW_AUDIO_PROCESSING_CALL:
+ // If we don't have any more active calls, transition to audio processing.
+ if (!args.hasActiveOrDialingCalls) {
+ transitionTo(mAudioProcessingFocusState);
+ } else {
+ Log.w(LOG_TAG, "Got a audio processing call while there's still a call "
+ + "active");
+ }
case FOREGROUND_VOIP_MODE_CHANGE:
if (args.foregroundCallIsVoip) {
transitionTo(mVoipCallFocusState);
@@ -380,7 +522,7 @@
switch (msg.what) {
case NO_MORE_ACTIVE_OR_DIALING_CALLS:
// Switch to either ringing, holding, or inactive
- transitionTo(destinationStateAfterNoMoreActiveCalls(args));
+ transitionTo(calculateProperStateFromArgs(args));
return HANDLED;
case NO_MORE_RINGING_CALLS:
// Don't transition state, but stop any call-waiting tones that may have been
@@ -410,6 +552,14 @@
transitionTo(mSimCallFocusState);
}
return HANDLED;
+ case NEW_AUDIO_PROCESSING_CALL:
+ // If we don't have any more active calls, transition to audio processing.
+ if (!args.hasActiveOrDialingCalls) {
+ transitionTo(mAudioProcessingFocusState);
+ } else {
+ Log.w(LOG_TAG, "Got a audio processing call while there's still a call "
+ + "active");
+ }
case FOREGROUND_VOIP_MODE_CHANGE:
if (!args.foregroundCallIsVoip) {
transitionTo(mSimCallFocusState);
@@ -476,7 +626,7 @@
mCallAudioManager.stopCallWaiting();
return HANDLED;
case TONE_STOPPED_PLAYING:
- transitionTo(destinationStateAfterNoMoreActiveCalls(args));
+ transitionTo(calculateProperStateFromArgs(args));
default:
return NOT_HANDLED;
}
@@ -489,6 +639,7 @@
private final BaseState mRingingFocusState = new RingingFocusState();
private final BaseState mSimCallFocusState = new SimCallFocusState();
private final BaseState mVoipCallFocusState = new VoipCallFocusState();
+ private final BaseState mAudioProcessingFocusState = new AudioProcessingFocusState();
private final BaseState mOtherFocusState = new OtherFocusState();
private final AudioManager mAudioManager;
@@ -526,10 +677,18 @@
addState(mRingingFocusState);
addState(mSimCallFocusState);
addState(mVoipCallFocusState);
+ addState(mAudioProcessingFocusState);
addState(mOtherFocusState);
setInitialState(mUnfocusedState);
start();
- sendMessage(INITIALIZE, new MessageArgs());
+ sendMessage(INITIALIZE, new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(Log.createSubsession())
+ .build());
}
public void setCallAudioManager(CallAudioManager callAudioManager) {
@@ -569,15 +728,32 @@
Log.endSession();
}
- private BaseState destinationStateAfterNoMoreActiveCalls(MessageArgs args) {
- if (args.hasHoldingCalls) {
+ private BaseState calculateProperStateFromArgs(MessageArgs args) {
+ // If there are active, audio-processing, holding, or ringing calls,
+ // switch to the appropriate focus.
+ // Otherwise abandon focus.
+
+ // The order matters here. If there are active calls, holding focus for them takes priority.
+ // After that, we want to prioritize holding calls over ringing calls so that when a
+ // call-waiting call gets answered, there's no transition in and out of the ringing focus
+ // state. After that, we want tones since we actually hold focus during them, then the
+ // audio processing state because that will release focus.
+ if (args.hasActiveOrDialingCalls) {
+ if (args.foregroundCallIsVoip) {
+ return mVoipCallFocusState;
+ } else {
+ return mSimCallFocusState;
+ }
+ } else if (args.hasHoldingCalls) {
return mOtherFocusState;
} else if (args.hasRingingCalls) {
return mRingingFocusState;
} else if (args.isTonePlaying) {
return mOtherFocusState;
- } else {
- return mUnfocusedState;
+ } else if (args.hasAudioProcessingCalls) {
+ return mAudioProcessingFocusState;
}
+ return mUnfocusedState;
}
+
}
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 4afa645..aea60df 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -38,11 +38,16 @@
}
public static class AdapterImpl implements Adapter {
+ private final DefaultDialerCache mDefaultDialerCache;
+ public AdapterImpl(DefaultDialerCache cache) {
+ mDefaultDialerCache = cache;
+ }
+
@Override
public void processOutgoingCallIntent(Context context, CallsManager callsManager,
Intent intent, String callingPackage) {
CallIntentProcessor.processOutgoingCallIntent(context, callsManager, intent,
- callingPackage);
+ callingPackage, mDefaultDialerCache);
}
@Override
@@ -58,11 +63,6 @@
public static final String KEY_IS_UNKNOWN_CALL = "is_unknown_call";
public static final String KEY_IS_INCOMING_CALL = "is_incoming_call";
- /*
- * Whether or not the dialer initiating this outgoing call is the default dialer, or system
- * dialer and thus allowed to make emergency calls.
- */
- public static final String KEY_IS_PRIVILEGED_DIALER = "is_privileged_dialer";
/**
* The user initiating the outgoing call.
@@ -72,10 +72,13 @@
private final Context mContext;
private final CallsManager mCallsManager;
+ private final DefaultDialerCache mDefaultDialerCache;
- public CallIntentProcessor(Context context, CallsManager callsManager) {
+ public CallIntentProcessor(Context context, CallsManager callsManager,
+ DefaultDialerCache defaultDialerCache) {
this.mContext = context;
this.mCallsManager = callsManager;
+ this.mDefaultDialerCache = defaultDialerCache;
}
public void processIntent(Intent intent, String callingPackage) {
@@ -86,7 +89,8 @@
if (isUnknownCall) {
processUnknownCallIntent(mCallsManager, intent);
} else {
- processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage);
+ processOutgoingCallIntent(mContext, mCallsManager, intent, callingPackage,
+ mDefaultDialerCache);
}
Trace.endSection();
}
@@ -102,7 +106,8 @@
Context context,
CallsManager callsManager,
Intent intent,
- String callingPackage) {
+ String callingPackage,
+ DefaultDialerCache defaultDialerCache) {
Uri handle = intent.getData();
String scheme = handle.getScheme();
@@ -157,6 +162,9 @@
UserHandle initiatingUser = intent.getParcelableExtra(KEY_INITIATING_USER);
+ boolean isPrivilegedDialer = defaultDialerCache.isDefaultOrSystemDialer(callingPackage,
+ initiatingUser.getIdentifier());
+
// Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
CompletableFuture<Call> callFuture = callsManager
.startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser,
@@ -167,7 +175,8 @@
if (call != null) {
Log.continueSession(logSubsession, "CIP.sNOCI");
try {
- sendNewOutgoingCallIntent(context, call, callsManager, intent);
+ sendNewOutgoingCallIntent(context, call, callsManager, intent,
+ isPrivilegedDialer, defaultDialerCache);
} finally {
Log.endSession();
}
@@ -176,17 +185,15 @@
}
static void sendNewOutgoingCallIntent(Context context, Call call, CallsManager callsManager,
- Intent intent) {
+ Intent intent, boolean isPrivilegedDialer, DefaultDialerCache defaultDialerCache) {
// Asynchronous calls should not usually be made inside a BroadcastReceiver because once
// onReceive is complete, the BroadcastReceiver's process runs the risk of getting
// killed if memory is scarce. However, this is OK here because the entire Telecom
// process will be running throughout the duration of the phone call and should never
// be killed.
- final boolean isPrivilegedDialer = intent.getBooleanExtra(KEY_IS_PRIVILEGED_DIALER, false);
-
NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
context, callsManager, call, intent, callsManager.getPhoneNumberUtilsAdapter(),
- isPrivilegedDialer);
+ isPrivilegedDialer, defaultDialerCache);
// If the broadcaster comes back with an immediate error, disconnect and show a dialog.
NewOutgoingCallIntentBroadcaster.CallDisposition disposition = broadcaster.evaluateCall();
diff --git a/src/com/android/server/telecom/CallScreeningServiceHelper.java b/src/com/android/server/telecom/CallScreeningServiceHelper.java
index a9341ab..79d5286 100644
--- a/src/com/android/server/telecom/CallScreeningServiceHelper.java
+++ b/src/com/android/server/telecom/CallScreeningServiceHelper.java
@@ -68,6 +68,11 @@
}
@Override
+ public void screenCallFurther(String callId) throws RemoteException {
+ // no-op; we don't allow this on outgoing calls.
+ }
+
+ @Override
public void disallowCall(String s, boolean b, boolean b1, boolean b2,
ComponentName componentName) throws RemoteException {
// no-op; we don't allow this on outgoing calls.
diff --git a/src/com/android/server/telecom/CallState.java b/src/com/android/server/telecom/CallState.java
index 1e31732..0411ecc 100644
--- a/src/com/android/server/telecom/CallState.java
+++ b/src/com/android/server/telecom/CallState.java
@@ -118,7 +118,19 @@
* Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
* set the call to active.
*/
- public static final int ANSWERED = 11;
+ public static final int ANSWERED = TelecomProtoEnums.ANSWERED; // = 11
+
+ /**
+ * Indicates that the call is undergoing audio processing by a different app in the background.
+ * @see android.telecom.Call#STATE_AUDIO_PROCESSING
+ */
+ public static final int AUDIO_PROCESSING = TelecomProtoEnums.AUDIO_PROCESSING; // = 12
+
+ /**
+ * Indicates that the call is in a fake ringing state.
+ * @see android.telecom.Call#STATE_SIMULATED_RINGING
+ */
+ public static final int SIMULATED_RINGING = TelecomProtoEnums.SIMULATED_RINGING; // = 13
public static String toString(int callState) {
switch (callState) {
@@ -146,6 +158,10 @@
return "PULLING";
case ANSWERED:
return "ANSWERED";
+ case AUDIO_PROCESSING:
+ return "AUDIO_PROCESSING";
+ case SIMULATED_RINGING:
+ return "SIMULATED_RINGING";
default:
return "UNKNOWN";
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 36ff803..ca673ad 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -35,6 +35,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -78,6 +79,7 @@
import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceController;
import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
import com.android.server.telecom.callfiltering.IncomingCallFilter;
@@ -608,7 +610,12 @@
incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE),
incomingCall.isSelfManaged(),
extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING));
- onCallFilteringComplete(incomingCall, new CallFilteringResult(true, false, true, true));
+ onCallFilteringComplete(incomingCall, new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build());
incomingCall.setIsUsingCallFiltering(false);
return;
}
@@ -1103,9 +1110,11 @@
call.setIsVoipAudioMode(true);
}
}
- if (isRttSettingOn() ||
+
+ boolean isRttSettingOn = isRttSettingOn(phoneAccountHandle);
+ if (isRttSettingOn ||
extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, false)) {
- Log.i(this, "Incoming call requesting RTT, rtt setting is %b", isRttSettingOn());
+ Log.i(this, "Incoming call requesting RTT, rtt setting is %b", isRttSettingOn);
call.createRttStreams();
// Even if the phone account doesn't support RTT yet, the connection manager might
// change that. Set this to check it later.
@@ -1536,11 +1545,12 @@
boolean isVoicemail = isVoicemail(callToUse.getHandle(), accountToUse);
- if (!isVoicemail && (isRttSettingOn() || (extras != null
+ boolean isRttSettingOn = isRttSettingOn(phoneAccountHandle);
+ if (!isVoicemail && (isRttSettingOn || (extras != null
&& extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT,
false)))) {
Log.d(this, "Outgoing call requesting RTT, rtt setting is %b",
- isRttSettingOn());
+ isRttSettingOn);
if (callToUse.isEmergencyCall() || (accountToUse != null
&& accountToUse.hasCapabilities(PhoneAccount.CAPABILITY_RTT))) {
// If the call requested RTT and it's an emergency call, ignore the
@@ -1623,6 +1633,7 @@
* @param handle The handle of the outgoing call; used to determine the SIP scheme when matching
* phone accounts.
* @param isVideo {@code true} if the call is a video call, {@code false} otherwise.
+ * @param isEmergency {@code true} if the call is an emergency call.
* @param initiatingUser The {@link UserHandle} the call is placed on.
* @return
*/
@@ -1753,7 +1764,7 @@
Log.w(this, "onCallRedirectionComplete: phoneAccountHandle is null");
endEarly = true;
disconnectReason = "Null phoneAccountHandle from Call Redirection Service";
- } else if (mPhoneNumberUtilsAdapter.isPotentialLocalEmergencyNumber(mContext,
+ } else if (getTelephonyManager().isPotentialEmergencyNumber(
handle.getSchemeSpecificPart())) {
Log.w(this, "onCallRedirectionComplete: emergency number %s is redirected from Call"
+ " Redirection Service", handle.getSchemeSpecificPart());
@@ -2225,10 +2236,8 @@
isEmergency ? 0 : PhoneAccount.CAPABILITY_EMERGENCY_CALLS_ONLY);
// First check the Radio SIM Technology
if(mRadioSimVariants == null) {
- TelephonyManager tm = (TelephonyManager) mContext.getSystemService(
- Context.TELEPHONY_SERVICE);
// Cache Sim Variants
- mRadioSimVariants = tm.getMultiSimConfiguration();
+ mRadioSimVariants = getTelephonyManager().getMultiSimConfiguration();
}
// Only one SIM PhoneAccount can be active at one time for DSDS. Only that SIM PhoneAccount
// Should be available if a call is already active on the SIM account.
@@ -2252,6 +2261,10 @@
return allAccounts;
}
+ private TelephonyManager getTelephonyManager() {
+ return mContext.getSystemService(TelephonyManager.class);
+ }
+
/**
* Informs listeners (notably {@link CallAudioManager} of a change to the call's external
* property.
@@ -2320,9 +2333,22 @@
mProximitySensorManager.turnOff(screenOnImmediately);
}
- private boolean isRttSettingOn() {
- return Settings.Secure.getInt(mContext.getContentResolver(),
+ private boolean isRttSettingOn(PhoneAccountHandle handle) {
+ boolean isRttModeSettingOn = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.RTT_CALLING_MODE, 0) != 0;
+ // If the carrier config says that we should ignore the RTT mode setting from the user,
+ // assume that it's off (i.e. only make an RTT call if it's requested through the extra).
+ boolean shouldIgnoreRttModeSetting = getCarrierConfigForPhoneAccount(handle)
+ .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL, false);
+ return isRttModeSettingOn && !shouldIgnoreRttModeSetting;
+ }
+
+ private PersistableBundle getCarrierConfigForPhoneAccount(PhoneAccountHandle handle) {
+ int subscriptionId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(handle);
+ CarrierConfigManager carrierConfigManager =
+ mContext.getSystemService(CarrierConfigManager.class);
+ PersistableBundle result = carrierConfigManager.getConfigForSubId(subscriptionId);
+ return result == null ? new PersistableBundle() : result;
}
void phoneAccountSelected(Call call, PhoneAccountHandle account, boolean setDefault) {
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 4621558..911cf0f 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -1743,8 +1743,12 @@
}
ConnectionServiceWrapper service = mConnectionServiceRepository.getService(
handle.getComponentName(), handle.getUserHandle());
- if (service != null) {
+ if (service != null && service != this) {
simServices.add(service);
+ } else {
+ // This is unexpected, normally PhoneAccounts with CAPABILITY_CALL_PROVIDER are not
+ // also CAPABILITY_CONNECTION_MANAGER
+ Log.w(this, "call provider also detected as SIM call manager: " + service);
}
}
@@ -1761,11 +1765,6 @@
Log.i(this, "queryRemoteConnectionServices, simServices = %s", simServices);
for (ConnectionServiceWrapper simService : simServices) {
- if (simService == this) {
- // Only happens in the unlikely case that a SIM service is also a SIM call manager
- continue;
- }
-
final ConnectionServiceWrapper currentSimService = simService;
currentSimService.mBinder.bind(new BindCallback() {
diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java
index 6c92724..84e97d9 100644
--- a/src/com/android/server/telecom/CreateConnectionProcessor.java
+++ b/src/com/android/server/telecom/CreateConnectionProcessor.java
@@ -383,6 +383,12 @@
allAccounts.add(TelephonyUtil.getDefaultEmergencyPhoneAccount());
}
+ // When testing emergency calls, we want the calls to go through to the test connection
+ // service, not the telephony ConnectionService.
+ if (mCall.isTestEmergencyCall()) {
+ allAccounts = mPhoneAccountRegistrar.filterRestrictedPhoneAccounts(allAccounts);
+ }
+
// Get user preferred PA if it exists.
PhoneAccount preferredPA = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
preferredPAH);
diff --git a/src/com/android/server/telecom/DefaultDialerCache.java b/src/com/android/server/telecom/DefaultDialerCache.java
index b72d860..c2b78ee 100644
--- a/src/com/android/server/telecom/DefaultDialerCache.java
+++ b/src/com/android/server/telecom/DefaultDialerCache.java
@@ -18,9 +18,11 @@
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
@@ -134,9 +136,10 @@
private final Context mContext;
private final DefaultDialerManagerAdapter mDefaultDialerManagerAdapter;
private final TelecomSystem.SyncRoot mLock;
- private final String mSystemDialerName;
+ private final ComponentName mSystemDialerComponentName;
private final RoleManagerAdapter mRoleManagerAdapter;
private SparseArray<String> mCurrentDefaultDialerPerUser = new SparseArray<>();
+ private ComponentName mOverrideSystemDialerComponentName;
public DefaultDialerCache(Context context,
DefaultDialerManagerAdapter defaultDialerManagerAdapter,
@@ -146,7 +149,11 @@
mDefaultDialerManagerAdapter = defaultDialerManagerAdapter;
mRoleManagerAdapter = roleManagerAdapter;
mLock = lock;
- mSystemDialerName = TelecomServiceImpl.getSystemDialerPackage(mContext);
+ Resources resources = mContext.getResources();
+ mSystemDialerComponentName = new ComponentName(resources.getString(
+ com.android.internal.R.string.config_defaultDialer),
+ resources.getString(R.string.incall_default_class));
+
IntentFilter packageIntentFilter = new IntentFilter();
packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
@@ -194,6 +201,22 @@
return getDefaultDialerApplication(mContext.getUserId());
}
+ public void setSystemDialerComponentName(ComponentName testComponentName) {
+ mOverrideSystemDialerComponentName = testComponentName;
+ }
+
+ public String getSystemDialerApplication() {
+ if (mOverrideSystemDialerComponentName != null) {
+ return mOverrideSystemDialerComponentName.getPackageName();
+ }
+ return mSystemDialerComponentName.getPackageName();
+ }
+
+ public ComponentName getSystemDialerComponent() {
+ if (mOverrideSystemDialerComponentName != null) return mOverrideSystemDialerComponentName;
+ return mSystemDialerComponentName;
+ }
+
public void observeDefaultDialerApplication(Executor executor, IntConsumer observer) {
mRoleManagerAdapter.observeDefaultDialerApp(executor, observer);
}
@@ -201,7 +224,7 @@
public boolean isDefaultOrSystemDialer(String packageName, int userId) {
String defaultDialer = getDefaultDialerApplication(userId);
return Objects.equals(packageName, defaultDialer)
- || Objects.equals(packageName, mSystemDialerName);
+ || Objects.equals(packageName, getSystemDialerApplication());
}
public boolean setDefaultDialer(String packageName, int userId) {
diff --git a/src/com/android/server/telecom/EmergencyCallHelper.java b/src/com/android/server/telecom/EmergencyCallHelper.java
index 7052597..5de4e5a 100644
--- a/src/com/android/server/telecom/EmergencyCallHelper.java
+++ b/src/com/android/server/telecom/EmergencyCallHelper.java
@@ -25,13 +25,13 @@
/**
* Helps with emergency calls by:
- * 1. granting temporary location permission to the default dialer service during emergency calls
+ * 1. granting temporary location permission to the system dialer service during emergency calls
* 2. keeping track of the time of the last emergency call
*/
@VisibleForTesting
public class EmergencyCallHelper {
private final Context mContext;
- private final String mDefaultDialerPackage;
+ private final DefaultDialerCache mDefaultDialerCache;
private final Timeouts.Adapter mTimeoutsAdapter;
private UserHandle mLocationPermissionGrantedToUser;
private boolean mHadFineLocation = false;
@@ -41,10 +41,10 @@
@VisibleForTesting
public EmergencyCallHelper(
Context context,
- String defaultDialerPackage,
+ DefaultDialerCache defaultDialerCache,
Timeouts.Adapter timeoutsAdapter) {
mContext = context;
- mDefaultDialerPackage = defaultDialerPackage;
+ mDefaultDialerCache = defaultDialerCache;
mTimeoutsAdapter = timeoutsAdapter;
}
@@ -94,48 +94,50 @@
}
private void grantLocationPermission(UserHandle userHandle) {
- Log.i(this, "Granting temporary location permission to " + mDefaultDialerPackage
+ String systemDialerPackage = mDefaultDialerCache.getSystemDialerApplication();
+ Log.i(this, "Granting temporary location permission to " + systemDialerPackage
+ ", user: " + userHandle);
try {
boolean hadBackgroundLocation = hasBackgroundLocationPermission();
boolean hadFineLocation = hasFineLocationPermission();
if (hadBackgroundLocation && hadFineLocation) {
- Log.i(this, "Skipping location grant because the default dialer already"
+ Log.i(this, "Skipping location grant because the system dialer already"
+ " holds sufficient permissions");
return;
}
if (!hadFineLocation) {
- mContext.getPackageManager().grantRuntimePermission(mDefaultDialerPackage,
+ mContext.getPackageManager().grantRuntimePermission(systemDialerPackage,
Manifest.permission.ACCESS_FINE_LOCATION, userHandle);
}
if (!hadBackgroundLocation) {
- mContext.getPackageManager().grantRuntimePermission(mDefaultDialerPackage,
+ mContext.getPackageManager().grantRuntimePermission(systemDialerPackage,
Manifest.permission.ACCESS_BACKGROUND_LOCATION, userHandle);
}
mHadFineLocation = hadFineLocation;
mHadBackgroundLocation = hadBackgroundLocation;
recordPermissionGrant(userHandle);
} catch (Exception e) {
- Log.e(this, e, "Failed to grant location permissions to " + mDefaultDialerPackage
+ Log.e(this, e, "Failed to grant location permissions to " + systemDialerPackage
+ ", user: " + userHandle);
}
}
private void revokeLocationPermission() {
- Log.i(this, "Revoking temporary location permission from " + mDefaultDialerPackage
+ String systemDialerPackage = mDefaultDialerCache.getSystemDialerApplication();
+ Log.i(this, "Revoking temporary location permission from " + systemDialerPackage
+ ", user: " + mLocationPermissionGrantedToUser);
UserHandle userHandle = mLocationPermissionGrantedToUser;
try {
if (!mHadFineLocation) {
- mContext.getPackageManager().revokeRuntimePermission(mDefaultDialerPackage,
+ mContext.getPackageManager().revokeRuntimePermission(systemDialerPackage,
Manifest.permission.ACCESS_FINE_LOCATION, userHandle);
}
if (!mHadBackgroundLocation) {
- mContext.getPackageManager().revokeRuntimePermission(mDefaultDialerPackage,
+ mContext.getPackageManager().revokeRuntimePermission(systemDialerPackage,
Manifest.permission.ACCESS_BACKGROUND_LOCATION, userHandle);
}
} catch (Exception e) {
- Log.e(this, e, "Failed to revoke location permission from " + mDefaultDialerPackage
+ Log.e(this, e, "Failed to revoke location permission from " + systemDialerPackage
+ ", user: " + userHandle);
}
clearPermissionGrant();
@@ -143,13 +145,15 @@
private boolean hasBackgroundLocationPermission() {
return mContext.getPackageManager().checkPermission(
- Manifest.permission.ACCESS_BACKGROUND_LOCATION, mDefaultDialerPackage)
+ Manifest.permission.ACCESS_BACKGROUND_LOCATION,
+ mDefaultDialerCache.getSystemDialerApplication())
== PackageManager.PERMISSION_GRANTED;
}
private boolean hasFineLocationPermission() {
return mContext.getPackageManager().checkPermission(
- Manifest.permission.ACCESS_FINE_LOCATION, mDefaultDialerPackage)
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ mDefaultDialerCache.getSystemDialerApplication())
== PackageManager.PERMISSION_GRANTED;
}
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index 8de27be..888010d 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -19,6 +19,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.RemoteException;
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
@@ -319,6 +320,16 @@
}
@Override
+ public void enterBackgroundAudioProcessing(String callId) {
+ // TODO: implement this
+ }
+
+ @Override
+ public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) {
+ // TODO: implement this
+ }
+
+ @Override
public void conference(String callId, String otherCallId) {
try {
Log.startSession(LogUtils.Sessions.ICA_CONFERENCE, mOwnerComponentName);
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index d562c7e..c4df1d3 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -721,9 +721,6 @@
private final CallIdMapper mCallIdMapper = new CallIdMapper(Call::getId);
- /** The {@link ComponentName} of the default InCall UI. */
- private final ComponentName mSystemInCallComponentName;
-
private final Context mContext;
private final TelecomSystem.SyncRoot mLock;
private final CallsManager mCallsManager;
@@ -751,11 +748,6 @@
mDefaultDialerCache = defaultDialerCache;
mEmergencyCallHelper = emergencyCallHelper;
- Resources resources = mContext.getResources();
- mSystemInCallComponentName = new ComponentName(
- TelecomServiceImpl.getSystemDialerPackage(mContext),
- resources.getString(R.string.incall_default_class));
-
mSystemStateHelper.addListener(mSystemStateListener);
}
@@ -1106,13 +1098,13 @@
Log.i(this, "defaultDialer: " + defaultDialerComponentInfo);
if (defaultDialerComponentInfo != null &&
!defaultDialerComponentInfo.getComponentName().equals(
- mSystemInCallComponentName)) {
+ mDefaultDialerCache.getSystemDialerComponent())) {
dialerInCall = new InCallServiceBindingConnection(defaultDialerComponentInfo);
}
Log.i(this, "defaultDialer: " + dialerInCall);
InCallServiceInfo systemInCallInfo = getInCallServiceComponent(
- mSystemInCallComponentName, IN_CALL_SERVICE_TYPE_SYSTEM_UI);
+ mDefaultDialerCache.getSystemDialerComponent(), IN_CALL_SERVICE_TYPE_SYSTEM_UI);
EmergencyInCallServiceConnection systemInCall =
new EmergencyInCallServiceConnection(systemInCallInfo, dialerInCall);
systemInCall.setHasEmergency(mCallsManager.hasEmergencyCall());
@@ -1120,7 +1112,8 @@
InCallServiceConnection carModeInCall = null;
InCallServiceInfo carModeComponentInfo = getCarModeComponent();
if (carModeComponentInfo != null &&
- !carModeComponentInfo.getComponentName().equals(mSystemInCallComponentName)) {
+ !carModeComponentInfo.getComponentName().equals(
+ mDefaultDialerCache.getSystemDialerComponent())) {
carModeInCall = new InCallServiceBindingConnection(carModeComponentInfo);
}
@@ -1280,8 +1273,9 @@
return IN_CALL_SERVICE_TYPE_INVALID;
}
- if (mSystemInCallComponentName.getPackageName().equals(serviceInfo.packageName) &&
- mSystemInCallComponentName.getClassName().equals(serviceInfo.name)) {
+ if (mDefaultDialerCache.getSystemDialerApplication().equals(serviceInfo.packageName) &&
+ mDefaultDialerCache.getSystemDialerComponent().getClassName()
+ .equals(serviceInfo.name)) {
return IN_CALL_SERVICE_TYPE_SYSTEM_UI;
}
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index 1e82fc0..f55fa2c 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -137,6 +137,7 @@
public static final String BIND_SCREENING = "BIND_SCREENING";
public static final String SCREENING_BOUND = "SCREENING_BOUND";
public static final String SCREENING_SENT = "SCREENING_SENT";
+ public static final String SCREENING_SKIPPED = "SCREENING_SKIPPED";
public static final String CONTROLLER_SCREENING_COMPLETED =
"CONTROLLER_SCREENING_COMPLETED";
public static final String SCREENING_COMPLETED = "SCREENING_COMPLETED";
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 7a641af..1abd6fb 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -35,6 +35,7 @@
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.DisconnectCause;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -76,6 +77,7 @@
private final Context mContext;
private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
private final TelecomSystem.SyncRoot mLock;
+ private final DefaultDialerCache mDefaultDialerCache;
/*
* Whether or not the outgoing call intent originated from the default phone application. If
@@ -99,7 +101,7 @@
@VisibleForTesting
public NewOutgoingCallIntentBroadcaster(Context context, CallsManager callsManager, Call call,
Intent intent, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
- boolean isDefaultPhoneApp) {
+ boolean isDefaultPhoneApp, DefaultDialerCache defaultDialerCache) {
mContext = context;
mCallsManager = callsManager;
mCall = call;
@@ -107,6 +109,7 @@
mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
mIsDefaultOrSystemPhoneApp = isDefaultPhoneApp;
mLock = mCallsManager.getLock();
+ mDefaultDialerCache = defaultDialerCache;
}
/**
@@ -137,8 +140,7 @@
disconnectTimeout = getDisconnectTimeoutFromApp(
getResultExtras(false), disconnectTimeout);
endEarly = true;
- } else if (mPhoneNumberUtilsAdapter.isPotentialLocalEmergencyNumber(
- mContext, resultNumber)) {
+ } else if (isPotentialEmergencyNumber(resultNumber)) {
Log.w(this, "Cannot modify outgoing call to emergency number %s.",
resultNumber);
disconnectTimeout = 0;
@@ -492,10 +494,7 @@
private void launchSystemDialer(Uri handle) {
Intent systemDialerIntent = new Intent();
- final Resources resources = mContext.getResources();
- systemDialerIntent.setClassName(
- TelecomServiceImpl.getSystemDialerPackage(mContext),
- resources.getString(R.string.dialer_default_class));
+ systemDialerIntent.setComponent(mDefaultDialerCache.getSystemDialerComponent());
systemDialerIntent.setAction(Intent.ACTION_DIAL);
systemDialerIntent.setData(handle);
systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -519,8 +518,8 @@
*/
private boolean isPotentialEmergencyNumber(String number) {
Log.v(this, "Checking restrictions for number : %s", Log.pii(number));
- return (number != null)
- && mPhoneNumberUtilsAdapter.isPotentialLocalEmergencyNumber(mContext, number);
+ if (number == null) return false;
+ return mContext.getSystemService(TelephonyManager.class).isPotentialEmergencyNumber(number);
}
/**
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 8746de1..8776ffd 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -154,6 +154,7 @@
private final AppLabelProxy mAppLabelProxy;
private State mState;
private UserHandle mCurrentUserHandle;
+ private String mTestPhoneAccountPackageNameFilter;
private interface PhoneAccountRegistrarWriteLock {}
private final PhoneAccountRegistrarWriteLock mWriteLock =
new PhoneAccountRegistrarWriteLock() {};
@@ -458,6 +459,34 @@
}
/**
+ * Sets a filter for which {@link PhoneAccount}s will be returned from
+ * {@link #filterRestrictedPhoneAccounts(List)}. If non-null, only {@link PhoneAccount}s
+ * with the package name packageNameFilter will be returned. If null, no filter is set.
+ * @param packageNameFilter The package name that will be used to filter only
+ * {@link PhoneAccount}s with the same package name.
+ */
+ public void setTestPhoneAccountPackageNameFilter(String packageNameFilter) {
+ mTestPhoneAccountPackageNameFilter = packageNameFilter;
+ Log.i(this, "filter set for PhoneAccounts, packageName=" + packageNameFilter);
+ }
+
+ /**
+ * Filter the given {@link List<PhoneAccount>} and keep only {@link PhoneAccount}s that have the
+ * #mTestPhoneAccountPackageNameFilter.
+ * @param accounts List of {@link PhoneAccount}s to filter.
+ * @return new list of filtered {@link PhoneAccount}s.
+ */
+ public List<PhoneAccount> filterRestrictedPhoneAccounts(List<PhoneAccount> accounts) {
+ if (TextUtils.isEmpty(mTestPhoneAccountPackageNameFilter)) {
+ return new ArrayList<>(accounts);
+ }
+ // Remove all PhoneAccounts that do not have the same package name as the filter.
+ return accounts.stream().filter(account -> mTestPhoneAccountPackageNameFilter.equals(
+ account.getAccountHandle().getComponentName().getPackageName()))
+ .collect(Collectors.toList());
+ }
+
+ /**
* If it is a outgoing call, sim call manager associated with the target phone account of the
* call is returned (if one exists).
* Otherwise, we return the sim call manager of the user associated with the
@@ -1202,6 +1231,9 @@
pw.println(phoneAccount);
}
pw.decreaseIndent();
+ pw.increaseIndent();
+ pw.println("test emergency PhoneAccount filter: " + mTestPhoneAccountPackageNameFilter);
+ pw.decreaseIndent();
}
}
diff --git a/src/com/android/server/telecom/PhoneNumberUtilsAdapter.java b/src/com/android/server/telecom/PhoneNumberUtilsAdapter.java
index aa568a9..28d832d 100644
--- a/src/com/android/server/telecom/PhoneNumberUtilsAdapter.java
+++ b/src/com/android/server/telecom/PhoneNumberUtilsAdapter.java
@@ -24,8 +24,6 @@
* refactoring.
*/
public interface PhoneNumberUtilsAdapter {
- boolean isLocalEmergencyNumber(Context context, String number);
- boolean isPotentialLocalEmergencyNumber(Context context, String number);
boolean isUriNumber(String number);
boolean isSamePhoneNumber(String number1, String number2);
String getNumberFromIntent(Intent intent, Context context);
diff --git a/src/com/android/server/telecom/PhoneNumberUtilsAdapterImpl.java b/src/com/android/server/telecom/PhoneNumberUtilsAdapterImpl.java
index 8b3c856..517857b 100644
--- a/src/com/android/server/telecom/PhoneNumberUtilsAdapterImpl.java
+++ b/src/com/android/server/telecom/PhoneNumberUtilsAdapterImpl.java
@@ -23,20 +23,6 @@
public class PhoneNumberUtilsAdapterImpl implements PhoneNumberUtilsAdapter {
@Override
- public boolean isLocalEmergencyNumber(Context context, String number) {
- TelephonyManager tm = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- return tm.isEmergencyNumber(number);
- }
-
- @Override
- public boolean isPotentialLocalEmergencyNumber(Context context, String number) {
- TelephonyManager tm = (TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE);
- return tm.isPotentialEmergencyNumber(number);
- }
-
- @Override
public boolean isUriNumber(String number) {
return PhoneNumberUtils.isUriNumber(number);
}
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index 93f6908..2469c1e 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -374,12 +374,12 @@
&& mSystemSettingsUtil.enableRampingRingerFromDeviceConfig()
&& isRingerAudible) {
Log.i(this, "start vibration for ramping ringer.");
- mVibrator.vibrate(effect, VIBRATION_ATTRIBUTES);
mIsVibrating = true;
+ mVibrator.vibrate(effect, VIBRATION_ATTRIBUTES);
} else {
Log.i(this, "start normal vibration.");
- mVibrator.vibrate(effect, VIBRATION_ATTRIBUTES);
mIsVibrating = true;
+ mVibrator.vibrate(effect, VIBRATION_ATTRIBUTES);
}
} else if (mIsVibrating) {
Log.addEvent(foregroundCall, LogUtils.Events.SKIP_VIBRATION, "already vibrating");
diff --git a/src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java b/src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java
index ca44cd4..8d2a2c5 100644
--- a/src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java
+++ b/src/com/android/server/telecom/TelecomBroadcastIntentProcessor.java
@@ -18,12 +18,17 @@
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.UserHandle;
import android.telecom.Log;
+import android.widget.Toast;
import com.android.server.telecom.ui.CallRedirectionConfirmDialogActivity;
import com.android.server.telecom.ui.ConfirmCallDialogActivity;
+import java.util.List;
+
public final class TelecomBroadcastIntentProcessor {
/** The action used to send SMS response for the missed call notification. */
public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
@@ -119,7 +124,15 @@
Intent callIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(callIntent, userHandle);
+ PackageManager packageManager = mContext.getPackageManager();
+ List<ResolveInfo> activities = packageManager.queryIntentActivitiesAsUser(
+ callIntent, PackageManager.MATCH_DEFAULT_ONLY, userHandle.getIdentifier());
+ if (activities.size() > 0) {
+ mContext.startActivityAsUser(callIntent, userHandle);
+ } else {
+ Toast.makeText(mContext, com.android.internal.R.string.noApplications,
+ Toast.LENGTH_SHORT).show();
+ }
// Call back recent caller from the missed call notification.
} else if (ACTION_CALL_BACK_FROM_NOTIFICATION.equals(action)) {
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 61aecfe..f82215f 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -34,7 +34,6 @@
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -679,11 +678,7 @@
public ComponentName getDefaultPhoneApp() {
try {
Log.startSession("TSI.gDPA");
- // No need to synchronize
- Resources resources = mContext.getResources();
- return new ComponentName(
- TelecomServiceImpl.getSystemDialerPackage(mContext),
- resources.getString(R.string.dialer_default_class));
+ return mDefaultDialerCache.getSystemDialerComponent();
} finally {
Log.endSession();
}
@@ -718,7 +713,25 @@
public String getSystemDialerPackage() {
try {
Log.startSession("TSI.gSDP");
- return TelecomServiceImpl.getSystemDialerPackage(mContext);
+ return mDefaultDialerCache.getSystemDialerApplication();
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ public void setSystemDialer(ComponentName testComponentName) {
+ try {
+ Log.startSession("TSI.sSD");
+ enforceModifyPermission();
+ enforceShellOnly(Binder.getCallingUid(), "setSystemDialer");
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mDefaultDialerCache.setSystemDialerComponentName(testComponentName);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
} finally {
Log.endSession();
}
@@ -1379,10 +1392,13 @@
return;
}
+
if (args.length > 0 && Analytics.ANALYTICS_DUMPSYS_ARG.equals(args[0])) {
- Analytics.dumpToEncodedProto(writer, args);
+ Binder.withCleanCallingIdentity(() ->
+ Analytics.dumpToEncodedProto(mContext, writer, args));
return;
}
+
boolean isTimeLineView = (args.length > 0 && TIME_LINE_ARG.equalsIgnoreCase(args[0]));
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -1483,6 +1499,26 @@
}
}
+ @Override
+ public void setTestEmergencyPhoneAccountPackageNameFilter(String packageName) {
+ try {
+ Log.startSession("TSI.sTPAPNF");
+ enforceModifyPermission();
+ enforceShellOnly(Binder.getCallingUid(),
+ "setTestEmergencyPhoneAccountPackageNameFilter");
+ synchronized (mLock) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mPhoneAccountRegistrar.setTestPhoneAccountPackageNameFilter(packageName);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
+
/**
* See {@link TelecomManager#isInEmergencyCall()}
*/
@@ -1507,10 +1543,10 @@
}
/**
- * See {@link TelecomManager#handleCallIntent(Intent)} ()}
+ * See {@link TelecomManager#handleCallIntent(Intent, String)}
*/
@Override
- public void handleCallIntent(Intent intent) {
+ public void handleCallIntent(Intent intent, String callingPackage) {
try {
Log.startSession("TSI.hCI");
synchronized (mLock) {
@@ -1521,7 +1557,7 @@
try {
Log.i(this, "handleCallIntent: handling call intent");
mCallIntentProcessorAdapter.processOutgoingCallIntent(mContext,
- mCallsManager, intent, null /* callingPackage */);
+ mCallsManager, intent, callingPackage);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -1746,10 +1782,6 @@
});
}
- public static String getSystemDialerPackage(Context context) {
- return context.getResources().getString(com.android.internal.R.string.config_defaultDialer);
- }
-
public ITelecomService.Stub getBinder() {
return mBinderImpl;
}
@@ -1938,6 +1970,15 @@
}
}
+ // to be used for TestApi methods that can only be called with SHELL UID.
+ private void enforceShellOnly(int callingUid, String message) {
+ if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
+ return; // okay
+ }
+
+ throw new SecurityException(message + ": Only shell user can call it");
+ }
+
private boolean canReadPhoneState(String callingPackage, String message) {
// The system/default dialer can always read phone state - so that emergency calls will
// still work.
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 5ffca0d..f354b94 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -254,7 +254,7 @@
mContactsAsyncHelper, mLock);
EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
- TelecomServiceImpl.getSystemDialerPackage(mContext), timeoutsAdapter);
+ defaultDialerCache, timeoutsAdapter);
InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
@Override
@@ -327,7 +327,7 @@
mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
- mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
+ mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
mContext, mCallsManager);
@@ -340,7 +340,7 @@
final UserManager userManager = UserManager.get(mContext);
mTelecomServiceImpl = new TelecomServiceImpl(
mContext, mCallsManager, mPhoneAccountRegistrar,
- new CallIntentProcessor.AdapterImpl(),
+ new CallIntentProcessor.AdapterImpl(defaultDialerCache),
new UserCallIntentProcessorFactory() {
@Override
public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
index 23a086b..92de536 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java
@@ -22,7 +22,9 @@
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.telecom.Log;
+import android.util.LocalLog;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.BluetoothAdapterProxy;
import com.android.server.telecom.BluetoothHeadsetProxy;
@@ -43,18 +45,21 @@
Log.startSession("BMSL.oSC");
try {
synchronized (mLock) {
+ String logString;
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadsetService =
new BluetoothHeadsetProxy((BluetoothHeadset) proxy);
- Log.i(this, "- Got BluetoothHeadset: " + mBluetoothHeadsetService);
+ logString = "Got BluetoothHeadset: " + mBluetoothHeadsetService;
} else if (profile == BluetoothProfile.HEARING_AID) {
mBluetoothHearingAidService = (BluetoothHearingAid) proxy;
- Log.i(this, "- Got BluetoothHearingAid: "
- + mBluetoothHearingAidService);
+ logString = "Got BluetoothHearingAid: "
+ + mBluetoothHearingAidService;
} else {
- Log.w(this, "Connected to non-requested bluetooth service." +
- " Not changing bluetooth headset.");
+ logString = "Connected to non-requested bluetooth service." +
+ " Not changing bluetooth headset.";
}
+ Log.i(BluetoothDeviceManager.this, logString);
+ mLocalLog.log(logString);
}
} finally {
Log.endSession();
@@ -67,23 +72,25 @@
try {
synchronized (mLock) {
LinkedHashMap<String, BluetoothDevice> lostServiceDevices;
+ String logString;
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadsetService = null;
- Log.i(BluetoothDeviceManager.this,
- "Lost BluetoothHeadset service. " +
- "Removing all tracked devices.");
lostServiceDevices = mHfpDevicesByAddress;
mBluetoothRouteManager.onActiveDeviceChanged(null, false);
+ logString = "Lost BluetoothHeadset service. " +
+ "Removing all tracked devices";
} else if (profile == BluetoothProfile.HEARING_AID) {
mBluetoothHearingAidService = null;
- Log.i(BluetoothDeviceManager.this,
- "Lost BluetoothHearingAid service. " +
- "Removing all tracked devices.");
+ logString = "Lost BluetoothHearingAid service. " +
+ "Removing all tracked devices.";
lostServiceDevices = mHearingAidDevicesByAddress;
mBluetoothRouteManager.onActiveDeviceChanged(null, true);
} else {
return;
}
+ Log.i(BluetoothDeviceManager.this, logString);
+ mLocalLog.log(logString);
+
List<BluetoothDevice> devicesToRemove = new LinkedList<>(
lostServiceDevices.values());
lostServiceDevices.clear();
@@ -103,6 +110,7 @@
new LinkedHashMap<>();
private final LinkedHashMap<BluetoothDevice, Long> mHearingAidDeviceSyncIds =
new LinkedHashMap<>();
+ private final LocalLog mLocalLog = new LocalLog(20);
// This lock only protects internal state -- it doesn't lock on anything going into Telecom.
private final Object mLock = new Object();
@@ -188,6 +196,8 @@
}
void onDeviceConnected(BluetoothDevice device, boolean isHearingAid) {
+ mLocalLog.log("Device connected -- address: " + device.getAddress() + " isHeadingAid: "
+ + isHearingAid);
synchronized (mLock) {
LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
if (isHearingAid) {
@@ -213,6 +223,8 @@
}
void onDeviceDisconnected(BluetoothDevice device, boolean isHearingAid) {
+ mLocalLog.log("Device disconnected -- address: " + device.getAddress() + " isHeadingAid: "
+ + isHearingAid);
synchronized (mLock) {
LinkedHashMap<String, BluetoothDevice> targetDeviceMap;
if (isHearingAid) {
@@ -297,4 +309,7 @@
}
}
+ public void dump(IndentingPrintWriter pw) {
+ mLocalLog.dump(pw);
+ }
}
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
index 9e64b56..7671abd 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
@@ -152,6 +152,10 @@
}
}
+ public BluetoothDeviceManager getBluetoothDeviceManager() {
+ return mBluetoothDeviceManager;
+ }
+
public BluetoothStateReceiver(BluetoothDeviceManager deviceManager,
BluetoothRouteManager routeManager) {
mBluetoothDeviceManager = deviceManager;
diff --git a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
index 0abd15d..edc68dd 100644
--- a/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
+++ b/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
@@ -30,6 +30,7 @@
import com.android.server.telecom.Call;
import com.android.server.telecom.CallerInfoLookupHelper;
import com.android.server.telecom.LogUtils;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.settings.BlockedNumbersUtil;
/**
@@ -121,15 +122,15 @@
try {
CallFilteringResult result;
if (isBlocked) {
- result = new CallFilteringResult(
- false, // shouldAllowCall
- true, //shouldReject
- true, //shouldAddToCallLog
- false, // shouldShowNotification
- convertBlockStatusToReason(), //callBlockReason
- null, //callScreeningAppName
- null //callScreeningComponentName
- );
+ result = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(false)
+ .setCallBlockReason(convertBlockStatusToReason())
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build();
if (mCallBlockListener != null) {
String number = mIncomingCall.getHandle() == null ? null
: mIncomingCall.getHandle().getSchemeSpecificPart();
@@ -137,12 +138,12 @@
mIncomingCall.getInitiatingUser());
}
} else {
- result = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ result = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
}
Log.addEvent(mIncomingCall, LogUtils.Events.BLOCK_CHECK_FINISHED,
BlockedNumberContract.SystemContract.blockStatusToString(mBlockStatus) + " "
diff --git a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
index af3ee1e..028fbf5 100644
--- a/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
+++ b/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
@@ -21,47 +21,73 @@
import android.text.TextUtils;
public class CallFilteringResult {
+ public static class Builder {
+ private boolean mShouldAllowCall;
+ private boolean mShouldReject;
+ private boolean mShouldAddToCallLog;
+ private boolean mShouldShowNotification;
+ private boolean mShouldSilence = false;
+ private int mCallBlockReason = Calls.BLOCK_REASON_NOT_BLOCKED;
+ private CharSequence mCallScreeningAppName = null;
+ private String mCallScreeningComponentName = null;
+
+ public Builder setShouldAllowCall(boolean shouldAllowCall) {
+ mShouldAllowCall = shouldAllowCall;
+ return this;
+ }
+
+ public Builder setShouldReject(boolean shouldReject) {
+ mShouldReject = shouldReject;
+ return this;
+ }
+
+ public Builder setShouldAddToCallLog(boolean shouldAddToCallLog) {
+ mShouldAddToCallLog = shouldAddToCallLog;
+ return this;
+ }
+
+ public Builder setShouldShowNotification(boolean shouldShowNotification) {
+ mShouldShowNotification = shouldShowNotification;
+ return this;
+ }
+
+ public Builder setShouldSilence(boolean shouldSilence) {
+ mShouldSilence = shouldSilence;
+ return this;
+ }
+
+ public Builder setCallBlockReason(int callBlockReason) {
+ mCallBlockReason = callBlockReason;
+ return this;
+ }
+
+ public Builder setCallScreeningAppName(CharSequence callScreeningAppName) {
+ mCallScreeningAppName = callScreeningAppName;
+ return this;
+ }
+
+ public Builder setCallScreeningComponentName(String callScreeningComponentName) {
+ mCallScreeningComponentName = callScreeningComponentName;
+ return this;
+ }
+
+ public CallFilteringResult build() {
+ return new CallFilteringResult(mShouldAllowCall, mShouldReject, mShouldSilence,
+ mShouldAddToCallLog, mShouldShowNotification, mCallBlockReason,
+ mCallScreeningAppName, mCallScreeningComponentName);
+ }
+ }
+
public boolean shouldAllowCall;
public boolean shouldReject;
public boolean shouldSilence;
public boolean shouldAddToCallLog;
public boolean shouldShowNotification;
- public int mCallBlockReason = CallLog.Calls.BLOCK_REASON_NOT_BLOCKED;
- public CharSequence mCallScreeningAppName = null;
- public String mCallScreeningComponentName = null;
+ public int mCallBlockReason;
+ public CharSequence mCallScreeningAppName;
+ public String mCallScreeningComponentName;
- public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
- shouldAddToCallLog, boolean shouldShowNotification) {
- this.shouldAllowCall = shouldAllowCall;
- this.shouldReject = shouldReject;
- this.shouldSilence = false;
- this.shouldAddToCallLog = shouldAddToCallLog;
- this.shouldShowNotification = shouldShowNotification;
- }
-
- public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
- shouldAddToCallLog, boolean shouldShowNotification, int callBlockReason,
- CharSequence callScreeningAppName, String callScreeningComponentName) {
- this.shouldAllowCall = shouldAllowCall;
- this.shouldReject = shouldReject;
- this.shouldSilence = false;
- this.shouldAddToCallLog = shouldAddToCallLog;
- this.shouldShowNotification = shouldShowNotification;
- this.mCallBlockReason = callBlockReason;
- this.mCallScreeningAppName = callScreeningAppName;
- this.mCallScreeningComponentName = callScreeningComponentName;
- }
-
- public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
- shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification) {
- this.shouldAllowCall = shouldAllowCall;
- this.shouldReject = shouldReject;
- this.shouldSilence = shouldSilence;
- this.shouldAddToCallLog = shouldAddToCallLog;
- this.shouldShowNotification = shouldShowNotification;
- }
-
- public CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
+ private CallFilteringResult(boolean shouldAllowCall, boolean shouldReject, boolean
shouldSilence, boolean shouldAddToCallLog, boolean shouldShowNotification, int
callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) {
this.shouldAllowCall = shouldAllowCall;
@@ -109,12 +135,13 @@
other.mCallScreeningAppName, other.mCallScreeningComponentName);
}
- return new CallFilteringResult(
- shouldAllowCall && other.shouldAllowCall,
- shouldReject || other.shouldReject,
- shouldSilence || other.shouldSilence,
- shouldAddToCallLog && other.shouldAddToCallLog,
- shouldShowNotification && other.shouldShowNotification);
+ return new Builder()
+ .setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
+ .setShouldReject(shouldReject || other.shouldReject)
+ .setShouldSilence(shouldSilence || other.shouldSilence)
+ .setShouldAddToCallLog(shouldAddToCallLog && other.shouldAddToCallLog)
+ .setShouldShowNotification(shouldShowNotification && other.shouldShowNotification)
+ .build();
}
private boolean isBlockedByProvider(int blockReason) {
@@ -131,15 +158,16 @@
private CallFilteringResult getCombinedCallFilteringResult(CallFilteringResult other,
int callBlockReason, CharSequence callScreeningAppName, String callScreeningComponentName) {
- return new CallFilteringResult(
- shouldAllowCall && other.shouldAllowCall,
- shouldReject || other.shouldReject,
- shouldSilence|| other.shouldSilence,
- shouldAddToCallLog && other.shouldAddToCallLog,
- shouldShowNotification && other.shouldShowNotification,
- callBlockReason,
- callScreeningAppName,
- callScreeningComponentName);
+ return new Builder()
+ .setShouldAllowCall(shouldAllowCall && other.shouldAllowCall)
+ .setShouldReject(shouldReject || other.shouldReject)
+ .setShouldSilence(shouldSilence || other.shouldSilence)
+ .setShouldAddToCallLog(shouldAddToCallLog && other.shouldAddToCallLog)
+ .setShouldShowNotification(shouldShowNotification && other.shouldShowNotification)
+ .setCallBlockReason(callBlockReason)
+ .setCallScreeningAppName(callScreeningAppName)
+ .setCallScreeningComponentName(callScreeningComponentName)
+ .build();
}
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
index 5b1971e..42d9a59 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceController.java
@@ -39,6 +39,7 @@
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomServiceImpl;
import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
/**
* This class supports binding to the various {@link android.telecom.CallScreeningService}:
@@ -66,12 +67,12 @@
private Call mCall;
private CallFilterResultCallback mCallback;
- private CallFilteringResult mResult = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ private CallFilteringResult mResult = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
private boolean mIsFinished;
private boolean mIsCarrierFinished;
@@ -195,10 +196,18 @@
if (TextUtils.isEmpty(userChosenPackageName)) {
mIsUserChosenFinished = true;
} else {
- createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
- CallScreeningServiceController.this, userChosenPackageName,
- mAppLabelProxy.getAppLabel(userChosenPackageName),
- CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
+ // If the user chosen call screening service is the same as the default dialer, then
+ // we have already bound to it above and don't need to do so again here.
+ if (userChosenPackageName.equals(dialerPackageName)) {
+ Log.addEvent(mCall, LogUtils.Events.SCREENING_SKIPPED,
+ "user pkg same as dialer: " + userChosenPackageName);
+ mIsUserChosenFinished = true;
+ } else {
+ createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
+ CallScreeningServiceController.this, userChosenPackageName,
+ mAppLabelProxy.getAppLabel(userChosenPackageName),
+ CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
+ }
}
if (mIsDefaultDialerFinished && mIsUserChosenFinished) {
@@ -253,7 +262,7 @@
PersistableBundle configBundle = configManager.getConfig();
if (configBundle != null) {
componentName = ComponentName.unflattenFromString(configBundle.getString
- (CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING));
+ (CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, ""));
}
return componentName != null ? componentName.getPackageName() : null;
diff --git a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
index c8ec18a..9ea8d70 100644
--- a/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
+++ b/src/com/android/server/telecom/callfiltering/CallScreeningServiceFilter.java
@@ -24,7 +24,7 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.provider.Settings;
import android.telecom.Log;
import android.telecom.TelecomManager;
@@ -41,6 +41,7 @@
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter;
import com.android.server.telecom.TelecomSystem;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
/**
* Binds to {@link ICallScreeningService} to allow call blocking. A single instance of this class
@@ -96,13 +97,13 @@
synchronized (mTelecomLock) {
Log.d(this, "allowCall(%s)", callId);
if (mCall != null && mCall.getId().equals(callId)) {
- mResult = new CallFilteringResult(
- true, // shouldAllowCall
- false, //shouldReject
- false, //shouldSilence
- true, //shouldAddToCallLog
- true // shouldShowNotification
- );
+ mResult = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldSilence(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
} else {
Log.w(this, "allowCall, unknown call id: %s", callId);
}
@@ -131,16 +132,16 @@
+ "shouldShowNotification: %b", callId, shouldReject,
isServiceRequestingLogging, shouldShowNotification);
if (mCall != null && mCall.getId().equals(callId)) {
- mResult = new CallFilteringResult(
- false, // shouldAllowCall
- shouldReject, //shouldReject
- false, // shouldSilenceCall
- isServiceRequestingLogging, //shouldAddToCallLog
- shouldShowNotification, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- mAppName, //callScreeningAppName
- componentName.flattenToString() //callScreeningComponentName
- );
+ mResult = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(shouldReject)
+ .setShouldSilence(false)
+ .setShouldAddToCallLog(isServiceRequestingLogging)
+ .setShouldShowNotification(shouldShowNotification)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(mAppName)
+ .setCallScreeningComponentName(componentName.flattenToString())
+ .build();
} else {
Log.w(this, "disallowCall, unknown call id: %s", callId);
}
@@ -160,13 +161,13 @@
synchronized (mTelecomLock) {
Log.d(this, "silenceCall(%s)", callId);
if (mCall != null && mCall.getId().equals(callId)) {
- mResult = new CallFilteringResult(
- true, // shouldAllowCall
- false, //shouldReject
- true, //shouldSilence
- true, //shouldAddToCallLog
- true // shouldShowNotification
- );
+ mResult = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldSilence(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
} else {
Log.w(this, "silenceCall, unknown call id: %s", callId);
}
@@ -177,6 +178,11 @@
Log.endSession();
}
}
+
+ @Override
+ public void screenCallFurther(String callId) {
+ // TODO: implement this
+ }
}
private final Context mContext;
@@ -194,12 +200,12 @@
private boolean mHasFinished = false;
private int mCallScreeningServiceType;
- private CallFilteringResult mResult = new CallFilteringResult(
- true, // shouldAllowCall
- false, //shouldReject
- true, //shouldAddToCallLog
- true // shouldShowNotification
- );
+ private CallFilteringResult mResult = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
public CallScreeningServiceFilter(
Context context,
diff --git a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
index 3a8ff7d..16d731b 100644
--- a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
@@ -17,13 +17,14 @@
package com.android.server.telecom.callfiltering;
import android.net.Uri;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.telecom.Log;
import com.android.internal.telephony.CallerInfo;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallerInfoLookupHelper;
import com.android.server.telecom.LogUtils;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import java.util.Objects;
@@ -46,33 +47,32 @@
CallFilteringResult result;
if ((handle != null) && Objects.equals(callHandle, handle)) {
if (info != null && info.shouldSendToVoicemail) {
- result = new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL,
- //callBlockReason
- null, //callScreeningAppName
- null // callScreeningComponentName
- );
+ result = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build();
} else {
- result = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ result = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
}
Log.addEvent(call, LogUtils.Events.DIRECT_TO_VM_FINISHED, result);
callback.onCallFilteringComplete(call, result);
} else {
- result = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ result = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
Log.addEvent(call, LogUtils.Events.DIRECT_TO_VM_FINISHED, result);
Log.w(this, "CallerInfo lookup returned with a different handle than " +
"what was passed in. Was %s, should be %s", handle, callHandle);
diff --git a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
index cc686ab..860de1f 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
@@ -27,6 +27,7 @@
import com.android.server.telecom.LogUtils;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import java.util.List;
@@ -53,12 +54,12 @@
private final CallFilterResultCallback mListener;
private final Timeouts.Adapter mTimeoutsAdapter;
- private CallFilteringResult mResult = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ private CallFilteringResult mResult = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
private boolean mIsPending = true;
private int mNumPendingFilters;
diff --git a/src/com/android/server/telecom/components/UserCallIntentProcessor.java b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
index ae4a7d8..134db80 100644
--- a/src/com/android/server/telecom/components/UserCallIntentProcessor.java
+++ b/src/com/android/server/telecom/components/UserCallIntentProcessor.java
@@ -22,13 +22,11 @@
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
-import android.telecom.DefaultDialerManager;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
import com.android.server.telecom.CallIntentProcessor;
import com.android.server.telecom.R;
@@ -153,31 +151,12 @@
VideoProfile.STATE_AUDIO_ONLY);
Log.d(this, "processOutgoingCallIntent videoState = " + videoState);
- intent.putExtra(CallIntentProcessor.KEY_IS_PRIVILEGED_DIALER,
- isDefaultOrSystemDialer(callingPackageName));
-
// Save the user handle of current user before forwarding the intent to primary user.
intent.putExtra(CallIntentProcessor.KEY_INITIATING_USER, mUserHandle);
sendIntentToDestination(intent, isLocalInvocation, callingPackageName);
}
- private boolean isDefaultOrSystemDialer(String callingPackageName) {
- if (TextUtils.isEmpty(callingPackageName)) {
- return false;
- }
-
- final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mContext,
- mUserHandle.getIdentifier());
- if (TextUtils.equals(defaultDialer, callingPackageName)) {
- return true;
- }
-
- final TelecomManager telecomManager =
- (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- return TextUtils.equals(telecomManager.getSystemDialerPackage(), callingPackageName);
- }
-
/**
* Returns whether the device is voice-capable (e.g. a phone vs a tablet).
*
@@ -211,7 +190,7 @@
// process; we need to trampoline to TelecomSystem in the system server process.
Log.i(this, "sendIntentToDestination: trampoline to Telecom.");
TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- tm.handleCallIntent(intent);
+ tm.handleCallIntent(intent, callingPackage);
}
return true;
}
diff --git a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
index 1fad3f7..ec5f7ba 100644
--- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
+++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
@@ -25,6 +25,7 @@
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Build;
@@ -39,6 +40,8 @@
import android.telecom.TelecomManager;
import android.telecom.VideoCallImpl;
import android.telecom.VideoProfile;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
@@ -60,6 +63,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -70,10 +74,16 @@
@RunWith(JUnit4.class)
public class AnalyticsTests extends TelecomSystemTest {
+ private SubscriptionManager mSubscriptionManager;
+
@Override
@Before
public void setUp() throws Exception {
super.setUp();
+ // this is a mock
+ mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
}
@Override
@@ -253,7 +263,7 @@
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- Analytics.dumpToEncodedProto(pw, new String[]{});
+ Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
TelecomLogClass.TelecomLog analyticsProto =
TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
@@ -300,6 +310,7 @@
@Test
public void testAnalyticsDumpToProto() throws Exception {
Analytics.reset();
+ setupCarrierIds();
IdPair testCall = startAndMakeActiveIncomingCall(
"650-555-1212",
mPhoneAccountA0.getAccountHandle(),
@@ -311,10 +322,11 @@
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- Analytics.dumpToEncodedProto(pw, new String[]{});
+ Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
TelecomLogClass.TelecomLog analyticsProto =
TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
+ assertEquals(1, analyticsProto.getCarrierId());
assertEquals(1, analyticsProto.callLogs.length);
TelecomLogClass.CallLog callLog = analyticsProto.callLogs[0];
@@ -413,7 +425,7 @@
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- Analytics.dumpToEncodedProto(pw, new String[]{});
+ Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
TelecomLogClass.TelecomLog analyticsProto =
TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
@@ -432,7 +444,7 @@
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- Analytics.dumpToEncodedProto(pw, new String[]{});
+ Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
TelecomLogClass.TelecomLog analyticsProto =
TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
@@ -445,4 +457,17 @@
private void assertIsRoundedToOneSigFig(long x) {
assertEquals(x, Analytics.roundToOneSigFig(x));
}
+
+ private void setupCarrierIds() {
+ SubscriptionInfo subInfo1 = mock(SubscriptionInfo.class);
+ SubscriptionInfo subInfo2 = mock(SubscriptionInfo.class);
+ when(subInfo1.getCarrierId()).thenReturn(1);
+ when(subInfo2.getCarrierId()).thenReturn(2);
+ when(subInfo1.isOpportunistic()).thenReturn(false);
+ when(subInfo2.isOpportunistic()).thenReturn(true);
+ when(subInfo1.getSimSlotIndex()).thenReturn(0);
+ when(subInfo2.getSimSlotIndex()).thenReturn(1);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(subInfo2, subInfo1));
+ }
}
diff --git a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
index ebc2826..ee34b0c 100644
--- a/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/AsyncBlockCheckFilterTest.java
@@ -23,7 +23,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.test.suitebuilder.annotation.SmallTest;
@@ -34,6 +34,7 @@
import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import org.junit.After;
import org.junit.Before;
@@ -61,23 +62,22 @@
@Mock private CarrierConfigManager mCarrierConfigManager;
private AsyncBlockCheckFilter mFilter;
- private static final CallFilteringResult BLOCK_RESULT = new CallFilteringResult(
- false, // shouldAllowCall
- true, //shouldReject
- true, //shouldAddToCallLog
- false, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //blockReason
- null, // callScreeningAppName
- null //callScreeningComponentName
+ private static final CallFilteringResult BLOCK_RESULT = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(false)
+ .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build();
- );
-
- private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ private static final CallFilteringResult PASS_RESULT = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
private static final int TEST_TIMEOUT = 1000;
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java b/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
index 6c5ee8b..3251d7d 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
@@ -19,16 +19,19 @@
import android.media.ToneGenerator;
import android.telecom.DisconnectCause;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import android.util.SparseArray;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallAudioModeStateMachine;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallState;
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.DtmfLocalTonePlayer;
import com.android.server.telecom.InCallTonePlayer;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.RingbackPlayer;
import com.android.server.telecom.Ringer;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
@@ -46,13 +49,16 @@
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -104,12 +110,11 @@
public void testUnmuteOfSecondIncomingCall() {
// Start with a single incoming call.
Call call = createIncomingCall();
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
when(call.can(android.telecom.Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO))
.thenReturn(false);
when(call.getId()).thenReturn("1");
- ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
- ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
// Answer the incoming call
mCallAudioManager.onIncomingCallAnswered(call);
when(call.getState()).thenReturn(CallState.ACTIVE);
@@ -117,14 +122,15 @@
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
CallAudioModeStateMachine.MessageArgs correctArgs =
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
assertMessageArgEquality(correctArgs, captor.getValue());
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
@@ -167,11 +173,10 @@
@Test
public void testSingleIncomingCallFlowWithoutMTSpeedUp() {
Call call = createIncomingCall();
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
when(call.can(android.telecom.Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO))
.thenReturn(false);
- ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
- ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
// Answer the incoming call
mCallAudioManager.onIncomingCallAnswered(call);
when(call.getState()).thenReturn(CallState.ACTIVE);
@@ -179,14 +184,15 @@
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
CallAudioModeStateMachine.MessageArgs correctArgs =
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
assertMessageArgEquality(correctArgs, captor.getValue());
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
@@ -203,12 +209,11 @@
@Test
public void testSingleIncomingCallFlowWithMTSpeedUp() {
Call call = createIncomingCall();
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
when(call.can(android.telecom.Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO))
.thenReturn(true);
when(call.getState()).thenReturn(CallState.ANSWERED);
- ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
- ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
// Answer the incoming call
mCallAudioManager.onCallStateChanged(call, CallState.RINGING, CallState.ANSWERED);
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
@@ -216,14 +221,15 @@
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
CallAudioModeStateMachine.MessageArgs correctArgs =
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
assertMessageArgEquality(correctArgs, captor.getValue());
assertMessageArgEquality(correctArgs, captor.getValue());
when(call.getState()).thenReturn(CallState.ACTIVE);
@@ -240,25 +246,25 @@
@Test
public void testSingleOutgoingCall() {
Call call = mock(Call.class);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
when(call.getState()).thenReturn(CallState.CONNECTING);
mCallAudioManager.onCallAdded(call);
assertEquals(call, mCallAudioManager.getForegroundCall());
- ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
- ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
verify(mCallAudioRouteStateMachine).sendMessageWithSessionInfo(
CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
CallAudioModeStateMachine.MessageArgs expectedArgs =
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
assertMessageArgEquality(expectedArgs, captor.getValue());
when(call.getState()).thenReturn(CallState.DIALING);
@@ -285,6 +291,347 @@
verifyProperCleanup();
}
+ @SmallTest
+ @Test
+ public void testNewCallGoesToAudioProcessing() {
+ Call call = mock(Call.class);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+ when(call.getState()).thenReturn(CallState.NEW);
+
+ // Make sure nothing happens when we add the NEW call
+ mCallAudioManager.onCallAdded(call);
+
+ verify(mCallAudioRouteStateMachine, never()).sendMessageWithSessionInfo(anyInt());
+ verify(mCallAudioModeStateMachine, never()).sendMessageWithArgs(
+ anyInt(), nullable(MessageArgs.class));
+
+ // Transition the call to AUDIO_PROCESSING and see what happens
+ when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+ mCallAudioManager.onCallStateChanged(call, CallState.NEW, CallState.AUDIO_PROCESSING);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL), captor.capture());
+
+ CallAudioModeStateMachine.MessageArgs expectedArgs =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ }
+
+ @SmallTest
+ @Test
+ public void testRingingCallGoesToAudioProcessing() {
+ Call call = mock(Call.class);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+ when(call.getState()).thenReturn(CallState.RINGING);
+
+ // Make sure appropriate messages are sent when we add a RINGING call
+ mCallAudioManager.onCallAdded(call);
+
+ assertEquals(call, mCallAudioManager.getForegroundCall());
+ verify(mCallAudioRouteStateMachine).sendMessageWithSessionInfo(
+ CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_RINGING_CALL), captor.capture());
+ CallAudioModeStateMachine.MessageArgs expectedArgs =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+
+ // Transition the call to AUDIO_PROCESSING and see what happens
+ when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+ mCallAudioManager.onCallStateChanged(call, CallState.RINGING, CallState.AUDIO_PROCESSING);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL), captor.capture());
+
+ CallAudioModeStateMachine.MessageArgs expectedArgs2 =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+ }
+
+ @SmallTest
+ @Test
+ public void testActiveCallGoesToAudioProcessing() {
+ Call call = mock(Call.class);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+ when(call.getState()).thenReturn(CallState.ACTIVE);
+
+ // Make sure appropriate messages are sent when we add an active call
+ mCallAudioManager.onCallAdded(call);
+
+ assertEquals(call, mCallAudioManager.getForegroundCall());
+ verify(mCallAudioRouteStateMachine).sendMessageWithSessionInfo(
+ CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
+ CallAudioModeStateMachine.MessageArgs expectedArgs =
+ new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+
+ // Transition the call to AUDIO_PROCESSING and see what happens
+ when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+ mCallAudioManager.onCallStateChanged(call, CallState.ACTIVE, CallState.AUDIO_PROCESSING);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL), captor.capture());
+
+ CallAudioModeStateMachine.MessageArgs expectedArgs2 =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+ }
+
+ @SmallTest
+ @Test
+ public void testAudioProcessingCallDisconnects() {
+ Call call = createAudioProcessingCall();
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ when(call.getState()).thenReturn(CallState.DISCONNECTED);
+ when(call.getDisconnectCause()).thenReturn(new DisconnectCause(DisconnectCause.LOCAL,
+ "", "", "", ToneGenerator.TONE_UNKNOWN));
+
+ mCallAudioManager.onCallStateChanged(call, CallState.AUDIO_PROCESSING,
+ CallState.DISCONNECTED);
+ verify(mPlayerFactory, never()).createPlayer(anyInt());
+ CallAudioModeStateMachine.MessageArgs expectedArgs2 = new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+ verify(mCallAudioModeStateMachine, never()).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.TONE_STARTED_PLAYING), nullable(MessageArgs.class));
+
+ mCallAudioManager.onCallRemoved(call);
+ verifyProperCleanup();
+ }
+
+ @SmallTest
+ @Test
+ public void testAudioProcessingCallDoesSimulatedRing() {
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ Call call = createAudioProcessingCall();
+
+ when(call.getState()).thenReturn(CallState.SIMULATED_RINGING);
+
+ mCallAudioManager.onCallStateChanged(call, CallState.AUDIO_PROCESSING,
+ CallState.SIMULATED_RINGING);
+ verify(mPlayerFactory, never()).createPlayer(anyInt());
+ CallAudioModeStateMachine.MessageArgs expectedArgs = new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_RINGING_CALL), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ }
+
+ @SmallTest
+ @Test
+ public void testAudioProcessingCallGoesActive() {
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ Call call = createAudioProcessingCall();
+
+ when(call.getState()).thenReturn(CallState.ACTIVE);
+
+ mCallAudioManager.onCallStateChanged(call, CallState.AUDIO_PROCESSING,
+ CallState.ACTIVE);
+ verify(mPlayerFactory, never()).createPlayer(anyInt());
+ CallAudioModeStateMachine.MessageArgs expectedArgs = new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ }
+
+ @SmallTest
+ @Test
+ public void testSimulatedRingingCallGoesActive() {
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ Call call = createSimulatedRingingCall();
+
+ when(call.getState()).thenReturn(CallState.ACTIVE);
+
+ mCallAudioManager.onCallStateChanged(call, CallState.SIMULATED_RINGING,
+ CallState.ACTIVE);
+ verify(mPlayerFactory, never()).createPlayer(anyInt());
+ CallAudioModeStateMachine.MessageArgs expectedArgs = new Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+ }
+
+ private Call createAudioProcessingCall() {
+ Call call = mock(Call.class);
+ when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ // Set up an AUDIO_PROCESSING call
+ mCallAudioManager.onCallAdded(call);
+
+ assertNull(mCallAudioManager.getForegroundCall());
+
+ verify(mCallAudioRouteStateMachine, never()).sendMessageWithSessionInfo(
+ CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL), captor.capture());
+ CallAudioModeStateMachine.MessageArgs expectedArgs =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+
+ return call;
+ }
+
+ @SmallTest
+ @Test
+ public void testSimulatedRingingCallDisconnects() {
+ Call call = createSimulatedRingingCall();
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ when(call.getState()).thenReturn(CallState.DISCONNECTED);
+ when(call.getDisconnectCause()).thenReturn(new DisconnectCause(DisconnectCause.LOCAL,
+ "", "", "", ToneGenerator.TONE_UNKNOWN));
+
+ mCallAudioManager.onCallStateChanged(call, CallState.SIMULATED_RINGING,
+ CallState.DISCONNECTED);
+ verify(mPlayerFactory, never()).createPlayer(anyInt());
+ CallAudioModeStateMachine.MessageArgs expectedArgs2 = new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
+ assertMessageArgEquality(expectedArgs2, captor.getValue());
+ verify(mCallAudioModeStateMachine, never()).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.TONE_STARTED_PLAYING), nullable(MessageArgs.class));
+
+ mCallAudioManager.onCallRemoved(call);
+ verifyProperCleanup();
+ }
+
+ private Call createSimulatedRingingCall() {
+ Call call = mock(Call.class);
+ when(call.getState()).thenReturn(CallState.SIMULATED_RINGING);
+ ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();
+
+ mCallAudioManager.onCallAdded(call);
+
+ assertEquals(call, mCallAudioManager.getForegroundCall());
+
+ verify(mCallAudioRouteStateMachine).sendMessageWithSessionInfo(
+ CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
+ verify(mCallAudioModeStateMachine).sendMessageWithArgs(
+ eq(CallAudioModeStateMachine.NEW_RINGING_CALL), captor.capture());
+ CallAudioModeStateMachine.MessageArgs expectedArgs =
+ new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setHasAudioProcessingCalls(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
+ assertMessageArgEquality(expectedArgs, captor.getValue());
+
+ return call;
+ }
+
private Call createIncomingCall() {
Call call = mock(Call.class);
when(call.getState()).thenReturn(CallState.RINGING);
@@ -297,14 +644,15 @@
CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NEW_RINGING_CALL), captor.capture());
- assertMessageArgEquality(new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ), captor.getValue());
+ assertMessageArgEquality(new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ captor.getValue());
return call;
}
@@ -320,14 +668,14 @@
mCallAudioManager.onCallStateChanged(call, CallState.ACTIVE, CallState.DISCONNECTED);
verify(mPlayerFactory).createPlayer(InCallTonePlayer.TONE_CALL_ENDED);
- correctArgs = new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ correctArgs = new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS), captor.capture());
assertMessageArgEquality(correctArgs, captor.getValue());
@@ -340,15 +688,14 @@
ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
mCallAudioManager.setIsTonePlaying(false);
- CallAudioModeStateMachine.MessageArgs correctArgs =
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- );
+ CallAudioModeStateMachine.MessageArgs correctArgs = new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build();
verify(mCallAudioModeStateMachine).sendMessageWithArgs(
eq(CallAudioModeStateMachine.TONE_STOPPED_PLAYING), captor.capture());
assertMessageArgEquality(correctArgs, captor.getValue());
@@ -362,6 +709,10 @@
}
}
+ private ArgumentCaptor<MessageArgs> makeNewCaptor() {
+ return ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
+ }
+
private void assertMessageArgEquality(CallAudioModeStateMachine.MessageArgs expected,
CallAudioModeStateMachine.MessageArgs actual) {
assertEquals(expected.hasActiveOrDialingCalls, actual.hasActiveOrDialingCalls);
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
index 0e33721..ca84c4c 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
@@ -23,6 +23,7 @@
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.SystemStateHelper;
import org.junit.After;
@@ -79,15 +80,14 @@
resetMocks();
when(mCallAudioManager.startRinging()).thenReturn(false);
- sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ));
+ sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build());
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
assertEquals(CallAudioModeStateMachine.RING_STATE_NAME, sm.getCurrentStateName());
@@ -107,29 +107,27 @@
mAudioManager, mTestThread.getLooper());
sm.setCallAudioManager(mCallAudioManager);
sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
- sm.sendMessage(CallAudioModeStateMachine.NEW_HOLDING_CALL,
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ));
+ sm.sendMessage(CallAudioModeStateMachine.NEW_HOLDING_CALL, new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build());
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
assertEquals(CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, sm.getCurrentStateName());
when(mSystemStateHelper.isDeviceAtEar()).thenReturn(true);
resetMocks();
- sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ));
+ sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build());
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
verify(mAudioManager, never()).requestAudioFocusForCall(anyInt(), anyInt());
@@ -150,15 +148,14 @@
resetMocks();
when(mCallAudioManager.startRinging()).thenReturn(false);
- sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ));
+ sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build());
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
assertEquals(CallAudioModeStateMachine.RING_STATE_NAME, sm.getCurrentStateName());
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java
index c90557d..2047867 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java
@@ -16,13 +16,13 @@
package com.android.server.telecom.tests;
-import android.content.Context;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs;
import com.android.server.telecom.SystemStateHelper;
import org.junit.After;
@@ -200,14 +200,14 @@
"New active/dialing call with no other calls when unfocused",
CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -219,14 +219,14 @@
"New active/dialing voip call with no other calls when unfocused",
CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- true, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(true)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.COMMS_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_COMMUNICATION, // expectedMode
@@ -238,14 +238,14 @@
"New ringing call with no other calls when unfocused",
CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_RINGING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.RING_STATE_NAME, // expectedFinalStateName
FOCUS_RING, // expectedFocus
AudioManager.MODE_RINGTONE, // expectedMode
@@ -257,14 +257,14 @@
"New ringing call coming in on top of active/dialing call",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_RINGING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -276,14 +276,14 @@
"Ringing call becomes active, part 1",
CallAudioModeStateMachine.ENTER_RING_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -295,14 +295,14 @@
"Ringing call becomes active, part 2",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -314,14 +314,14 @@
"Active call disconnects, but tone is playing",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -333,14 +333,14 @@
"Tone stops playing, with no active calls",
CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.TONE_STOPPED_PLAYING, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName
FOCUS_OFF, // expectedFocus
AudioManager.MODE_NORMAL, // expectedMode
@@ -352,14 +352,14 @@
"Ringing call disconnects",
CallAudioModeStateMachine.ENTER_RING_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName
FOCUS_OFF, // expectedFocus
AudioManager.MODE_NORMAL, // expectedMode
@@ -371,14 +371,14 @@
"Call-waiting call disconnects",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -390,14 +390,14 @@
"Call is placed on hold - 1",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -409,14 +409,14 @@
"Call is placed on hold - 2",
CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, // expectedFinalStateName
FOCUS_NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -428,14 +428,14 @@
"Swap between voip and sim calls - 1",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- true, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(true)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.COMMS_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_COMMUNICATION, // expectedMode
@@ -447,14 +447,14 @@
"Swap between voip and sim calls - 2",
CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -466,14 +466,14 @@
"Swap between voip and sim calls - 3",
CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -485,14 +485,14 @@
"Swap between voip and sim calls - 4",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- true, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(true)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.COMMS_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_COMMUNICATION, // expectedMode
@@ -504,14 +504,14 @@
"Call is taken off hold - 1",
CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_HOLDING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -523,14 +523,14 @@
"Call is taken off hold - 2",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -542,14 +542,14 @@
"Active call disconnects while there's a call-waiting call",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- true, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.RING_STATE_NAME, // expectedFinalStateName
FOCUS_RING, // expectedFocus
AudioManager.MODE_RINGTONE, // expectedMode
@@ -561,14 +561,14 @@
"New dialing call when there's a call on hold",
CallAudioModeStateMachine.ENTER_TONE_OR_HOLD_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -580,14 +580,14 @@
"Ringing call disconnects with a holding call in the background",
CallAudioModeStateMachine.ENTER_RING_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- false, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- true, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_NORMAL, // expectedMode -- we're expecting this because
@@ -600,14 +600,14 @@
"Foreground call transitions from sim to voip",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- true, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(true)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.COMMS_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_COMMUNICATION, // expectedMode
@@ -619,14 +619,14 @@
"Foreground call transitions from voip to sim",
CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- false, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_VOICE, // expectedFocus
AudioManager.MODE_IN_CALL, // expectedMode
@@ -639,14 +639,14 @@
"foreground",
CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- false, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
FOCUS_NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -659,14 +659,14 @@
"foreground",
CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
- new CallAudioModeStateMachine.MessageArgs(
- true, // hasActiveOrDialingCalls
- false, // hasRingingCalls
- false, // hasHoldingCalls
- true, // isTonePlaying
- true, // foregroundCallIsVoip
- null // session
- ),
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setIsTonePlaying(true)
+ .setForegroundCallIsVoip(true)
+ .setSession(null)
+ .build(),
CallAudioModeStateMachine.COMMS_STATE_NAME, // expectedFinalStateName
FOCUS_NO_CHANGE, // expectedFocus
NO_CHANGE, // expectedMode
@@ -674,6 +674,188 @@
OFF // expectedCallWaitingInteraction
));
+ result.add(new ModeTestParameters(
+ "Call enters audio processing state from call screening service",
+ CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.AUDIO_PROCESSING_STATE_NAME, // expectedFinalStateName
+ FOCUS_NO_CHANGE, // expectedFocus
+ CallAudioModeStateMachine.NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING, // expectedMode
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Call enters audio processing state by manual intervention from ringing state, 1",
+ CallAudioModeStateMachine.ENTER_RING_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NO_MORE_RINGING_CALLS, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.AUDIO_PROCESSING_STATE_NAME, // expectedFinalStateName
+ FOCUS_OFF, // expectedFocus
+ CallAudioModeStateMachine.NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING, // expectedMode
+ OFF, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Call enters audio processing state by manual intervention from ringing state, 2",
+ CallAudioModeStateMachine.ENTER_RING_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.AUDIO_PROCESSING_STATE_NAME, // expectedFinalStateName
+ FOCUS_OFF, // expectedFocus
+ CallAudioModeStateMachine.NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING, // expectedMode
+ OFF, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Call enters audio processing state from active call, 1",
+ CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.AUDIO_PROCESSING_STATE_NAME, // expectedFinalStateName
+ FOCUS_OFF, // expectedFocus
+ CallAudioModeStateMachine.NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING, // expectedMode
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Call enters audio processing state from active call, 2",
+ CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_AUDIO_PROCESSING_CALL, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(true)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.AUDIO_PROCESSING_STATE_NAME, // expectedFinalStateName
+ FOCUS_OFF, // expectedFocus
+ CallAudioModeStateMachine.NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING, // expectedMode
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Call in audio processing gets hanged up",
+ CallAudioModeStateMachine.ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING, // initialAudioS
+ CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.UNFOCUSED_STATE_NAME, // expectedFinalStateName
+ NO_CHANGE, // expectedFocus
+ AudioManager.MODE_NORMAL, // expectedMode
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Notify user of a call in audio processing by simulating ringing, 1",
+ CallAudioModeStateMachine.ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING, // initialAudioS
+ CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.RING_STATE_NAME, // expectedFinalStateName
+ FOCUS_RING, // expectedFocus
+ AudioManager.MODE_RINGTONE, // expectedMode
+ ON, // expectedRingingInteraction
+ // We expect a call to stopCallWaiting because it happens whenever the ringer starts
+ OFF // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Notify user of a call in audio processing by simulating ringing, 2",
+ CallAudioModeStateMachine.ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING, // initialAudioS
+ CallAudioModeStateMachine.NEW_RINGING_CALL, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(false)
+ .setHasRingingCalls(true)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.RING_STATE_NAME, // expectedFinalStateName
+ FOCUS_RING, // expectedFocus
+ AudioManager.MODE_RINGTONE, // expectedMode
+ ON, // expectedRingingInteraction
+ // We expect a call to stopCallWaiting because it happens whenever the ringer starts
+ OFF // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Audio processing call gets set to active manually",
+ CallAudioModeStateMachine.ENTER_AUDIO_PROCESSING_FOCUS_FOR_TESTING, // initialAudioS
+ CallAudioModeStateMachine.NO_MORE_AUDIO_PROCESSING_CALLS, // messageType
+ new MessageArgs.Builder()
+ .setHasActiveOrDialingCalls(true)
+ .setHasRingingCalls(false)
+ .setHasHoldingCalls(false)
+ .setHasAudioProcessingCalls(false)
+ .setIsTonePlaying(false)
+ .setForegroundCallIsVoip(false)
+ .setSession(null)
+ .build(),
+ CallAudioModeStateMachine.CALL_STATE_NAME, // expectedFinalStateName
+ FOCUS_VOICE, // expectedFocus
+ AudioManager.MODE_IN_CALL, // expectedMode
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
return result;
}
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
index c4acfe0..24cc8d2 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
@@ -29,6 +29,7 @@
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.test.suitebuilder.annotation.SmallTest;
@@ -45,6 +46,7 @@
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceController;
import org.junit.After;
@@ -70,31 +72,6 @@
@RunWith(JUnit4.class)
public class CallScreeningServiceControllerTest extends TelecomTestCase {
- @Mock Context mContext;
- @Mock Call mCall;
- @Mock private CallFilterResultCallback mCallback;
- @Mock CallsManager mCallsManager;
- @Mock RoleManagerAdapter mRoleManagerAdapter;
- @Mock CarrierConfigManager mCarrierConfigManager;
- @Mock private TelecomManager mTelecomManager;
- @Mock PackageManager mPackageManager;
- @Mock ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
- @Mock PhoneAccountRegistrar mPhoneAccountRegistrar;
- @Mock private CallerInfoLookupHelper mCallerInfoLookupHelper;
-
- CallScreeningServiceHelper.AppLabelProxy mAppLabelProxy =
- new CallScreeningServiceHelper.AppLabelProxy() {
- @Override
- public CharSequence getAppLabel(String packageName) {
- return APP_NAME;
- }
- };
-
- private ResolveInfo mResolveInfo;
- private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
- spy(new CallScreeningServiceFilterTest.SettingsSecureAdapterFake());
- private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
-
private static final String CALL_ID = "u89prgt9ps78y5";
private static final Uri TEST_HANDLE = Uri.parse("tel:1235551234");
private static final String DEFAULT_DIALER_PACKAGE = "com.android.dialer";
@@ -107,27 +84,46 @@
"com.android.dialer", "com.android.dialer.callscreeningserviceimpl");
private static final ComponentName USER_CHOSEN_CALL_SCREENING = new ComponentName(
"com.android.userchosen", "com.android.userchosen.callscreeningserviceimpl");
-
- private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
-
- public static class SettingsSecureAdapterFake implements
- TelecomServiceImpl.SettingsSecureAdapter {
- @Override
- public void putStringForUser(ContentResolver resolver, String name, String value,
- int userHandle) {
-
- }
-
- @Override
- public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
- return USER_CHOSEN_CALL_SCREENING.flattenToString();
- }
- }
+ private static final CallFilteringResult PASS_RESULT = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
+ @Mock
+ Context mContext;
+ @Mock
+ Call mCall;
+ @Mock
+ CallsManager mCallsManager;
+ @Mock
+ RoleManagerAdapter mRoleManagerAdapter;
+ @Mock
+ CarrierConfigManager mCarrierConfigManager;
+ @Mock
+ PackageManager mPackageManager;
+ @Mock
+ ParcelableCallUtils.Converter mParcelableCallUtilsConverter;
+ @Mock
+ PhoneAccountRegistrar mPhoneAccountRegistrar;
+ CallScreeningServiceHelper.AppLabelProxy mAppLabelProxy =
+ new CallScreeningServiceHelper.AppLabelProxy() {
+ @Override
+ public CharSequence getAppLabel(String packageName) {
+ return APP_NAME;
+ }
+ };
+ @Mock
+ private CallFilterResultCallback mCallback;
+ @Mock
+ private TelecomManager mTelecomManager;
+ @Mock
+ private CallerInfoLookupHelper mCallerInfoLookupHelper;
+ private ResolveInfo mResolveInfo;
+ private TelecomServiceImpl.SettingsSecureAdapter mSettingsSecureAdapter =
+ spy(new CallScreeningServiceFilterTest.SettingsSecureAdapterFake());
+ private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {
+ };
@Override
@Before
@@ -145,7 +141,7 @@
when(TelecomManager.from(mContext)).thenReturn(mTelecomManager);
when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
- mResolveInfo = new ResolveInfo() {{
+ mResolveInfo = new ResolveInfo() {{
serviceInfo = new ServiceInfo();
serviceInfo.packageName = PKG_NAME;
serviceInfo.name = CLS_NAME;
@@ -236,30 +232,27 @@
controller.startFilterLookup(mCall, mCallback);
- controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
- APP_NAME,
- CARRIER_DEFINED_CALL_SCREENING.flattenToString()
- ), CARRIER_DEFINED_CALL_SCREENING.getPackageName());
+ CallFilteringResult expectedResult = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(
+ CARRIER_DEFINED_CALL_SCREENING.flattenToString())
+ .build();
+
+ controller.onCallScreeningFilterComplete(mCall, expectedResult,
+ CARRIER_DEFINED_CALL_SCREENING.getPackageName());
verify(mContext, times(1)).bindServiceAsUser(any(Intent.class),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
- verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- APP_NAME, //callScreeningAppName
- CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )));
+ verify(mCallback)
+ .onCallFilteringComplete(eq(mCall), eq(expectedResult));
}
@SmallTest
@@ -282,30 +275,31 @@
callerInfo.contactExists = false;
queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
- controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
- APP_NAME,
- DEFAULT_DIALER_CALL_SCREENING.flattenToString()
- ), DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+ CallFilteringResult.Builder resultBuilder = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString());
+
+ CallFilteringResult providedResult = resultBuilder
+ .setShouldAddToCallLog(false)
+ .build();
+
+ controller.onCallScreeningFilterComplete(mCall, providedResult,
+ DEFAULT_DIALER_CALL_SCREENING.getPackageName());
verify(mContext, times(3)).bindServiceAsUser(any(Intent.class),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
- verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog (we don't allow services to skip call log)
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- APP_NAME, //callScreeningAppName
- DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )));
+ CallFilteringResult expectedResult = resultBuilder
+ .setShouldAddToCallLog(true)
+ .build();
+
+ verify(mCallback).onCallFilteringComplete(eq(mCall), eq(expectedResult));
}
@SmallTest
@@ -330,30 +324,99 @@
controller.onCallScreeningFilterComplete(mCall, PASS_RESULT,
DEFAULT_DIALER_CALL_SCREENING.getPackageName());
- controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE,
- APP_NAME,
- USER_CHOSEN_CALL_SCREENING.flattenToString()
- ), USER_CHOSEN_CALL_SCREENING.getPackageName());
+
+ CallFilteringResult.Builder resultBuilder = new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString());
+ CallFilteringResult providedResult = resultBuilder
+ .setShouldAddToCallLog(false)
+ .build();
+
+ controller.onCallScreeningFilterComplete(mCall, providedResult,
+ USER_CHOSEN_CALL_SCREENING.getPackageName());
verify(mContext, times(3)).bindServiceAsUser(any(Intent.class),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
- verify(mCallback).onCallFilteringComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog (we don't allow services to skip call log)
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- APP_NAME, //callScreeningAppName
- USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )));
+ CallFilteringResult expectedResult = resultBuilder
+ .setShouldAddToCallLog(true)
+ .build();
+
+ verify(mCallback).onCallFilteringComplete(eq(mCall), eq(expectedResult));
+ }
+
+ /**
+ * This test verifies that where the default dialer role is filled by the same app as the caller
+ * id and spam role, we will only bind to that call screening service once.
+ */
+ @SmallTest
+ @Test
+ public void testOnlyBindOnce() {
+ // Assume the user chose the default dialer to also fill the caller id and spam role.
+ when(mRoleManagerAdapter.getDefaultCallScreeningApp()).thenReturn(
+ DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+ CallScreeningServiceController controller = new CallScreeningServiceController(mContext,
+ mCallsManager,
+ mPhoneAccountRegistrar, mParcelableCallUtilsConverter, mLock,
+ mSettingsSecureAdapter, mCallerInfoLookupHelper, mAppLabelProxy);
+
+ controller.startFilterLookup(mCall, mCallback);
+
+ controller.onCallScreeningFilterComplete(mCall, PASS_RESULT,
+ CARRIER_DEFINED_CALL_SCREENING.getPackageName());
+
+ CallerInfoLookupHelper.OnQueryCompleteListener queryListener = verifyLookupStart();
+ CallerInfo callerInfo = new CallerInfo();
+ callerInfo.contactExists = false;
+ queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
+
+ controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult.Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(
+ DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+ .build(),
+ DEFAULT_DIALER_CALL_SCREENING.getPackageName());
+
+ controller.onCallScreeningFilterComplete(mCall, new CallFilteringResult.Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+ .build(), USER_CHOSEN_CALL_SCREENING.getPackageName());
+
+ // Expect to bind twice; once to the carrier defined service, and then again to the default
+ // dialer.
+ verify(mContext, times(2)).bindServiceAsUser(any(Intent.class),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.CURRENT));
+
+ // Expect filtering to complete only a single time from the default dialer service.
+ verify(mCallback, times(1)).onCallFilteringComplete(eq(mCall),
+ eq(new CallFilteringResult.Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(APP_NAME)
+ .setCallScreeningComponentName(
+ DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+ .build()));
}
private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart() {
@@ -377,4 +440,18 @@
.thenReturn(mCarrierConfigManager);
when(mCarrierConfigManager.getConfig()).thenReturn(bundle);
}
+
+ public static class SettingsSecureAdapterFake implements
+ TelecomServiceImpl.SettingsSecureAdapter {
+ @Override
+ public void putStringForUser(ContentResolver resolver, String name, String value,
+ int userHandle) {
+
+ }
+
+ @Override
+ public String getStringForUser(ContentResolver resolver, String name, int userHandle) {
+ return USER_CHOSEN_CALL_SCREENING.flattenToString();
+ }
+ }
}
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
index b11b397..7b3a499 100644
--- a/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallScreeningServiceFilterTest.java
@@ -29,7 +29,7 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.telecom.CallScreeningService;
import android.telecom.ParcelableCall;
import android.telecom.TelecomManager;
@@ -44,6 +44,7 @@
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomServiceImpl;
import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.CallScreeningServiceFilter;
import com.android.server.telecom.TelecomSystem;
@@ -105,20 +106,20 @@
private static final String USER_CHOSEN_CALL_SCREENING_APP_NAME = "UserChosen";
private ResolveInfo mResolveInfo;
- private static final CallFilteringResult PASS_RESULT = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ private static final CallFilteringResult PASS_RESULT = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
- private static final CallFilteringResult PASS_RESULT_WITH_SILENCE = new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldSilence
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ private static final CallFilteringResult PASS_RESULT_WITH_SILENCE = new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldSilence(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
private CallScreeningServiceFilter mFilter;
@@ -274,15 +275,17 @@
true, // shouldShowNotification
CARRIER_DEFINED_CALL_SCREENING
);
- verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- CARRIER_DEFINED_CALL_SCREENING_APP_NAME, //callScreeningAppName
- CARRIER_DEFINED_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )), eq(CARRIER_DEFINED_CALL_SCREENING.getPackageName()));
+ verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(CARRIER_DEFINED_CALL_SCREENING_APP_NAME)
+ .setCallScreeningComponentName(
+ CARRIER_DEFINED_CALL_SCREENING.flattenToString())
+ .build()),
+ eq(CARRIER_DEFINED_CALL_SCREENING.getPackageName()));
}
@SmallTest
@@ -307,15 +310,16 @@
true, // shouldShowNotification
DEFAULT_DIALER_CALL_SCREENING
);
- verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- DEFAULT_DIALER_APP_NAME, //callScreeningAppName
- DEFAULT_DIALER_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )), eq(DEFAULT_DIALER_CALL_SCREENING.getPackageName()));
+ verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(DEFAULT_DIALER_APP_NAME)
+ .setCallScreeningComponentName(DEFAULT_DIALER_CALL_SCREENING.flattenToString())
+ .build()),
+ eq(DEFAULT_DIALER_CALL_SCREENING.getPackageName()));
}
@SmallTest
@@ -340,15 +344,16 @@
true, // shouldShowNotification
USER_CHOSEN_CALL_SCREENING
);
- verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- USER_CHOSEN_CALL_SCREENING_APP_NAME, //callScreeningAppName
- USER_CHOSEN_CALL_SCREENING.flattenToString() //callScreeningComponentName
- )), eq(USER_CHOSEN_CALL_SCREENING.getPackageName()));
+ verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName(USER_CHOSEN_CALL_SCREENING_APP_NAME)
+ .setCallScreeningComponentName(USER_CHOSEN_CALL_SCREENING.flattenToString())
+ .build()),
+ eq(USER_CHOSEN_CALL_SCREENING.getPackageName()));
}
private ServiceConnection verifyBindingIntent() {
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 165d80e..fdd1d89 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -263,7 +263,7 @@
Call ongoingCall = new Call(
"1", /* callId */
- mComponentContextFixture.getTestDouble(),
+ mContext,
mCallsManager,
mLock,
null /* ConnectionServiceRepository */,
@@ -1026,7 +1026,8 @@
public void testIsInEmergencyCallLocal() {
// Setup a call which is considered emergency based on its phone number.
Call ongoingCall = addSpyCall();
- when(mPhoneNumberUtilsAdapter.isLocalEmergencyNumber(any(), any())).thenReturn(true);
+ when(mComponentContextFixture.getTelephonyManager().isEmergencyNumber(any()))
+ .thenReturn(true);
ongoingCall.setHandle(Uri.fromParts("tel", "5551212", null),
TelecomManager.PRESENTATION_ALLOWED);
@@ -1102,7 +1103,7 @@
private Call addSpyCall(PhoneAccountHandle targetPhoneAccount) {
Call ongoingCall = new Call(String.format("TC@%d", sCallId++), /* callId */
- mComponentContextFixture.getTestDouble(),
+ mContext,
mCallsManager,
mLock, /* ConnectionServiceRepository */
null,
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index 86bbadb..e6e8ba1 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -51,6 +51,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IInterface;
+import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.telecom.CallAudioState;
@@ -209,6 +210,10 @@
return Context.AUDIO_SERVICE;
} else if (svcClass == TelephonyManager.class) {
return Context.TELEPHONY_SERVICE;
+ } else if (svcClass == CarrierConfigManager.class) {
+ return Context.CARRIER_CONFIG_SERVICE;
+ } else if (svcClass == SubscriptionManager.class) {
+ return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
}
throw new UnsupportedOperationException();
}
@@ -513,6 +518,9 @@
when(mNotificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
+ when(mCarrierConfigManager.getConfig()).thenReturn(new PersistableBundle());
+ when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(new PersistableBundle());
+
when(mUserManager.getSerialNumberForUser(any(UserHandle.class))).thenReturn(-1L);
doReturn(null).when(mApplicationContextSpy).registerReceiver(any(BroadcastReceiver.class),
diff --git a/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
index c2db626..845a838 100644
--- a/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
+++ b/tests/src/com/android/server/telecom/tests/CreateConnectionProcessorTest.java
@@ -48,7 +48,9 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
@@ -286,6 +288,45 @@
}
/**
+ * Ensure that when a test emergency number is being dialed and we restrict the usable
+ * PhoneAccounts using {@link PhoneAccountRegistrar#filterRestrictedPhoneAccounts(List)}, the
+ * test emergency call is sent on the filtered PhoneAccount.
+ */
+ @SmallTest
+ @Test
+ public void testFakeEmergencyNumber() throws Exception {
+ when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(true);
+ // Put in a regular phone account as the target and make sure it calls that.
+ PhoneAccount regularAccount = makeEmergencyTestPhoneAccount("tel_acct1", 0);
+ PhoneAccountHandle regularAccountHandle = regularAccount.getAccountHandle();
+ List<PhoneAccount> filteredList = new ArrayList<>();
+ filteredList.add(regularAccount);
+ when(mMockAccountRegistrar.filterRestrictedPhoneAccounts(anyList()))
+ .thenReturn(filteredList);
+ mapToSubSlot(regularAccount, 1 /*subId*/, 0 /*slotId*/);
+ setTargetPhoneAccount(mMockCall, regularAccount.getAccountHandle());
+ phoneAccounts.add(regularAccount);
+ // Do not use this account, even though it is a SIM subscription and can place emergency
+ // calls
+ ConnectionServiceWrapper service = makeConnectionServiceWrapper();
+ PhoneAccount emergencyPhoneAccount = makeEmergencyPhoneAccount("tel_emer", 0);
+ mapToSubSlot(emergencyPhoneAccount, 2 /*subId*/, 1 /*slotId*/);
+ phoneAccounts.add(emergencyPhoneAccount);
+
+ mTestCreateConnectionProcessor.process();
+
+ verify(mMockCall).setConnectionManagerPhoneAccount(eq(regularAccountHandle));
+ verify(mMockCall).setTargetPhoneAccount(eq(regularAccountHandle));
+ verify(mMockCall).setConnectionService(eq(service));
+ verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class));
+ // Notify successful connection to call
+ CallIdMapper mockCallIdMapper = mock(CallIdMapper.class);
+ mTestCreateConnectionProcessor.handleCreateConnectionSuccess(mockCallIdMapper, null);
+ verify(mMockCreateConnectionResponse).handleCreateConnectionSuccess(mockCallIdMapper, null);
+ }
+
+ /**
* Ensure that the non-emergency capable PhoneAccount and the SIM manager is not chosen to place
* the emergency call if there is an emergency capable PhoneAccount available as well.
*/
@@ -293,6 +334,7 @@
@Test
public void testEmergencyCall() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
// Put in a regular phone account as the target to be sure it doesn't call that
PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
@@ -331,6 +373,7 @@
@Test
public void testEmergencyCallMultiSimNoPreferred() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
// Put in a non-SIM phone account as the target to be sure it doesn't call that.
PhoneAccount regularAccount = makePhoneAccount("tel_acct1", 0);
setTargetPhoneAccount(mMockCall, regularAccount.getAccountHandle());
@@ -368,6 +411,7 @@
@Test
public void testEmergencyCallMultiSimTelephonyPreferred() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
ConnectionServiceWrapper service = makeConnectionServiceWrapper();
PhoneAccount emergencyPhoneAccount1 = makeEmergencyPhoneAccount("tel_emer1", 0);
mapToSubSlot(emergencyPhoneAccount1, 1 /*subId*/, 0 /*slotId*/);
@@ -400,6 +444,7 @@
@Test
public void testEmergencyCallMultiSimUserPreferred() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
// Include a Connection Manager to be sure it doesn't call that
PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
"cm_acct", 0);
@@ -436,6 +481,7 @@
@Test
public void testEmergencyCallMultiSimUserPreferredInvalidSlot() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
// Include a Connection Manager to be sure it doesn't call that
PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
"cm_acct", 0);
@@ -472,6 +518,7 @@
@Test
public void testEmergencyCallMultiSimNoPreferenceInvalidSlot() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
// Include a Connection Manager to be sure it doesn't call that
PhoneAccount callManagerPA = createNewConnectionManagerPhoneAccountForCall(mMockCall,
"cm_acct", 0);
@@ -503,6 +550,7 @@
@Test
public void testEmergencyCallSimFailToConnectionManager() throws Exception {
when(mMockCall.isEmergencyCall()).thenReturn(true);
+ when(mMockCall.isTestEmergencyCall()).thenReturn(false);
when(mMockCall.getHandle()).thenReturn(Uri.parse(""));
// Put in a regular phone account to be sure it doesn't call that
PhoneAccount regularAccount = makePhoneAccount("tel_acct1",
@@ -542,6 +590,16 @@
verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class));
}
+ private PhoneAccount makeEmergencyTestPhoneAccount(String id, int capabilities) {
+ final PhoneAccount emergencyPhoneAccount = makeQuickAccount(id, capabilities |
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS);
+ PhoneAccountHandle emergencyPhoneAccountHandle = emergencyPhoneAccount.getAccountHandle();
+ givePhoneAccountBindPermission(emergencyPhoneAccountHandle);
+ when(mMockAccountRegistrar.getPhoneAccountUnchecked(emergencyPhoneAccountHandle))
+ .thenReturn(emergencyPhoneAccount);
+ return emergencyPhoneAccount;
+ }
+
private PhoneAccount makeEmergencyPhoneAccount(String id, int capabilities) {
final PhoneAccount emergencyPhoneAccount = makeQuickAccount(id, capabilities |
PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS |
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index 551165d..e62a9fc 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -17,14 +17,14 @@
package com.android.server.telecom.tests;
import android.net.Uri;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.CallerInfo;
import com.android.server.telecom.Call;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.CallerInfoLookupHelper;
-import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.DirectToVoicemailCallFilter;
import org.junit.After;
@@ -68,16 +68,15 @@
callerInfo.shouldSendToVoicemail = true;
queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
- verify(mCallback).onCallFilteringComplete(mCall,
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
- null, //callScreeningAppName
- null // callScreeningComponentName
- ));
+ verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build());
}
@SmallTest
@@ -89,13 +88,12 @@
callerInfo.shouldSendToVoicemail = false;
queryListener.onCallerInfoQueryComplete(TEST_HANDLE, callerInfo);
- verify(mCallback).onCallFilteringComplete(mCall,
- new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- ));
+ verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build());
}
@SmallTest
@@ -104,13 +102,12 @@
CallerInfoLookupHelper.OnQueryCompleteListener queryListener = verifyLookupStart(null);
queryListener.onCallerInfoQueryComplete(null, null);
- verify(mCallback).onCallFilteringComplete(mCall,
- new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- ));
+ verify(mCallback).onCallFilteringComplete(mCall, new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build());
}
private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart() {
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index ce874f4..2577631 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -148,7 +148,10 @@
com.android.internal.R.string.config_defaultDialer);
doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
doReturn(true).when(mMockResources).getBoolean(R.bool.grant_location_permission_enabled);
- mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, SYS_PKG,
+ when(mDefaultDialerCache.getSystemDialerApplication()).thenReturn(SYS_PKG);
+ when(mDefaultDialerCache.getSystemDialerComponent()).thenReturn(
+ new ComponentName(SYS_PKG, SYS_CLASS));
+ mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, mDefaultDialerCache,
mTimeoutsAdapter);
when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
index 76341b2..8e2d11e 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -17,17 +17,17 @@
package com.android.server.telecom.tests;
import android.content.ContentResolver;
-import android.content.IContentProvider;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
-import android.provider.CallLog;
+import android.provider.CallLog.Calls;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.Call;
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
+import com.android.server.telecom.callfiltering.CallFilteringResult.Builder;
import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.TelecomSystem;
@@ -68,46 +68,47 @@
private static final long SHORT_TIMEOUT = 100;
private static final CallFilteringResult PASS_CALL_RESULT =
- new CallFilteringResult(
- true, // shouldAllowCall
- false, // shouldReject
- true, // shouldAddToCallLog
- true // shouldShowNotification
- );
+ new Builder()
+ .setShouldAllowCall(true)
+ .setShouldReject(false)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .build();
private static final CallFilteringResult ASYNC_BLOCK_CHECK_BLOCK_RESULT =
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- false, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
- null, //callScreeningAppName
- null //callScreeningComponentName
- );
+ new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(false)
+ .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build();
private static final CallFilteringResult DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT =
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- true, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
- null, //callScreeningAppName
- null //callScreeningComponentName
- );
+ new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(true)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build();
private static final CallFilteringResult CALL_SCREENING_SERVICE_BLOCK_RESULT =
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- "com.android.thirdparty", //callScreeningAppName
- "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
- //callScreeningComponentName
- );
+ new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName("com.android.thirdparty")
+ .setCallScreeningComponentName(
+ "com.android.thirdparty/"
+ + "com.android.thirdparty.callscreeningserviceimpl")
+ .build();
private static final CallFilteringResult DEFAULT_RESULT = PASS_CALL_RESULT;
private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -207,16 +208,15 @@
testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- false, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_BLOCKED_NUMBER, //callBlockReason
- null, //callScreeningAppName
- null //callScreeningComponentName
- )));
+ verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(false)
+ .setCallBlockReason(Calls.BLOCK_REASON_BLOCKED_NUMBER)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build()));
}
@SmallTest
@@ -239,16 +239,15 @@
testFilter.onCallFilteringComplete(mCall, DIRECT_TO_VOICEMAIL_CALL_BLOCK_RESULT);
testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL, //callBlockReason
- null, ////callScreeningAppName
- null ////callScreeningComponentName
- )));
+ verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_DIRECT_TO_VOICEMAIL)
+ .setCallScreeningAppName(null)
+ .setCallScreeningComponentName(null)
+ .build()));
}
@SmallTest
@@ -268,17 +267,16 @@
testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
testFilter.onCallFilteringComplete(mCall, CALL_SCREENING_SERVICE_BLOCK_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
- verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(
- new CallFilteringResult(
- false, // shouldAllowCall
- true, // shouldReject
- false, // shouldAddToCallLog
- true, // shouldShowNotification
- CallLog.Calls.BLOCK_REASON_CALL_SCREENING_SERVICE, //callBlockReason
- "com.android.thirdparty", //callScreeningAppName
- "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl"
- //callScreeningComponentName
- )));
+ verify(mResultCallback).onCallFilteringComplete(eq(mCall), eq(new Builder()
+ .setShouldAllowCall(false)
+ .setShouldReject(true)
+ .setShouldAddToCallLog(false)
+ .setShouldShowNotification(true)
+ .setCallBlockReason(Calls.BLOCK_REASON_CALL_SCREENING_SERVICE)
+ .setCallScreeningAppName("com.android.thirdparty")
+ .setCallScreeningComponentName(
+ "com.android.thirdparty/com.android.thirdparty.callscreeningserviceimpl")
+ .build()));
}
@SmallTest
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 54fc89c..3438802 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -38,7 +38,6 @@
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -54,6 +53,7 @@
import com.android.server.telecom.Call;
import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.NewOutgoingCallIntentBroadcaster;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneNumberUtilsAdapter;
@@ -89,15 +89,14 @@
@Mock private PhoneAccount mPhoneAccount;
@Mock private PhoneAccountRegistrar mPhoneAccountRegistrar;
@Mock private RoleManagerAdapter mRoleManagerAdapter;
+ @Mock private DefaultDialerCache mDefaultDialerCache;
- private PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapterSpy;
+ private PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new PhoneNumberUtilsAdapterImpl();
@Override
@Before
public void setUp() throws Exception {
super.setUp();
- mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
- mPhoneNumberUtilsAdapterSpy = spy(new PhoneNumberUtilsAdapterImpl());
when(mCall.getInitiatingUser()).thenReturn(UserHandle.CURRENT);
when(mCallsManager.getLock()).thenReturn(new TelecomSystem.SyncRoot() { });
when(mCallsManager.getSystemStateHelper()).thenReturn(mSystemStateHelper);
@@ -217,8 +216,8 @@
@Test
public void testEmergencyCallWithNonDefaultDialer() {
Uri handle = Uri.parse("tel:6505551911");
- doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber(
- any(Context.class), eq(handle.getSchemeSpecificPart()));
+ doReturn(true).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(eq(handle.getSchemeSpecificPart()));
Intent intent = new Intent(Intent.ACTION_CALL, handle);
String ui_package_string = "sample_string_1";
@@ -227,6 +226,9 @@
ui_package_string);
mComponentContextFixture.putResource(R.string.dialer_default_class,
dialer_default_class_string);
+ when(mDefaultDialerCache.getSystemDialerApplication()).thenReturn(ui_package_string);
+ when(mDefaultDialerCache.getSystemDialerComponent()).thenReturn(
+ new ComponentName(ui_package_string, dialer_default_class_string));
int result = processIntent(intent, false).disconnectCause;
@@ -285,8 +287,8 @@
@Test
public void testActionEmergencyWithNonEmergencyNumber() {
Uri handle = Uri.parse("tel:6505551911");
- doReturn(false).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber(
- any(Context.class), eq(handle.getSchemeSpecificPart()));
+ doReturn(false).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(eq(handle.getSchemeSpecificPart()));
Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY, handle);
int result = processIntent(intent, true).disconnectCause;
@@ -299,8 +301,8 @@
Uri handle = intent.getData();
int videoState = VideoProfile.STATE_BIDIRECTIONAL;
boolean isSpeakerphoneOn = true;
- doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber(
- any(Context.class), eq(handle.getSchemeSpecificPart()));
+ doReturn(true).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(eq(handle.getSchemeSpecificPart()));
intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, isSpeakerphoneOn);
intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
@@ -421,8 +423,8 @@
String newEmergencyNumber = "1234567890";
result.receiver.setResultData(newEmergencyNumber);
- doReturn(true).when(mPhoneNumberUtilsAdapterSpy).isPotentialLocalEmergencyNumber(
- any(Context.class), eq(newEmergencyNumber));
+ doReturn(true).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(eq(newEmergencyNumber));
result.receiver.onReceive(mContext, result.intent);
verify(mCall).disconnect(eq(0L));
}
@@ -458,8 +460,8 @@
private NewOutgoingCallIntentBroadcaster.CallDisposition processIntent(Intent intent,
boolean isDefaultPhoneApp) {
NewOutgoingCallIntentBroadcaster b = new NewOutgoingCallIntentBroadcaster(
- mContext, mCallsManager, mCall, intent, mPhoneNumberUtilsAdapterSpy,
- isDefaultPhoneApp);
+ mContext, mCallsManager, mCall, intent, mPhoneNumberUtilsAdapter,
+ isDefaultPhoneApp, mDefaultDialerCache);
NewOutgoingCallIntentBroadcaster.CallDisposition cd = b.evaluateCall();
if (cd.disconnectCause == DisconnectCause.NOT_DISCONNECTED) {
b.processCall(cd);
diff --git a/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java b/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
index 3f0216f..7104e3a 100644
--- a/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
+++ b/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
@@ -61,9 +61,10 @@
when(mCallsManager.getCallerInfoLookupHelper()).thenReturn(mCallerInfoLookupHelper);
when(mCallsManager.getPhoneAccountRegistrar()).thenReturn(mPhoneAccountRegistrar);
when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(any())).thenReturn(null);
- when(mPhoneNumberUtilsAdapter.isLocalEmergencyNumber(any(), any())).thenReturn(false);
+ when(mComponentContextFixture.getTelephonyManager().isEmergencyNumber(any()))
+ .thenReturn(false);
mCall = new Call("1",
- null /* context */,
+ mContext /* context */,
mCallsManager,
mLock,
null /* ConnectionServiceRepository */,
diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
index a978cfd..e9efacd 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -69,6 +69,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -153,6 +154,68 @@
assertPhoneAccountEquals(input, result);
}
+ @SmallTest
+ @Test
+ public void testFilterPhoneAccountForTest() throws Exception {
+ ComponentName componentA = new ComponentName("a", "a");
+ ComponentName componentB1 = new ComponentName("b", "b1");
+ ComponentName componentB2 = new ComponentName("b", "b2");
+ ComponentName componentC = new ComponentName("c", "c");
+
+ PhoneAccount simAccountA = new PhoneAccount.Builder(
+ makeQuickAccountHandle(componentA, "1"), "1")
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setIsEnabled(true)
+ .build();
+
+ List<PhoneAccount> accountAList = new ArrayList<>();
+ accountAList.add(simAccountA);
+
+ PhoneAccount simAccountB1 = new PhoneAccount.Builder(
+ makeQuickAccountHandle(componentB1, "2"), "2")
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setIsEnabled(true)
+ .build();
+
+ PhoneAccount simAccountB2 = new PhoneAccount.Builder(
+ makeQuickAccountHandle(componentB2, "3"), "3")
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setIsEnabled(true)
+ .build();
+
+ List<PhoneAccount> accountBList = new ArrayList<>();
+ accountBList.add(simAccountB1);
+ accountBList.add(simAccountB2);
+
+ PhoneAccount simAccountC = new PhoneAccount.Builder(
+ makeQuickAccountHandle(componentC, "4"), "4")
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setIsEnabled(true)
+ .build();
+
+ List<PhoneAccount> accountCList = new ArrayList<>();
+ accountCList.add(simAccountC);
+
+ List<PhoneAccount> allAccounts = new ArrayList<>();
+ allAccounts.addAll(accountAList);
+ allAccounts.addAll(accountBList);
+ allAccounts.addAll(accountCList);
+
+ assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
+
+ mRegistrar.setTestPhoneAccountPackageNameFilter(componentA.getPackageName());
+ assertEquals(accountAList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
+
+ mRegistrar.setTestPhoneAccountPackageNameFilter(componentB1.getPackageName());
+ assertEquals(accountBList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
+
+ mRegistrar.setTestPhoneAccountPackageNameFilter(componentC.getPackageName());
+ assertEquals(accountCList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
+
+ mRegistrar.setTestPhoneAccountPackageNameFilter(null);
+ assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
+ }
+
@MediumTest
@Test
public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 9b89a03..4fc9ed6 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -78,6 +78,7 @@
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ContactsAsyncHelper;
+import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.HeadsetMediaButton;
import com.android.server.telecom.HeadsetMediaButtonFactory;
import com.android.server.telecom.InCallWakeLockController;
@@ -183,18 +184,6 @@
}
MissedCallNotifierFakeImpl mMissedCallNotifier = new MissedCallNotifierFakeImpl();
- private class EmergencyNumberUtilsAdapter extends PhoneNumberUtilsAdapterImpl {
-
- @Override
- public boolean isLocalEmergencyNumber(Context context, String number) {
- return mIsEmergencyCall;
- }
-
- @Override
- public boolean isPotentialLocalEmergencyNumber(Context context, String number) {
- return mIsEmergencyCall;
- }
- }
private class IncomingCallAddedListener extends CallsManagerListenerBase {
@@ -210,8 +199,6 @@
}
}
- PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
-
@Mock HeadsetMediaButton mHeadsetMediaButton;
@Mock ProximitySensorManager mProximitySensorManager;
@Mock InCallWakeLockController mInCallWakeLockController;
@@ -344,8 +331,6 @@
private int mNumOutgoingCallsMade;
- private boolean mIsEmergencyCall;
-
class IdPair {
final String mConnectionId;
final String mCallId;
@@ -368,7 +353,10 @@
mNumOutgoingCallsMade = 0;
- mIsEmergencyCall = false;
+ doReturn(false).when(mComponentContextFixture.getTelephonyManager())
+ .isEmergencyNumber(any());
+ doReturn(false).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(any());
// First set up information about the In-Call services in the mock Context, since
// Telecom will search for these as soon as it is instantiated
@@ -492,7 +480,7 @@
mConnServFMFactory,
mTimeoutsAdapter,
mAsyncRingtonePlayer,
- mPhoneNumberUtilsAdapter,
+ new PhoneNumberUtilsAdapterImpl(),
mIncomingCallNotifier,
(streamType, volume) -> mToneGenerator,
new CallAudioRouteStateMachine.Factory() {
@@ -712,7 +700,11 @@
int startingNumConnections = connectionServiceFixture.mConnectionById.size();
int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
- mIsEmergencyCall = true;
+ doReturn(true).when(mComponentContextFixture.getTelephonyManager())
+ .isEmergencyNumber(any());
+ doReturn(true).when(mComponentContextFixture.getTelephonyManager())
+ .isPotentialEmergencyNumber(any());
+
// Call will not use the ordered broadcaster, since it is an Emergency Call
startOutgoingPhoneCallWaitForBroadcaster(number, phoneAccountHandle,
connectionServiceFixture, initiatingUser, videoState, true /*isEmergency*/);