Merge "Fix issue where conference gets logged when no CEP is enabled."
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 ecc6359..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;
@@ -431,6 +439,7 @@
private boolean mWasConferencePreviouslyMerged = false;
private boolean mWasHighDefAudio = false;
+ private boolean mWasWifi = false;
// For conferences which support merge/swap at their level, we retain a notion of an active
// call. This is used for BluetoothPhoneService. In order to support hold/merge, it must have
@@ -1072,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);
@@ -1083,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;
}
@@ -1143,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() {
@@ -1565,12 +1594,12 @@
getInCallToCsRttPipeForCs(), getCsToInCallRttPipeForCs());
mWasEverRtt = true;
if (isEmergencyCall()) {
- mCallsManager.setAudioRoute(CallAudioState.ROUTE_SPEAKER, null);
mCallsManager.mute(false);
}
}
mWasHighDefAudio = (connectionProperties & Connection.PROPERTY_HIGH_DEF_AUDIO) ==
Connection.PROPERTY_HIGH_DEF_AUDIO;
+ mWasWifi = (connectionProperties & Connection.PROPERTY_WIFI) > 0;
for (Listener l : mListeners) {
l.onConnectionPropertiesChanged(this, didRttChange);
}
@@ -3162,6 +3191,10 @@
}
}
+ private TelephonyManager getTelephonyManager() {
+ return mContext.getSystemService(TelephonyManager.class);
+ }
+
/**
* Sets whether this {@link Call} is a conference or not.
* @param isConference
@@ -3201,6 +3234,15 @@
return mWasHighDefAudio;
}
+ /**
+ * Returns wether or not Wifi call was used.
+ *
+ * @return true if wifi call was used during this call.
+ */
+ boolean wasWifi() {
+ return mWasWifi;
+ }
+
public void setIsUsingCallFiltering(boolean isUsingCallFiltering) {
mIsUsingCallFiltering = isUsingCallFiltering;
}
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 42a1d36..06be216 100644
--- a/src/com/android/server/telecom/CallAudioModeStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioModeStateMachine.java
@@ -17,6 +17,7 @@
package com.android.server.telecom;
import android.media.AudioManager;
+import android.os.Looper;
import android.os.Message;
import android.telecom.Log;
import android.telecom.Logging.Runnable;
@@ -40,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;
@@ -101,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");
@@ -119,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();
@@ -139,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;
@@ -160,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);
@@ -184,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);
@@ -192,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"
@@ -249,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.");
@@ -310,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
@@ -323,23 +458,38 @@
// 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:
- // Do nothing.
+ if (args.foregroundCallIsVoip) {
+ transitionTo(mVoipCallFocusState);
+ }
return HANDLED;
case NEW_ACTIVE_OR_DIALING_CALL:
- // Do nothing. Already active.
+ if (args.foregroundCallIsVoip) {
+ transitionTo(mVoipCallFocusState);
+ }
return HANDLED;
case NEW_RINGING_CALL:
// Don't make a call ring over an active call, but do play a call waiting tone.
mCallAudioManager.startCallWaiting("call already active");
return HANDLED;
case NEW_HOLDING_CALL:
- // Don't do anything now. Putting an active call on hold will be handled when
+ // Just check the voip mode. Putting an active call on hold will be handled when
// NO_MORE_ACTIVE_CALLS is processed.
+ if (args.foregroundCallIsVoip) {
+ 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);
@@ -372,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
@@ -382,19 +532,34 @@
}
return HANDLED;
case NO_MORE_HOLDING_CALLS:
- // Do nothing.
+ if (!args.foregroundCallIsVoip) {
+ transitionTo(mSimCallFocusState);
+ }
return HANDLED;
case NEW_ACTIVE_OR_DIALING_CALL:
- // Do nothing. Already active.
+ if (!args.foregroundCallIsVoip) {
+ transitionTo(mSimCallFocusState);
+ }
return HANDLED;
case NEW_RINGING_CALL:
// Don't make a call ring over an active call, but do play a call waiting tone.
mCallAudioManager.startCallWaiting("call already active");
return HANDLED;
case NEW_HOLDING_CALL:
- // Don't do anything now. Putting an active call on hold will be handled when
+ // Just check the voip mode. Putting an active call on hold will be handled when
// NO_MORE_ACTIVE_CALLS is processed.
+ if (!args.foregroundCallIsVoip) {
+ 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);
@@ -461,7 +626,7 @@
mCallAudioManager.stopCallWaiting();
return HANDLED;
case TONE_STOPPED_PLAYING:
- transitionTo(destinationStateAfterNoMoreActiveCalls(args));
+ transitionTo(calculateProperStateFromArgs(args));
default:
return NOT_HANDLED;
}
@@ -474,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;
@@ -490,14 +656,39 @@
mSystemStateHelper = systemStateHelper;
mMostRecentMode = AudioManager.MODE_NORMAL;
+ createStates();
+ }
+
+ /**
+ * Used for testing
+ */
+ public CallAudioModeStateMachine(SystemStateHelper systemStateHelper,
+ AudioManager audioManager, Looper looper) {
+ super(CallAudioModeStateMachine.class.getSimpleName(), looper);
+ mAudioManager = audioManager;
+ mSystemStateHelper = systemStateHelper;
+ mMostRecentMode = AudioManager.MODE_NORMAL;
+
+ createStates();
+ }
+
+ private void createStates() {
addState(mUnfocusedState);
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) {
@@ -537,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/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index dcf1b27..2e9917b 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -28,6 +28,7 @@
import android.media.AudioManager;
import android.media.IAudioService;
import android.os.Binder;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -1316,7 +1317,7 @@
private final WiredHeadsetManager mWiredHeadsetManager;
private final StatusBarNotifier mStatusBarNotifier;
private final CallAudioManager.AudioServiceFactory mAudioServiceFactory;
- private final boolean mDoesDeviceSupportEarpieceRoute;
+ private boolean mDoesDeviceSupportEarpieceRoute;
private final TelecomSystem.SyncRoot mLock;
private boolean mHasUserExplicitlyLeftBluetooth = false;
@@ -1339,16 +1340,6 @@
CallAudioManager.AudioServiceFactory audioServiceFactory,
int earpieceControl) {
super(NAME);
- addState(mActiveEarpieceRoute);
- addState(mActiveHeadsetRoute);
- addState(mActiveBluetoothRoute);
- addState(mActiveSpeakerRoute);
- addState(mRingingBluetoothRoute);
- addState(mQuiescentEarpieceRoute);
- addState(mQuiescentHeadsetRoute);
- addState(mQuiescentBluetoothRoute);
- addState(mQuiescentSpeakerRoute);
-
mContext = context;
mCallsManager = callsManager;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
@@ -1356,6 +1347,34 @@
mWiredHeadsetManager = wiredHeadsetManager;
mStatusBarNotifier = statusBarNotifier;
mAudioServiceFactory = audioServiceFactory;
+ mLock = callsManager.getLock();
+
+ createStates(earpieceControl);
+ }
+
+ /** Used for testing only */
+ public CallAudioRouteStateMachine(
+ Context context,
+ CallsManager callsManager,
+ BluetoothRouteManager bluetoothManager,
+ WiredHeadsetManager wiredHeadsetManager,
+ StatusBarNotifier statusBarNotifier,
+ CallAudioManager.AudioServiceFactory audioServiceFactory,
+ int earpieceControl, Looper looper) {
+ super(NAME, looper);
+ mContext = context;
+ mCallsManager = callsManager;
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ mBluetoothRouteManager = bluetoothManager;
+ mWiredHeadsetManager = wiredHeadsetManager;
+ mStatusBarNotifier = statusBarNotifier;
+ mAudioServiceFactory = audioServiceFactory;
+ mLock = callsManager.getLock();
+
+ createStates(earpieceControl);
+ }
+
+ private void createStates(int earpieceControl) {
switch (earpieceControl) {
case EARPIECE_FORCE_DISABLED:
mDoesDeviceSupportEarpieceRoute = false;
@@ -1366,7 +1385,17 @@
default:
mDoesDeviceSupportEarpieceRoute = checkForEarpieceSupport();
}
- mLock = callsManager.getLock();
+
+ addState(mActiveEarpieceRoute);
+ addState(mActiveHeadsetRoute);
+ addState(mActiveBluetoothRoute);
+ addState(mActiveSpeakerRoute);
+ addState(mRingingBluetoothRoute);
+ addState(mQuiescentEarpieceRoute);
+ addState(mQuiescentHeadsetRoute);
+ addState(mQuiescentBluetoothRoute);
+ addState(mQuiescentSpeakerRoute);
+
mStateNameToRouteCode = new HashMap<>(8);
mStateNameToRouteCode.put(mQuiescentEarpieceRoute.getName(), ROUTE_EARPIECE);
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/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index b1b2058..d42c6b5 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -333,7 +333,7 @@
int callFeatures = getCallFeatures(call.getVideoStateHistory(),
call.getDisconnectCause().getCode() == DisconnectCause.CALL_PULLED,
- shouldSaveHdInfo(call, accountHandle),
+ call.wasHighDefAudio(), call.wasWifi(),
(call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING_USED) ==
Connection.PROPERTY_ASSISTED_DIALING_USED,
call.wasEverRttCall());
@@ -456,11 +456,12 @@
* @param videoState The video state.
* @param isPulledCall {@code true} if this call was pulled to another device.
* @param isStoreHd {@code true} if this call was used HD.
+ * @param isWifi {@code true} if this call was used wifi.
* @param isUsingAssistedDialing {@code true} if this call used assisted dialing.
* @return The call features.
*/
private static int getCallFeatures(int videoState, boolean isPulledCall, boolean isStoreHd,
- boolean isUsingAssistedDialing, boolean isRtt) {
+ boolean isWifi, boolean isUsingAssistedDialing, boolean isRtt) {
int features = 0;
if (VideoProfile.isVideo(videoState)) {
features |= Calls.FEATURES_VIDEO;
@@ -471,6 +472,9 @@
if (isStoreHd) {
features |= Calls.FEATURES_HD_CALL;
}
+ if (isWifi) {
+ features |= Calls.FEATURES_WIFI;
+ }
if (isUsingAssistedDialing) {
features |= Calls.FEATURES_ASSISTED_DIALING_USED;
}
@@ -480,22 +484,6 @@
return features;
}
- private boolean shouldSaveHdInfo(Call call, PhoneAccountHandle accountHandle) {
- CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
- Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle configBundle = null;
- if (configManager != null) {
- configBundle = configManager.getConfigForSubId(
- mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(accountHandle));
- }
- if (configBundle != null && configBundle.getBoolean(
- CarrierConfigManager.KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL)
- && call.wasHighDefAudio()) {
- return true;
- }
- return false;
- }
-
/**
* Retrieve the phone number from the call, and then process it before returning the
* actual number that is to be logged.
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 2bd403c..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;
@@ -312,6 +314,7 @@
private final MissedCallNotifier mMissedCallNotifier;
private IncomingCallNotifier mIncomingCallNotifier;
private final CallerInfoLookupHelper mCallerInfoLookupHelper;
+ private final IncomingCallFilter.Factory mIncomingCallFilterFactory;
private final DefaultDialerCache mDefaultDialerCache;
private final Timeouts.Adapter mTimeoutsAdapter;
private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
@@ -434,7 +437,8 @@
CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
InCallControllerFactory inCallControllerFactory,
- RoleManagerAdapter roleManagerAdapter) {
+ RoleManagerAdapter roleManagerAdapter,
+ IncomingCallFilter.Factory incomingCallFilterFactory) {
mContext = context;
mLock = lock;
mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
@@ -450,6 +454,7 @@
mTimeoutsAdapter = timeoutsAdapter;
mEmergencyCallHelper = emergencyCallHelper;
mCallerInfoLookupHelper = callerInfoLookupHelper;
+ mIncomingCallFilterFactory = incomingCallFilterFactory;
mDtmfLocalTonePlayer =
new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
@@ -605,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;
}
@@ -632,7 +642,7 @@
return null;
}
}));
- new IncomingCallFilter(mContext, this, incomingCall, mLock,
+ mIncomingCallFilterFactory.create(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}
@@ -1029,7 +1039,8 @@
mListeners.add(listener);
}
- void removeListener(CallsManagerListener listener) {
+ @VisibleForTesting
+ public void removeListener(CallsManagerListener listener) {
mListeners.remove(listener);
}
@@ -1099,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.
@@ -1532,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
@@ -1619,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
*/
@@ -1749,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());
@@ -2221,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.
@@ -2248,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.
@@ -2299,11 +2316,6 @@
* speaker phone.
*/
void setAudioRoute(int route, String bluetoothAddress) {
- if (hasEmergencyRttCall() && route != CallAudioState.ROUTE_SPEAKER) {
- Log.i(this, "In an emergency RTT call. Forcing route to speaker.");
- route = CallAudioState.ROUTE_SPEAKER;
- bluetoothAddress = null;
- }
mCallAudioManager.setAudioRoute(route, bluetoothAddress);
}
@@ -2321,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/ContactsAsyncHelper.java b/src/com/android/server/telecom/ContactsAsyncHelper.java
index 7fb6419..37ee941 100644
--- a/src/com/android/server/telecom/ContactsAsyncHelper.java
+++ b/src/com/android/server/telecom/ContactsAsyncHelper.java
@@ -40,6 +40,12 @@
public class ContactsAsyncHelper {
private static final String LOG_TAG = ContactsAsyncHelper.class.getSimpleName();
+ public static class Factory {
+ public ContactsAsyncHelper create(ContentResolverAdapter adapter) {
+ return new ContactsAsyncHelper(adapter);
+ }
+ }
+
/**
* Interface for a WorkerHandler result return.
*/
@@ -77,6 +83,11 @@
mContentResolverAdapter = contentResolverAdapter;
}
+ public ContactsAsyncHelper(ContentResolverAdapter contentResolverAdapter, Looper looper) {
+ mContentResolverAdapter = contentResolverAdapter;
+ mThreadHandler = new WorkerHandler(looper);
+ }
+
private static final class WorkerArgs {
public Context context;
public Uri displayPhotoUri;
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 2e3ee8d..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;
@@ -731,6 +728,7 @@
private final Timeouts.Adapter mTimeoutsAdapter;
private final DefaultDialerCache mDefaultDialerCache;
private final EmergencyCallHelper mEmergencyCallHelper;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
private CarSwappingInCallServiceConnection mInCallServiceConnection;
private NonUIInCallServiceConnectionCollection mNonUIInCallServiceConnections;
@@ -750,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);
}
@@ -817,8 +810,7 @@
/** Let's add a 2 second delay before we send unbind to the services to hopefully
* give them enough time to process all the pending messages.
*/
- Handler handler = new Handler(Looper.getMainLooper());
- handler.postDelayed(new Runnable("ICC.oCR", mLock) {
+ mHandler.postDelayed(new Runnable("ICC.oCR", mLock) {
@Override
public void loggedRun() {
// Check again to make sure there are no active calls.
@@ -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;
}
@@ -1597,4 +1591,9 @@
childCalls.addAll(parentCalls);
return childCalls;
}
+
+ @VisibleForTesting
+ public Handler getHandler() {
+ return mHandler;
+ }
}
diff --git a/src/com/android/server/telecom/InCallTonePlayer.java b/src/com/android/server/telecom/InCallTonePlayer.java
index 5864ce0..4f0cf8d 100644
--- a/src/com/android/server/telecom/InCallTonePlayer.java
+++ b/src/com/android/server/telecom/InCallTonePlayer.java
@@ -502,7 +502,7 @@
public void loggedRun() {
if (sTonesPlaying == 0) {
Log.wtf(this, "Over-releasing focus for tone player.");
- } else if (--sTonesPlaying == 0) {
+ } else if (--sTonesPlaying == 0 && mCallAudioManager != null) {
mCallAudioManager.setIsTonePlaying(false);
}
}
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 8bf42a8..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;
@@ -581,28 +580,28 @@
public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
try {
Log.startSession("TSI.gVMN");
- synchronized (mLock) {
- if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
+ if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
+ return null;
+ }
+ try {
+ final UserHandle callingUserHandle = Binder.getCallingUserHandle();
+ if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
+ callingUserHandle)) {
+ Log.d(this, "%s is not visible for the calling user [gVMN]",
+ accountHandle);
return null;
}
- try {
- final UserHandle callingUserHandle = Binder.getCallingUserHandle();
- if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
- callingUserHandle)) {
- Log.d(this, "%s is not visible for the calling user [gVMN]",
- accountHandle);
- return null;
- }
- int subId = mSubscriptionManagerAdapter.getDefaultVoiceSubId();
+ int subId = mSubscriptionManagerAdapter.getDefaultVoiceSubId();
+ synchronized (mLock) {
if (accountHandle != null) {
subId = mPhoneAccountRegistrar
.getSubscriptionIdForPhoneAccount(accountHandle);
}
- return getTelephonyManager().getVoiceMailNumber(subId);
- } catch (Exception e) {
- Log.e(this, e, "getSubscriptionIdForPhoneAccount");
- throw e;
}
+ return getTelephonyManager().getVoiceMailNumber(subId);
+ } catch (Exception e) {
+ Log.e(this, e, "getSubscriptionIdForPhoneAccount");
+ throw e;
}
} finally {
Log.endSession();
@@ -620,25 +619,26 @@
return null;
}
- synchronized (mLock) {
- final UserHandle callingUserHandle = Binder.getCallingUserHandle();
- if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
- callingUserHandle)) {
- Log.d(this, "%s is not visible for the calling user [gL1N]", accountHandle);
- return null;
- }
+ final UserHandle callingUserHandle = Binder.getCallingUserHandle();
+ if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
+ callingUserHandle)) {
+ Log.d(this, "%s is not visible for the calling user [gL1N]", accountHandle);
+ return null;
+ }
- long token = Binder.clearCallingIdentity();
- try {
- int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
+ long token = Binder.clearCallingIdentity();
+ try {
+ int subId;
+ synchronized (mLock) {
+ subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
accountHandle);
- return getTelephonyManager().getLine1Number(subId);
- } catch (Exception e) {
- Log.e(this, e, "getSubscriptionIdForPhoneAccount");
- throw e;
- } finally {
- Binder.restoreCallingIdentity(token);
}
+ return getTelephonyManager().getLine1Number(subId);
+ } catch (Exception e) {
+ Log.e(this, e, "getSubscriptionIdForPhoneAccount");
+ throw e;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
} finally {
Log.endSession();
@@ -678,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();
}
@@ -717,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();
}
@@ -929,21 +943,19 @@
public boolean handlePinMmi(String dialString, String callingPackage) {
try {
Log.startSession("TSI.hPM");
- synchronized (mLock) {
- enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
+ enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
- // Switch identity so that TelephonyManager checks Telecom's permissions
- // instead.
- long token = Binder.clearCallingIdentity();
- boolean retval = false;
- try {
- retval = getTelephonyManager().handlePinMmi(dialString);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- return retval;
+ // Switch identity so that TelephonyManager checks Telecom's permissions
+ // instead.
+ long token = Binder.clearCallingIdentity();
+ boolean retval = false;
+ try {
+ retval = getTelephonyManager().handlePinMmi(dialString);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
+
+ return retval;
}finally {
Log.endSession();
}
@@ -957,29 +969,33 @@
String dialString, String callingPackage) {
try {
Log.startSession("TSI.hPMFPA");
- synchronized (mLock) {
- enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
- UserHandle callingUserHandle = Binder.getCallingUserHandle();
+ enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
+ UserHandle callingUserHandle = Binder.getCallingUserHandle();
+ synchronized (mLock) {
if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
callingUserHandle)) {
- Log.d(this, "%s is not visible for the calling user [hMMI]", accountHandle);
+ Log.d(this, "%s is not visible for the calling user [hMMI]",
+ accountHandle);
return false;
}
-
- // Switch identity so that TelephonyManager checks Telecom's permissions
- // instead.
- long token = Binder.clearCallingIdentity();
- boolean retval = false;
- try {
- int subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
- accountHandle);
- retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- return retval;
}
+
+ // Switch identity so that TelephonyManager checks Telecom's permissions
+ // instead.
+ long token = Binder.clearCallingIdentity();
+ boolean retval = false;
+ int subId;
+ try {
+ synchronized (mLock) {
+ subId = mPhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(
+ accountHandle);
+ }
+ retval = getTelephonyManager().handlePinMmiForSubscriber(subId, dialString);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return retval;
}finally {
Log.endSession();
}
@@ -993,28 +1009,28 @@
String callingPackage) {
try {
Log.startSession("TSI.aAUFPA");
+ enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
synchronized (mLock) {
- enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
if (!isPhoneAccountHandleVisibleToCallingUser(accountHandle,
Binder.getCallingUserHandle())) {
Log.d(this, "%s is not visible for the calling user [gA4PA]",
accountHandle);
return null;
}
- // Switch identity so that TelephonyManager checks Telecom's permissions
- // instead.
- long token = Binder.clearCallingIdentity();
- String retval = "content://icc/adn/";
- try {
- long subId = mPhoneAccountRegistrar
- .getSubscriptionIdForPhoneAccount(accountHandle);
- retval = retval + "subId/" + subId;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- return Uri.parse(retval);
}
+ // Switch identity so that TelephonyManager checks Telecom's permissions
+ // instead.
+ long token = Binder.clearCallingIdentity();
+ String retval = "content://icc/adn/";
+ try {
+ long subId = mPhoneAccountRegistrar
+ .getSubscriptionIdForPhoneAccount(accountHandle);
+ retval = retval + "subId/" + subId;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+
+ return Uri.parse(retval);
} finally {
Log.endSession();
}
@@ -1376,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, " ");
@@ -1480,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()}
*/
@@ -1504,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) {
@@ -1518,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);
}
@@ -1743,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;
}
@@ -1757,7 +1792,10 @@
private boolean isPhoneAccountHandleVisibleToCallingUser(
PhoneAccountHandle phoneAccountUserHandle, UserHandle callingUser) {
- return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser) != null;
+ synchronized (mLock) {
+ return mPhoneAccountRegistrar.getPhoneAccount(phoneAccountUserHandle, callingUser)
+ != null;
+ }
}
private boolean isCallerSystemApp() {
@@ -1932,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 e772eb4..f354b94 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -20,6 +20,7 @@
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
+import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.IncomingCallNotifier;
@@ -197,8 +198,11 @@
IncomingCallNotifier incomingCallNotifier,
InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
+ CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
ClockProxy clockProxy,
- RoleManagerAdapter roleManagerAdapter) {
+ RoleManagerAdapter roleManagerAdapter,
+ IncomingCallFilter.Factory incomingCallFilterFactory,
+ ContactsAsyncHelper.Factory contactsAsyncHelperFactory) {
mContext = context.getApplicationContext();
LogUtils.initLogging(mContext);
DefaultDialerManagerAdapter defaultDialerAdapter =
@@ -223,7 +227,7 @@
return null;
}
});
- mContactsAsyncHelper = new ContactsAsyncHelper(
+ mContactsAsyncHelper = contactsAsyncHelperFactory.create(
new ContactsAsyncHelper.ContentResolverAdapter() {
@Override
public InputStream openInputStream(Context context, Uri uri)
@@ -250,7 +254,7 @@
mContactsAsyncHelper, mLock);
EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
- TelecomServiceImpl.getSystemDialerPackage(mContext), timeoutsAdapter);
+ defaultDialerCache, timeoutsAdapter);
InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
@Override
@@ -286,9 +290,10 @@
clockProxy,
bluetoothStateReceiver,
callAudioRouteStateMachineFactory,
- new CallAudioModeStateMachine.Factory(),
+ callAudioModeStateMachineFactory,
inCallControllerFactory,
- roleManagerAdapter);
+ roleManagerAdapter,
+ incomingCallFilterFactory);
mIncomingCallNotifier = incomingCallNotifier;
incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
@@ -322,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);
@@ -335,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 1c947d1..860de1f 100644
--- a/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/IncomingCallFilter.java
@@ -27,36 +27,46 @@
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;
public class IncomingCallFilter implements CallFilterResultCallback {
+ public static class Factory {
+ public IncomingCallFilter create(Context context, CallFilterResultCallback listener,
+ Call call, TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
+ List<CallFilter> filters) {
+ return new IncomingCallFilter(context, listener, call, lock, timeoutsAdapter, filters,
+ new Handler(Looper.getMainLooper()));
+ }
+ }
+
public interface CallFilter {
void startFilterLookup(Call call, CallFilterResultCallback listener);
}
private final TelecomSystem.SyncRoot mTelecomLock;
private final Context mContext;
- private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Handler mHandler;
private final List<CallFilter> mFilters;
private final Call mCall;
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;
public IncomingCallFilter(Context context, CallFilterResultCallback listener, Call call,
TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
- List<CallFilter> filters) {
+ List<CallFilter> filters, Handler handler) {
mContext = context;
mListener = listener;
mCall = call;
@@ -64,6 +74,7 @@
mFilters = filters;
mNumPendingFilters = filters.size();
mTimeoutsAdapter = timeoutsAdapter;
+ mHandler = handler;
}
public void performFiltering() {
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index 956274a..0eab83f 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -24,7 +24,6 @@
import android.media.IAudioService;
import android.media.ToneGenerator;
import android.os.IBinder;
-import android.os.Looper;
import android.os.PowerManager;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -34,15 +33,16 @@
import com.android.server.telecom.AsyncRingtonePlayer;
import com.android.server.telecom.BluetoothAdapterProxy;
import com.android.server.telecom.BluetoothPhoneServiceImpl;
+import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallerInfoAsyncQueryFactory;
import com.android.server.telecom.CallsManager;
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.InCallTonePlayer;
import com.android.server.telecom.InCallWakeLockControllerFactory;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.PhoneAccountRegistrar;
@@ -51,11 +51,11 @@
import com.android.server.telecom.InCallWakeLockController;
import com.android.server.telecom.ProximitySensorManager;
import com.android.server.telecom.R;
-import com.android.server.telecom.RoleManagerAdapter;
import com.android.server.telecom.RoleManagerAdapterImpl;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.TelecomWakeLock;
import com.android.server.telecom.Timeouts;
+import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl;
import com.android.server.telecom.ui.NotificationChannelManager;
@@ -178,6 +178,7 @@
new IncomingCallNotifier(context),
ToneGenerator::new,
new CallAudioRouteStateMachine.Factory(),
+ new CallAudioModeStateMachine.Factory(),
new ClockProxy() {
@Override
public long currentTimeMillis() {
@@ -190,7 +191,9 @@
}
},
new RoleManagerAdapterImpl(context,
- (RoleManager) context.getSystemService(Context.ROLE_SERVICE))));
+ (RoleManager) context.getSystemService(Context.ROLE_SERVICE)),
+ new IncomingCallFilter.Factory(),
+ new ContactsAsyncHelper.Factory()));
}
if (BluetoothAdapter.getDefaultAdapter() != null) {
context.startService(new Intent(context, BluetoothPhoneService.class));
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/testapps/res/layout/testdialer_main.xml b/testapps/res/layout/testdialer_main.xml
index 9da3789..a9507c3 100644
--- a/testapps/res/layout/testdialer_main.xml
+++ b/testapps/res/layout/testdialer_main.xml
@@ -59,4 +59,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/startCallWithRtt"/>
+ <Button
+ android:id="@+id/toggle_car_mode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Toggle Car mode" />
+ <Button
+ android:id="@+id/toggle_incallservice"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Toggle InCallService" />
</LinearLayout>
diff --git a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
index c7eccf7..9aa076f 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestDialerActivity.java
@@ -1,9 +1,14 @@
package com.android.server.telecom.testapps;
+import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
+
import android.app.Activity;
+import android.app.UiModeManager;
+import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog.Calls;
@@ -56,6 +61,18 @@
mNumberView = (EditText) findViewById(R.id.number);
mRttCheckbox = (CheckBox) findViewById(R.id.call_with_rtt_checkbox);
+ findViewById(R.id.toggle_car_mode).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleCarMode();
+ }
+ });
+ findViewById(R.id.toggle_incallservice).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleInCallService();
+ }
+ });
updateMutableUi();
}
@@ -140,4 +157,29 @@
Log.i("Santos xtr", intentExtras.toString());
return intentExtras;
}
+
+ private void toggleCarMode() {
+ UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
+ boolean isCarMode = uiModeManager.getCurrentModeType() == UI_MODE_TYPE_CAR;
+ if (isCarMode) {
+ uiModeManager.disableCarMode(0);
+ } else {
+ uiModeManager.enableCarMode(0);
+ }
+ }
+
+ private void toggleInCallService() {
+ ComponentName uiComponent = new ComponentName(
+ TestInCallServiceImpl.class.getPackage().getName(),
+ TestInCallServiceImpl.class.getName());
+ boolean isEnabled = getPackageManager().getComponentEnabledSetting(uiComponent)
+ == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ getPackageManager().setComponentEnabledSetting(uiComponent,
+ isEnabled ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ isEnabled = getPackageManager().getComponentEnabledSetting(uiComponent)
+ == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ Toast.makeText(this, "Is UI enabled? " + isEnabled, Toast.LENGTH_LONG).show();
+ }
}
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 91ddf5a..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,7 +34,9 @@
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;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -60,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;
@@ -90,6 +91,12 @@
mCallerInfoLookupHelper, null);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testBlockNumber() {
diff --git a/tests/src/com/android/server/telecom/tests/BasicCallTests.java b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
index 95ca3f3..04f0e66 100644
--- a/tests/src/com/android/server/telecom/tests/BasicCallTests.java
+++ b/tests/src/com/android/server/telecom/tests/BasicCallTests.java
@@ -306,7 +306,8 @@
mTelecomSystem.getTelecomServiceImpl().getBinder()
.addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
ArgumentCaptor<ConnectionRequest> connectionRequestCaptor
= ArgumentCaptor.forClass(ConnectionRequest.class);
verify(mConnectionServiceFixtureA.getTestDouble())
@@ -333,15 +334,18 @@
String callId = startOutgoingPhoneCallWithNoPhoneAccount("650-555-1212",
mConnectionServiceFixtureA);
mTelecomSystem.getCallsManager().getLatestPreAccountSelectionFuture().join();
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT,
mInCallServiceFixtureX.getCall(callId).getState());
assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT,
mInCallServiceFixtureY.getCall(callId).getState());
mInCallServiceFixtureX.mInCallAdapter.phoneAccountSelected(callId,
mPhoneAccountA0.getAccountHandle(), false);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
verifyAndProcessOutgoingCallBroadcast(mPhoneAccountA0.getAccountHandle());
IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(),
@@ -366,12 +370,14 @@
mTelecomSystem.getTelecomServiceImpl().getBinder()
.addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
verify(mConnectionServiceFixtureA.getTestDouble())
.createConnection(any(PhoneAccountHandle.class), anyString(),
any(ConnectionRequest.class), eq(true), eq(false), any());
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
for (CallerInfoAsyncQueryFactoryFixture.Request request :
mCallerInfoAsyncQueryFactoryFixture.mRequests) {
@@ -411,12 +417,14 @@
mTelecomSystem.getTelecomServiceImpl().getBinder()
.addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
verify(mConnectionServiceFixtureA.getTestDouble())
.createConnection(any(PhoneAccountHandle.class), anyString(),
any(ConnectionRequest.class), eq(true), eq(false), any());
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
// Never reply to the caller info lookup.
assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
@@ -460,12 +468,14 @@
mTelecomSystem.getTelecomServiceImpl().getBinder()
.addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
verify(mConnectionServiceFixtureA.getTestDouble())
.createConnection(any(PhoneAccountHandle.class), anyString(),
any(ConnectionRequest.class), eq(true), eq(false), any());
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
for (CallerInfoAsyncQueryFactoryFixture.Request request :
mCallerInfoAsyncQueryFactoryFixture.mRequests) {
@@ -554,10 +564,12 @@
// TODO: We have to use the same PhoneAccount for both; see http://b/18461539
IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212",
mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323",
mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
verify(mConnectionServiceFixtureA.getTestDouble())
.hold(eq(outgoing.mConnectionId), any());
mConnectionServiceFixtureA.mConnectionById.get(outgoing.mConnectionId).state =
@@ -786,7 +798,8 @@
@Override
public Bundle answer(InvocationOnMock invocation) throws Throwable {
Bundle bundle = new Bundle();
- bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true);
+ bundle.putInt(BlockedNumberContract.RES_BLOCK_STATUS,
+ BlockedNumberContract.STATUS_BLOCKED_IN_LIST);
return bundle;
}
});
@@ -795,6 +808,7 @@
private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception {
when(getBlockedNumberProvider().call(
anyString(),
+ anyString(),
eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
eq(phoneNumber),
nullable(Bundle.class))).thenAnswer(answer);
@@ -1051,7 +1065,8 @@
// Route self-managed call to speaker.
connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mConnectionServiceFixtureA.mConnectionServiceDelegate.getHandler(),
+ TEST_TIMEOUT);
// Place an emergency call.
startAndMakeDialingEmergencyCall("650-555-1212", mPhoneAccountE0.getAccountHandle(),
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
index 2129ffa..63ff962 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothDeviceManagerTest.java
@@ -31,6 +31,7 @@
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -96,6 +97,12 @@
mBluetoothDeviceManager.setHearingAidServiceForTesting(mBluetoothHearingAid);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testSingleDeviceConnectAndDisconnect() {
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
index 93c2909..b20ecfb 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
@@ -31,6 +31,7 @@
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,6 +72,12 @@
super.setUp();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testConnectHfpRetryWhileNotConnected() {
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
index 2584f33..8ba6b63 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
@@ -30,6 +30,7 @@
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -246,6 +247,12 @@
super.setUp();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
public BluetoothRouteTransitionTests(BluetoothRouteTestParameters params) {
mParams = params;
}
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java b/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
index 01add22..3251d7d 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioManagerTest.java
@@ -19,20 +19,24 @@
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;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -45,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;
@@ -92,17 +99,22 @@
mDtmfLocalTonePlayer);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@MediumTest
@Test
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);
@@ -110,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());
@@ -160,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);
@@ -172,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());
@@ -196,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(
@@ -209,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);
@@ -233,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);
@@ -278,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);
@@ -290,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;
}
@@ -313,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());
@@ -333,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());
@@ -355,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 56f585f..ca84c4c 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
@@ -17,13 +17,16 @@
package com.android.server.telecom.tests;
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.CallAudioRouteStateMachine;
+import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.SystemStateHelper;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,17 +50,29 @@
@Mock private AudioManager mAudioManager;
@Mock private CallAudioManager mCallAudioManager;
+ private HandlerThread mTestThread;
+
@Override
@Before
public void setUp() throws Exception {
+ mTestThread = new HandlerThread("CallAudioModeStateMachineTest");
+ mTestThread.start();
super.setUp();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ mTestThread.quit();
+ mTestThread.join();
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testNoFocusWhenRingerSilenced() throws Throwable {
CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mSystemStateHelper,
- mAudioManager);
+ mAudioManager, mTestThread.getLooper());
sm.setCallAudioManager(mCallAudioManager);
sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
@@ -65,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());
@@ -90,32 +104,30 @@
@Test
public void testNoRingWhenDeviceIsAtEar() {
CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mSystemStateHelper,
- mAudioManager);
+ 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());
@@ -128,7 +140,7 @@
@Test
public void testRegainFocusWhenHfpIsConnectedSilenced() throws Throwable {
CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mSystemStateHelper,
- mAudioManager);
+ mAudioManager, mTestThread.getLooper());
sm.setCallAudioManager(mCallAudioManager);
sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
@@ -136,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 81339ed..2047867 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioModeTransitionTests.java
@@ -16,14 +16,16 @@
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;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -102,13 +104,24 @@
@Mock private AudioManager mAudioManager;
@Mock private CallAudioManager mCallAudioManager;
private final ModeTestParameters mParams;
+ private HandlerThread mTestThread;
@Override
@Before
public void setUp() throws Exception {
+ mTestThread = new HandlerThread("CallAudioModeStateMachineTest");
+ mTestThread.start();
super.setUp();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ mTestThread.quit();
+ mTestThread.join();
+ super.tearDown();
+ }
+
public CallAudioModeTransitionTests(ModeTestParameters params) {
mParams = params;
}
@@ -117,7 +130,7 @@
@SmallTest
public void modeTransitionTest() {
CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mSystemStateHelper,
- mAudioManager);
+ mAudioManager, mTestThread.getLooper());
sm.setCallAudioManager(mCallAudioManager);
sm.sendMessage(mParams.initialAudioState);
waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
@@ -178,8 +191,6 @@
verify(mCallAudioManager).stopCallWaiting();
break;
}
-
- sm.quitNow();
}
@Parameterized.Parameters(name = "{0}")
@@ -189,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
@@ -208,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
@@ -227,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
@@ -246,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
@@ -265,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
@@ -284,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
@@ -303,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
@@ -322,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
@@ -341,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
@@ -360,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
@@ -379,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
@@ -398,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
@@ -414,17 +425,93 @@
));
result.add(new ModeTestParameters(
+ "Swap between voip and sim calls - 1",
+ CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
+ 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
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Swap between voip and sim calls - 2",
+ CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
+ 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
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Swap between voip and sim calls - 3",
+ CallAudioModeStateMachine.ENTER_COMMS_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL, // messageType
+ 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
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
+ "Swap between voip and sim calls - 4",
+ CallAudioModeStateMachine.ENTER_CALL_FOCUS_FOR_TESTING, // initialAudioState
+ CallAudioModeStateMachine.NEW_HOLDING_CALL, // messageType
+ 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
+ NO_CHANGE, // expectedRingingInteraction
+ NO_CHANGE // expectedCallWaitingInteraction
+ ));
+
+ result.add(new ModeTestParameters(
"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
@@ -436,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
@@ -455,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
@@ -474,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
@@ -493,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
@@ -513,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
@@ -532,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
@@ -552,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
@@ -572,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
@@ -587,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/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 7f289b8..5a739a5 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.media.AudioManager;
import android.media.IAudioService;
+import android.os.HandlerThread;
import android.telecom.CallAudioState;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -34,6 +35,7 @@
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.WiredHeadsetManager;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -66,7 +68,7 @@
import static org.mockito.Mockito.when;
@RunWith(JUnit4.class)
-public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
+public class CallAudioRouteStateMachineTest extends TelecomTestCase {
private static final BluetoothDevice bluetoothDevice1 =
BluetoothRouteManagerTest.makeBluetoothDevice("00:00:00:00:00:01");
@@ -88,12 +90,15 @@
private static final int TEST_TIMEOUT = 500;
private AudioManager mockAudioManager;
private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
+ private HandlerThread mThreadHandler;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
+ mThreadHandler = new HandlerThread("CallAudioRouteStateMachineTest");
+ mThreadHandler.start();
mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
mockAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
@@ -115,6 +120,14 @@
any(CallAudioState.class));
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ mThreadHandler.quit();
+ mThreadHandler.join();
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testEarpieceAutodetect() {
@@ -125,7 +138,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT);
+ CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT,
+ mThreadHandler.getLooper());
// Since we don't know if we're on a platform with an earpiece or not, all we can do
// is ensure the stateMachine construction didn't fail. But at least we exercised the
@@ -143,7 +157,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -187,7 +202,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -230,7 +246,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
Collection<BluetoothDevice> availableDevices = Collections.singleton(bluetoothDevice1);
@@ -303,7 +320,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -338,7 +356,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
setInBandRing(false);
when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -392,7 +411,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
List<BluetoothDevice> availableDevices =
Arrays.asList(bluetoothDevice1, bluetoothDevice2, bluetoothDevice3);
@@ -441,7 +461,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
List<BluetoothDevice> availableDevices =
Arrays.asList(bluetoothDevice1, bluetoothDevice2);
@@ -554,7 +575,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mThreadHandler.getLooper());
stateMachine.initialize();
assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
}
@@ -575,7 +597,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- earpieceControl);
+ earpieceControl,
+ mThreadHandler.getLooper());
stateMachine.initialize();
assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
}
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
index e63fe9b..57462c4 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -33,6 +33,7 @@
import android.media.AudioManager;
import android.media.IAudioService;
import android.os.Handler;
+import android.os.HandlerThread;
import android.telecom.CallAudioState;
import android.test.suitebuilder.annotation.SmallTest;
@@ -46,6 +47,7 @@
import com.android.server.telecom.WiredHeadsetManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -154,6 +156,7 @@
private static final int TEST_TIMEOUT = 500;
private AudioManager mockAudioManager;
private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
+ private HandlerThread mHandlerThread;
public CallAudioRouteTransitionTests(RoutingTestParameters params) {
mParams = params;
@@ -164,6 +167,8 @@
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
+ mHandlerThread = new HandlerThread("CallAudioRouteTransitionTests");
+ mHandlerThread.start();
mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
mockAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
@@ -185,6 +190,14 @@
any(CallAudioState.class));
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ mHandlerThread.quit();
+ mHandlerThread.join();
+ super.tearDown();
+ }
+
private void setupMocksForParams(final CallAudioRouteStateMachine sm,
RoutingTestParameters params) {
// Set up bluetooth and speakerphone state
@@ -241,7 +254,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- mParams.earpieceControl);
+ mParams.earpieceControl,
+ mHandlerThread.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
setupMocksForParams(stateMachine, mParams);
@@ -329,7 +343,8 @@
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
- mParams.earpieceControl);
+ mParams.earpieceControl,
+ mHandlerThread.getLooper());
stateMachine.setCallAudioManager(mockCallAudioManager);
// Set up bluetooth and speakerphone state
diff --git a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
index ffd56fa..d53c73c 100644
--- a/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallLogManagerTest.java
@@ -69,6 +69,7 @@
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelephonyUtil;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -173,6 +174,12 @@
when(userManager.getUserInfo(eq(MANAGED_USER_ID))).thenReturn(managedProfileUserInfo);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@MediumTest
@Test
public void testDontLogCancelledCall() {
diff --git a/tests/src/com/android/server/telecom/tests/CallRecordingTonePlayerTest.java b/tests/src/com/android/server/telecom/tests/CallRecordingTonePlayerTest.java
index eca374b..5151d4c 100644
--- a/tests/src/com/android/server/telecom/tests/CallRecordingTonePlayerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallRecordingTonePlayerTest.java
@@ -39,6 +39,7 @@
import com.android.server.telecom.CallRecordingTonePlayer;
import com.android.server.telecom.TelecomSystem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -80,6 +81,12 @@
when(mAudioManager.getActiveRecordingConfigurations()).thenReturn(null);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
/**
* Ensures that child calls are not tracked.
*/
diff --git a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
index 169c56a..90d4dee 100644
--- a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
@@ -39,6 +39,7 @@
import com.android.server.telecom.callredirection.CallRedirectionProcessor;
import com.android.server.telecom.callredirection.CallRedirectionProcessorHelper;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -126,6 +127,12 @@
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
private void setIsInCarMode(boolean isInCarMode) {
when(mSystemStateHelper.isCarMode()).thenReturn(isInCarMode);
}
diff --git a/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java b/tests/src/com/android/server/telecom/tests/CallScreeningServiceControllerTest.java
index 1a01a95..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,8 +46,10 @@
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;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -69,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";
@@ -106,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
@@ -144,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;
@@ -160,6 +157,12 @@
when(mCall.getHandle()).thenReturn(TEST_HANDLE);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testAllAllowCall() {
@@ -229,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
@@ -275,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
@@ -323,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() {
@@ -370,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 5b47fe9..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,9 +44,11 @@
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;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -104,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;
@@ -162,6 +164,12 @@
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testNoPackageName() {
@@ -267,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
@@ -300,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
@@ -333,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/CallerInfoLookupHelperTest.java b/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
index e26d7e5..d4bff89 100644
--- a/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
@@ -44,6 +44,7 @@
import com.android.server.telecom.ContactsAsyncHelper;
import com.android.server.telecom.TelecomSystem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -102,6 +103,12 @@
}
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testLookupWithEmptyHandle() {
diff --git a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
index 7846fe9..fdd1d89 100644
--- a/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallsManagerTest.java
@@ -61,7 +61,6 @@
import com.android.server.telecom.ClockProxy;
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory;
-import com.android.server.telecom.ConnectionServiceWrapper;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.EmergencyCallHelper;
import com.android.server.telecom.HeadsetMediaButton;
@@ -83,7 +82,9 @@
import com.android.server.telecom.WiredHeadsetManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
+import com.android.server.telecom.callfiltering.IncomingCallFilter;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -173,6 +174,8 @@
@Mock private CallAudioModeStateMachine.Factory mCallAudioModeStateMachineFactory;
@Mock private BluetoothStateReceiver mBluetoothStateReceiver;
@Mock private RoleManagerAdapter mRoleManagerAdapter;
+ @Mock private IncomingCallFilter.Factory mIncomingCallFilterFactory;
+ @Mock private IncomingCallFilter mIncomingCallFilter;
private CallsManager mCallsManager;
@@ -193,6 +196,8 @@
anyInt())).thenReturn(mCallAudioRouteStateMachine);
when(mCallAudioModeStateMachineFactory.create(any(), any()))
.thenReturn(mCallAudioModeStateMachine);
+ when(mIncomingCallFilterFactory.create(any(), any(), any(), any(), any(), any()))
+ .thenReturn(mIncomingCallFilter);
when(mClockProxy.currentTimeMillis()).thenReturn(System.currentTimeMillis());
when(mClockProxy.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
when(mConnSvrFocusManagerFactory.create(any())).thenReturn(mConnectionSvrFocusMgr);
@@ -222,7 +227,8 @@
mCallAudioRouteStateMachineFactory,
mCallAudioModeStateMachineFactory,
mInCallControllerFactory,
- mRoleManagerAdapter);
+ mRoleManagerAdapter,
+ mIncomingCallFilterFactory);
when(mPhoneAccountRegistrar.getPhoneAccount(
eq(SELF_MANAGED_HANDLE), any())).thenReturn(SELF_MANAGED_ACCOUNT);
@@ -232,6 +238,12 @@
eq(SIM_2_HANDLE), any())).thenReturn(SIM_2_ACCOUNT);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@MediumTest
@Test
public void testConstructPossiblePhoneAccounts() throws Exception {
@@ -251,7 +263,7 @@
Call ongoingCall = new Call(
"1", /* callId */
- mComponentContextFixture.getTestDouble(),
+ mContext,
mCallsManager,
mLock,
null /* ConnectionServiceRepository */,
@@ -1014,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);
@@ -1090,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/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 9655476..3718419 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -29,8 +29,10 @@
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
+import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.telecom.CallAudioState;
@@ -658,6 +660,19 @@
mExtrasLock = new CountDownLatch(1);
}
+ public void waitForHandlerToClear() {
+ mConnectionServiceDelegate.getHandler().removeCallbacksAndMessages(null);
+ final CountDownLatch lock = new CountDownLatch(1);
+ mConnectionServiceDelegate.getHandler().post(lock::countDown);
+ while (lock.getCount() > 0) {
+ try {
+ lock.await(TelecomSystemTest.TEST_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+
private ParcelableConference parcelable(ConferenceInfo c) {
return new ParcelableConference(
c.phoneAccount,
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
index 77a9c0d..0d6ceba 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
@@ -23,6 +23,7 @@
import com.android.server.telecom.ConnectionServiceFocusManager;
import com.android.server.telecom.ConnectionServiceFocusManager.*;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,6 +72,12 @@
mCallsManagerListener = captor.getValue();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testRequestFocusWithoutActiveFocusExisted() {
diff --git a/tests/src/com/android/server/telecom/tests/ContactsAsyncHelperTest.java b/tests/src/com/android/server/telecom/tests/ContactsAsyncHelperTest.java
index 08d9a47..10cac93 100644
--- a/tests/src/com/android/server/telecom/tests/ContactsAsyncHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/ContactsAsyncHelperTest.java
@@ -32,12 +32,15 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.InstrumentationRegistry;
import com.android.server.telecom.ContactsAsyncHelper;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -46,6 +49,7 @@
import java.io.FileNotFoundException;
import java.io.InputStream;
+import java.util.concurrent.Executor;
@RunWith(JUnit4.class)
public class ContactsAsyncHelperTest extends TelecomTestCase {
@@ -96,10 +100,17 @@
mContext = InstrumentationRegistry.getTargetContext();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testEmptyUri() throws Exception {
- ContactsAsyncHelper cah = new ContactsAsyncHelper(mNullContentResolverAdapter);
+ ContactsAsyncHelper cah = new ContactsAsyncHelper(mNullContentResolverAdapter,
+ Looper.getMainLooper());
try {
cah.startObtainPhotoAsync(TOKEN, mContext, null, mListener, COOKIE);
} catch (IllegalStateException e) {
@@ -113,7 +124,8 @@
@SmallTest
@Test
public void testNullReturnFromOpenInputStream() {
- ContactsAsyncHelper cah = new ContactsAsyncHelper(mNullContentResolverAdapter);
+ ContactsAsyncHelper cah = new ContactsAsyncHelper(mNullContentResolverAdapter,
+ Looper.getMainLooper());
cah.startObtainPhotoAsync(TOKEN, mContext, SAMPLE_CONTACT_PHOTO_URI, mListener, COOKIE);
verify(mListener, timeout(TEST_TIMEOUT)).onImageLoadComplete(eq(TOKEN),
@@ -123,7 +135,8 @@
@SmallTest
@Test
public void testImageScaling() {
- ContactsAsyncHelper cah = new ContactsAsyncHelper(mWorkingContentResolverAdapter);
+ ContactsAsyncHelper cah = new ContactsAsyncHelper(mWorkingContentResolverAdapter,
+ Looper.getMainLooper());
cah.startObtainPhotoAsync(TOKEN, mContext, SAMPLE_CONTACT_PHOTO_URI, mListener, COOKIE);
ArgumentCaptor<Drawable> photoCaptor = ArgumentCaptor.forClass(Drawable.class);
@@ -143,7 +156,8 @@
@SmallTest
@Test
public void testNoScaling() {
- ContactsAsyncHelper cah = new ContactsAsyncHelper(mWorkingContentResolverAdapter);
+ ContactsAsyncHelper cah = new ContactsAsyncHelper(mWorkingContentResolverAdapter,
+ Looper.getMainLooper());
cah.startObtainPhotoAsync(TOKEN, mContext, SAMPLE_CONTACT_PHOTO_URI_SMALL,
mListener, COOKIE);
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/DefaultDialerCacheTest.java b/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
index e8bca03..e733465 100644
--- a/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
+++ b/tests/src/com/android/server/telecom/tests/DefaultDialerCacheTest.java
@@ -30,6 +30,7 @@
import com.android.server.telecom.RoleManagerAdapter;
import com.android.server.telecom.TelecomSystem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -101,6 +102,12 @@
when(mRoleManagerAdapter.getDefaultDialerApp(eq(USER2))).thenReturn(DIALER3);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testThreeUsers() {
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index a685c5e..e62a9fc 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -17,16 +17,17 @@
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;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,6 +53,12 @@
super.setUp();
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testSendToVoicemail() {
@@ -61,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
@@ -82,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
@@ -97,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/DtmfLocalTonePlayerTest.java b/tests/src/com/android/server/telecom/tests/DtmfLocalTonePlayerTest.java
index 24dd18f..85a5278 100644
--- a/tests/src/com/android/server/telecom/tests/DtmfLocalTonePlayerTest.java
+++ b/tests/src/com/android/server/telecom/tests/DtmfLocalTonePlayerTest.java
@@ -22,6 +22,7 @@
import com.android.server.telecom.DtmfLocalTonePlayer;
import com.android.server.telecom.R;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,6 +43,7 @@
DtmfLocalTonePlayer mPlayer;
+ @Override
@Before
public void setUp() throws Exception {
super.setUp();
@@ -50,6 +52,12 @@
when(mCall.getContext()).thenReturn(mContext);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testSupportedStart() {
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index bbefae3..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,
@@ -166,6 +169,8 @@
@Override
@After
public void tearDown() throws Exception {
+ mInCallController.getHandler().removeCallbacksAndMessages(null);
+ waitForHandlerAction(mInCallController.getHandler(), 1000);
super.tearDown();
}
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
index e399088..8e2d11e 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallFilterTest.java
@@ -17,18 +17,21 @@
package com.android.server.telecom.tests;
import android.content.ContentResolver;
-import android.content.IContentProvider;
import android.net.Uri;
-import android.provider.CallLog;
+import android.os.Handler;
+import android.os.Looper;
+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;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -65,48 +68,50 @@
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());
@Override
@Before
@@ -117,11 +122,19 @@
setTimeoutLength(LONG_TIMEOUT);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ mHandler.removeCallbacksAndMessages(null);
+ waitForHandlerAction(mHandler, 1000);
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testAsyncBlockCallResultFilter() {
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
@@ -135,7 +148,7 @@
@Test
public void testDirectToVoiceMailCallResultFilter() {
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
@@ -149,7 +162,7 @@
@Test
public void testCallScreeningServiceBlockCallResultFilter() {
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
@@ -163,7 +176,7 @@
@Test
public void testPassCallResultFilter() {
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
@@ -183,7 +196,7 @@
add(mFilter4);
}};
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters);
+ mLock, mTimeoutsAdapter, filters, mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
verify(mFilter2).startFilterLookup(mCall, testFilter);
@@ -195,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
@@ -217,7 +229,7 @@
add(mFilter3);
}};
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters);
+ mLock, mTimeoutsAdapter, filters, mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
verify(mFilter2).startFilterLookup(mCall, testFilter);
@@ -227,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
@@ -248,7 +259,7 @@
add(mFilter2);
}};
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, filters);
+ mLock, mTimeoutsAdapter, filters, mHandler);
testFilter.performFiltering();
verify(mFilter1).startFilterLookup(mCall, testFilter);
verify(mFilter2).startFilterLookup(mCall, testFilter);
@@ -256,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
@@ -274,7 +284,7 @@
public void testFilterTimeout() throws Exception {
setTimeoutLength(SHORT_TIMEOUT);
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
verify(mResultCallback, timeout((int) SHORT_TIMEOUT * 2)).onCallFilteringComplete(eq(mCall),
eq(DEFAULT_RESULT));
@@ -290,7 +300,7 @@
public void testFilterTimeoutDoesntTrip() throws Exception {
setTimeoutLength(SHORT_TIMEOUT);
IncomingCallFilter testFilter = new IncomingCallFilter(mContext, mResultCallback, mCall,
- mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1));
+ mLock, mTimeoutsAdapter, Collections.singletonList(mFilter1), mHandler);
testFilter.performFiltering();
testFilter.onCallFilteringComplete(mCall, PASS_CALL_RESULT);
waitForHandlerAction(testFilter.getHandler(), SHORT_TIMEOUT * 2);
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
index f54783e..a871b73 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
@@ -28,6 +28,7 @@
import com.android.server.telecom.HandoverState;
import com.android.server.telecom.ui.IncomingCallNotifier;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -81,6 +82,12 @@
when(mRingingCall.getHandoverState()).thenReturn(HandoverState.HANDOVER_NONE);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
/**
* Add a call that isn't ringing.
*/
diff --git a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
index a3bdb10..404fcbd 100644
--- a/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/MissedCallNotifierImplTest.java
@@ -187,6 +187,7 @@
public void tearDown() throws Exception {
TelecomSystem.setInstance(null);
when(mTelecomSystem.isBootComplete()).thenReturn(false);
+ super.tearDown();
}
@SmallTest
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 4ed1039..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;
@@ -62,6 +62,7 @@
import com.android.server.telecom.SystemStateHelper;
import com.android.server.telecom.TelecomSystem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -88,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);
@@ -111,6 +111,12 @@
when(mSystemStateHelper.isCarMode()).thenReturn(false);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testSelfManagedCall() {
@@ -210,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";
@@ -220,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;
@@ -278,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;
@@ -292,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);
@@ -414,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));
}
@@ -451,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 3f4a4cd..7104e3a 100644
--- a/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
+++ b/tests/src/com/android/server/telecom/tests/ParcelableCallUtilsTest.java
@@ -32,6 +32,7 @@
import com.android.server.telecom.PhoneNumberUtilsAdapter;
import com.android.server.telecom.TelecomSystem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -60,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 */,
@@ -78,6 +80,12 @@
mClockProxy /* ClockProxy */);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testParcelForNonSystemDialer() {
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/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
index 75e89bc..53ddd93 100644
--- a/tests/src/com/android/server/telecom/tests/RingerTest.java
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -40,6 +40,7 @@
import com.android.server.telecom.RingtoneFactory;
import com.android.server.telecom.SystemSettingsUtil;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -147,6 +148,12 @@
mRingerUnderTest.setBlockOnRingingFuture(mRingCompletionFuture);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testNoActionInTheaterMode() {
diff --git a/tests/src/com/android/server/telecom/tests/SessionManagerTest.java b/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
index 85a9bff..cf84b7c 100644
--- a/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/SessionManagerTest.java
@@ -290,9 +290,9 @@
assertTrue(childSession.isSessionCompleted());
assertEquals(TEST_PARENT_NAME, mFullSessionMethodName);
// Reduce flakiness by assuming that the true completion time is within a threshold of
- // +-10 ms
- assertTrue(mfullSessionCompleteTime >= TEST_DELAY_TIME - 10);
- assertTrue(mfullSessionCompleteTime <= TEST_DELAY_TIME + 10);
+ // +-50 ms
+ assertTrue(mfullSessionCompleteTime >= TEST_DELAY_TIME / 2);
+ assertTrue(mfullSessionCompleteTime <= TEST_DELAY_TIME * 1.5);
}
/**
@@ -365,8 +365,8 @@
mTestSessionManager.endSession();
assertEquals(TEST_CHILD_NAME, mFullSessionMethodName);
- assertTrue(mfullSessionCompleteTime >= TEST_DELAY_TIME - 10);
- assertTrue(mfullSessionCompleteTime <= TEST_DELAY_TIME + 10);
+ assertTrue(mfullSessionCompleteTime >= TEST_DELAY_TIME / 2);
+ assertTrue(mfullSessionCompleteTime <= TEST_DELAY_TIME * 1.5);
}
/**
diff --git a/tests/src/com/android/server/telecom/tests/SessionTest.java b/tests/src/com/android/server/telecom/tests/SessionTest.java
index 7957a28..337041b 100644
--- a/tests/src/com/android/server/telecom/tests/SessionTest.java
+++ b/tests/src/com/android/server/telecom/tests/SessionTest.java
@@ -21,6 +21,8 @@
import android.telecom.Logging.Session;
import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -30,7 +32,19 @@
*/
@RunWith(JUnit4.class)
-public class SessionTest {
+public class SessionTest extends TelecomTestCase {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
/**
* Ensure creating two sessions that are parent/child of each other does not lead to a crash
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 185cb97..7d1bef7 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -55,6 +55,7 @@
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -229,6 +230,12 @@
.thenReturn(true);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testGetDefaultOutgoingPhoneAccount() throws RemoteException {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 82b17be..4fc9ed6 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -44,7 +44,6 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.IContentProvider;
import android.content.Intent;
import android.media.AudioManager;
import android.media.IAudioService;
@@ -52,29 +51,33 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
-import android.provider.BlockedNumberContract;
import android.telecom.Call;
import android.telecom.ConnectionRequest;
import android.telecom.DisconnectCause;
+import android.telecom.Log;
import android.telecom.ParcelableCall;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
+import android.text.TextUtils;
import com.android.internal.telecom.IInCallAdapter;
import com.android.server.telecom.AsyncRingtonePlayer;
import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallAudioManager;
+import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallerInfoLookupHelper;
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.CallsManagerListenerBase;
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;
@@ -88,13 +91,15 @@
import com.android.server.telecom.ProximitySensorManagerFactory;
import com.android.server.telecom.RoleManagerAdapter;
import com.android.server.telecom.StatusBarNotifier;
+import com.android.server.telecom.SystemStateHelper;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.WiredHeadsetManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
+import com.android.server.telecom.callfiltering.CallFilterResultCallback;
+import com.android.server.telecom.callfiltering.IncomingCallFilter;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.ui.IncomingCallNotifier;
-import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
import com.google.common.base.Predicate;
@@ -179,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 {
@@ -206,8 +199,6 @@
}
}
- PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
-
@Mock HeadsetMediaButton mHeadsetMediaButton;
@Mock ProximitySensorManager mProximitySensorManager;
@Mock InCallWakeLockController mInCallWakeLockController;
@@ -216,6 +207,7 @@
@Mock IncomingCallNotifier mIncomingCallNotifier;
@Mock ClockProxy mClockProxy;
@Mock RoleManagerAdapter mRoleManagerAdapter;
+ @Mock ToneGenerator mToneGenerator;
final ComponentName mInCallServiceComponentNameX =
new ComponentName(
@@ -333,9 +325,11 @@
Context mSpyContext;
- private int mNumOutgoingCallsMade;
+ ConnectionServiceFocusManager mConnectionServiceFocusManager;
- private boolean mIsEmergencyCall;
+ private HandlerThread mHandlerThread;
+
+ private int mNumOutgoingCallsMade;
class IdPair {
final String mConnectionId;
@@ -354,9 +348,15 @@
doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
doNothing().when(mSpyContext).sendBroadcastAsUser(any(), any(), any());
+ mHandlerThread = new HandlerThread("TelecomHandlerThread");
+ mHandlerThread.start();
+
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
@@ -364,6 +364,8 @@
// Next, create the TelecomSystem, our system under test
setupTelecomSystem();
+ // Need to reset teseting tag here
+ Log.setTag(TESTING_TAG);
// Finally, register the ConnectionServices with the PhoneAccountRegistrar of the
// now-running TelecomSystem
@@ -374,10 +376,30 @@
@Override
public void tearDown() throws Exception {
- mTelecomSystem.getCallsManager().getCallAudioManager()
- .getCallAudioRouteStateMachine().quitNow();
- mTelecomSystem.getCallsManager().getCallAudioManager()
- .getCallAudioModeStateMachine().quitNow();
+ mTelecomSystem.getCallsManager().waitOnHandlers();
+ waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ waitForHandlerAction(mHandlerThread.getThreadHandler(), TEST_TIMEOUT);
+ // Bring down the threads that are active.
+ mHandlerThread.quit();
+ try {
+ mHandlerThread.join();
+ } catch (InterruptedException e) {
+ // don't do anything
+ }
+
+ mConnectionServiceFocusManager.getHandler().removeCallbacksAndMessages(null);
+ waitForHandlerAction(mConnectionServiceFocusManager.getHandler(), TEST_TIMEOUT);
+ mConnectionServiceFocusManager.getHandler().getLooper().quit();
+
+ mConnectionServiceFixtureA.waitForHandlerToClear();
+ mConnectionServiceFixtureB.waitForHandlerToClear();
+
+ // Print out any incomplete sessions for debugging tests
+ String sessions = Log.getSessionManager().printActiveSessions();
+ if (!TextUtils.isEmpty(sessions)) {
+ Log.w(this, "Active Sessions:\n" + sessions);
+ }
+
mTelecomSystem = null;
super.tearDown();
}
@@ -430,6 +452,12 @@
mCallerInfoAsyncQueryFactoryFixture = new CallerInfoAsyncQueryFactoryFixture();
+ ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory mConnServFMFactory =
+ requester -> {
+ mConnectionServiceFocusManager = new ConnectionServiceFocusManager(requester);
+ return mConnectionServiceFocusManager;
+ };
+
mTimeoutsAdapter = mock(Timeouts.Adapter.class);
when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
.thenReturn(TEST_TIMEOUT / 5L);
@@ -449,12 +477,12 @@
inCallWakeLockControllerFactory,
() -> mAudioService,
(context, lock, callsManager, phoneAccountRegistrar) -> mBluetoothPhoneServiceImpl,
- ConnectionServiceFocusManager::new,
+ mConnServFMFactory,
mTimeoutsAdapter,
mAsyncRingtonePlayer,
- mPhoneNumberUtilsAdapter,
+ new PhoneNumberUtilsAdapterImpl(),
mIncomingCallNotifier,
- (streamType, volume) -> mock(ToneGenerator.class),
+ (streamType, volume) -> mToneGenerator,
new CallAudioRouteStateMachine.Factory() {
@Override
public CallAudioRouteStateMachine create(
@@ -472,11 +500,37 @@
statusBarNotifier,
audioServiceFactory,
// Force enable an earpiece for the end-to-end tests
- CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED,
+ mHandlerThread.getLooper());
+ }
+ },
+ new CallAudioModeStateMachine.Factory() {
+ @Override
+ public CallAudioModeStateMachine create(SystemStateHelper systemStateHelper,
+ AudioManager am) {
+ return new CallAudioModeStateMachine(systemStateHelper, am,
+ mHandlerThread.getLooper());
}
},
mClockProxy,
- mRoleManagerAdapter);
+ mRoleManagerAdapter,
+ new IncomingCallFilter.Factory() {
+ @Override
+ public IncomingCallFilter create(Context context,
+ CallFilterResultCallback listener, com.android.server.telecom.Call call,
+ TelecomSystem.SyncRoot lock, Timeouts.Adapter timeoutsAdapter,
+ List<IncomingCallFilter.CallFilter> filters) {
+ return new IncomingCallFilter(context, listener, call, lock,
+ timeoutsAdapter, filters, mHandlerThread.getThreadHandler());
+ }
+ },
+ new ContactsAsyncHelper.Factory() {
+ @Override
+ public ContactsAsyncHelper create(
+ ContactsAsyncHelper.ContentResolverAdapter adapter) {
+ return new ContactsAsyncHelper(adapter, mHandlerThread.getLooper());
+ }
+ });
mComponentContextFixture.setTelecomManager(new TelecomManager(
mComponentContextFixture.getTestDouble(),
@@ -646,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*/);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
index 637895b..b0b1ec0 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
@@ -22,6 +22,7 @@
import androidx.test.InstrumentationRegistry;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CountDownLatch;
@@ -36,6 +37,7 @@
public void setUp() throws Exception {
Log.setTag(TESTING_TAG);
+ Log.setIsExtendedLoggingEnabled(true);
mMockitoHelper.setUp(InstrumentationRegistry.getContext(), getClass());
mComponentContextFixture = new ComponentContextFixture();
mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
@@ -47,6 +49,7 @@
public void tearDown() throws Exception {
mComponentContextFixture = null;
mMockitoHelper.tearDown();
+ Mockito.framework().clearInlineMocks();
}
protected static void waitForHandlerAction(Handler h, long timeoutMillis) {
diff --git a/tests/src/com/android/server/telecom/tests/VideoProfileTest.java b/tests/src/com/android/server/telecom/tests/VideoProfileTest.java
index 6acadf7..5ee0414 100644
--- a/tests/src/com/android/server/telecom/tests/VideoProfileTest.java
+++ b/tests/src/com/android/server/telecom/tests/VideoProfileTest.java
@@ -23,6 +23,8 @@
import android.telecom.VideoProfile;
import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -32,6 +34,19 @@
*/
@RunWith(JUnit4.class)
public class VideoProfileTest extends TelecomTestCase {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@SmallTest
@Test
public void testToString() {
diff --git a/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java b/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java
index b09aa5b..2b6c260 100644
--- a/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java
+++ b/tests/src/com/android/server/telecom/tests/VideoProviderProxyTest.java
@@ -35,6 +35,7 @@
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.VideoProviderProxy;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -69,6 +70,12 @@
mVideoProviderProxy.addListener(mListener);
}
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
/**
* Tests the case where we receive a request to upgrade to video, except:
* 1. Phone account says we support video.
diff --git a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
index eacecf9..597924d 100644
--- a/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
+++ b/tests/src/com/android/server/telecom/tests/VideoProviderTest.java
@@ -34,8 +34,10 @@
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
+import android.telecom.Call;
import android.telecom.Connection;
import android.telecom.Connection.VideoProvider;
+import android.telecom.DisconnectCause;
import android.telecom.InCallService;
import android.telecom.InCallService.VideoCall;
import android.telecom.VideoCallImpl;
@@ -64,6 +66,8 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import com.android.server.telecom.CallsManager;
+
/**
* Performs tests of the {@link VideoProvider} and {@link VideoCall} APIs. Ensures that requests
* sent from an InCallService are routed through Telecom to a VideoProvider, and that callbacks are
@@ -116,13 +120,18 @@
mVideoCallImpl = (VideoCallImpl) mVideoCall;
mVideoCall.registerCallback(mVideoCallCallback);
+ // A little hacky, but we do not want CallsManager spawning InCallTonePlayer threads.
+ CallsManager callsManager = mTelecomSystem.getCallsManager();
+ callsManager.removeListener(callsManager.getCallAudioManager());
+
mConnectionInfo = mConnectionServiceFixtureA.mConnectionById.get(mCallIds.mConnectionId);
mVerificationLock = new CountDownLatch(1);
- waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
+ mTelecomSystem.getCallsManager().waitOnHandlers();
doNothing().when(mContext).enforcePermission(anyString(), anyInt(), anyInt(), anyString());
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager).noteOp(anyInt(), anyInt(),
anyString());
+
}
@Override