Merge "Ensure ImsConferenceController recalcs when a conference is no longer full." into udc-dev
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 71b2a9a..57f85ca 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -870,7 +870,7 @@
<string name="radioInfo_lac" msgid="3892986460272607013">"LAC"</string>
<string name="radioInfo_cid" msgid="1423185536264406705">"CID"</string>
<string name="radio_info_subid" msgid="6839966868621703203">"Sous-identifiant actuel :"</string>
- <string name="radio_info_dds" msgid="1122593144425697126">"Sous-identifiant de la carte SIM par défaut pour les données :"</string>
+ <string name="radio_info_dds" msgid="1122593144425697126">"Sous-identifiant SIM par défaut pour les données :"</string>
<string name="radio_info_dl_kbps" msgid="2382922659525318726">"Bande passante de téléchargement (kbit/s) :"</string>
<string name="radio_info_ul_kbps" msgid="2102225400904799036">"Bande passante d\'importation (kbit/s) :"</string>
<string name="radio_info_phy_chan_config" msgid="1277949603275436081">"Configuration de la chaîne physique LTE :"</string>
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index b49ff4e..bc1bae6 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -51,7 +51,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
import android.os.ICancellationSignal;
@@ -146,11 +145,9 @@
import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.satellite.ISatelliteDatagramCallback;
-import android.telephony.satellite.ISatelliteDatagramReceiverAck;
import android.telephony.satellite.ISatellitePositionUpdateCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteStateCallback;
-import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteDatagramCallback;
@@ -182,6 +179,7 @@
import com.android.internal.telephony.ICallForwardingInfoCallback;
import com.android.internal.telephony.IImsStateCallback;
import com.android.internal.telephony.IIntegerConsumer;
+import com.android.internal.telephony.ILongConsumer;
import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.IccCard;
@@ -198,7 +196,6 @@
import com.android.internal.telephony.ProxyController;
import com.android.internal.telephony.RIL;
import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RILUtils;
import com.android.internal.telephony.RadioInterfaceCapabilityController;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.SmsApplication;
@@ -266,7 +263,6 @@
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
@@ -6764,7 +6760,7 @@
mApp, subId, "getAllowedNetworkTypesForReason");
final long identity = Binder.clearCallingIdentity();
try {
- return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
+ return getPhoneFromSubIdOrDefault(subId).getAllowedNetworkTypes(reason);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -9566,6 +9562,34 @@
}
@Override
+ public void setCarrierServicePackageOverride(
+ int subId, String carrierServicePackage, String callingPackage) {
+ TelephonyPermissions.enforceShellOnly(
+ Binder.getCallingUid(), "setCarrierServicePackageOverride");
+
+ // Verify that the callingPackage belongs to the calling UID
+ mApp.getSystemService(AppOpsManager.class)
+ .checkPackage(Binder.getCallingUid(), callingPackage);
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final Phone phone = getPhone(subId);
+ if (phone == null || phone.getSubId() != subId) {
+ loge("setCarrierServicePackageOverride fails with invalid subId: " + subId);
+ throw new IllegalArgumentException("No phone for subid");
+ }
+ CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
+ if (cpt == null) {
+ loge("setCarrierServicePackageOverride failed with no CPT for phone");
+ throw new IllegalStateException("No CPT for phone");
+ }
+ cpt.setTestOverrideCarrierServicePackage(carrierServicePackage);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public int getCarrierIdListVersion(int subId) {
enforceReadPrivilegedPermission("getCarrierIdListVersion");
@@ -12388,7 +12412,7 @@
* This method requests modem to check if there are any pending datagrams to be received over
* satellite. If there are any incoming datagrams, they will be received via
* {@link SatelliteDatagramCallback#onSatelliteDatagramReceived(long, SatelliteDatagram, int,
- * ISatelliteDatagramReceiverAck)}
+ * ILongConsumer)})}
*
* @param subId The subId of the subscription used for receiving datagrams.
* @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
@@ -12409,25 +12433,23 @@
* encoding or encryption.
*
* @param subId The subId of the subscription to send satellite datagrams for.
- * @param datagramId An id that uniquely identifies datagram requested to be sent.
* @param datagramType datagram type indicating whether the datagram is of type
* SOS_SMS or LOCATION_SHARING.
* @param datagram encoded gateway datagram which is encrypted by the caller.
* Datagram will be passed down to modem without any encoding or encryption.
* @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
* full screen mode.
- * @param result The result receiver that returns datagramId if datagram is sent successfully
- * or {@link SatelliteManager.SatelliteError} of the request if it is failed.
+ * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
*
* @throws SecurityException if the caller doesn't have required permission.
*/
@Override
- public void sendSatelliteDatagram(int subId, long datagramId,
- @SatelliteManager.DatagramType int datagramType, SatelliteDatagram datagram,
- boolean needFullScreenPointingUI, @NonNull ResultReceiver result) {
+ public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
+ @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
+ @NonNull IIntegerConsumer callback) {
enforceSatelliteCommunicationPermission("sendSatelliteDatagram");
- mSatelliteController.sendSatelliteDatagram(subId, datagramId, datagramType, datagram,
- needFullScreenPointingUI, result);
+ mSatelliteController.sendSatelliteDatagram(subId, datagramType, datagram,
+ needFullScreenPointingUI, callback);
}
/**
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 5f14387..4826d2b 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -713,11 +713,11 @@
// an emergency-only account
String id = isEmergency ? EMERGENCY_ACCOUNT_HANDLE_ID : prefix +
String.valueOf(phone.getSubId());
- return makePstnPhoneAccountHandleWithPrefix(id, prefix, isEmergency, userHandle);
+ return makePstnPhoneAccountHandleWithId(id, userHandle);
}
- public static PhoneAccountHandle makePstnPhoneAccountHandleWithPrefix(
- String id, String prefix, boolean isEmergency, UserHandle userHandle) {
+ public static PhoneAccountHandle makePstnPhoneAccountHandleWithId(
+ String id, UserHandle userHandle) {
ComponentName pstnConnectionServiceName = getPstnConnectionServiceName();
// If user handle is null, resort to default constructor to use phone process's
// user handle
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 1858fe2..14eba74 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -100,6 +100,10 @@
private static final String DISABLE = "disable";
private static final String QUERY = "query";
private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
+ private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
+ "set-carrier-service-package-override";
+ private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
+ "clear-carrier-service-package-override";
private final String QUOTES = "\"";
private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
@@ -352,6 +356,10 @@
return handleRadioCommand();
case CARRIER_RESTRICTION_STATUS_TEST:
return handleCarrierRestrictionStatusCommand();
+ case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
+ return setCarrierServicePackageOverride();
+ case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
+ return clearCarrierServicePackageOverride();
default: {
return handleDefaultCommands(cmd);
}
@@ -3103,6 +3111,96 @@
return result;
}
+ // set-carrier-service-package-override
+ private int setCarrierServicePackageOverride() {
+ PrintWriter errPw = getErrPrintWriter();
+ int subId = SubscriptionManager.getDefaultSubscriptionId();
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-s":
+ try {
+ subId = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ errPw.println(
+ "set-carrier-service-package-override requires an integer as a"
+ + " subscription ID.");
+ return -1;
+ }
+ break;
+ }
+ }
+
+ String packageName = getNextArg();
+ if (packageName == null) {
+ errPw.println("set-carrier-service-package-override requires a override package name.");
+ return -1;
+ }
+
+ try {
+ mInterface.setCarrierServicePackageOverride(
+ subId, packageName, mContext.getOpPackageName());
+
+ if (VDBG) {
+ Log.v(
+ LOG_TAG,
+ "set-carrier-service-package-override -s " + subId + " " + packageName);
+ }
+ } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
+ Log.w(
+ LOG_TAG,
+ "set-carrier-service-package-override -s "
+ + subId
+ + " "
+ + packageName
+ + ", error"
+ + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
+
+ // clear-carrier-service-package-override
+ private int clearCarrierServicePackageOverride() {
+ PrintWriter errPw = getErrPrintWriter();
+ int subId = getDefaultSlot();
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-s":
+ try {
+ subId = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ errPw.println(
+ "clear-carrier-service-package-override requires an integer as a"
+ + " subscription ID.");
+ return -1;
+ }
+ break;
+ }
+ }
+
+ try {
+ mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
+
+ if (VDBG) {
+ Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
+ }
+ } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
+ Log.w(
+ LOG_TAG,
+ "clear-carrier-service-package-override -s "
+ + subId
+ + ", error"
+ + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
/**
* Building the string that can be used to build the JsonObject which supports to stub the data
diff --git a/src/com/android/phone/TimeConsumingPreferenceActivity.java b/src/com/android/phone/TimeConsumingPreferenceActivity.java
index d21f6a8..1fe548c 100644
--- a/src/com/android/phone/TimeConsumingPreferenceActivity.java
+++ b/src/com/android/phone/TimeConsumingPreferenceActivity.java
@@ -192,7 +192,12 @@
if (mIsForeground) {
showDialog(error);
}
- preference.setEnabled(false);
+
+ //If the error is due to RESPONSE_ERROR, do not disable the item so end user
+ //can continue to interact with it.
+ if (error != RESPONSE_ERROR) {
+ preference.setEnabled(false);
+ }
}
@Override
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
index 2546023..8288c43 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementApi.java
@@ -45,7 +45,7 @@
private static final String ENTITLEMENT_STATUS_KEY = "EntitlementStatus";
private static final String PROVISION_STATUS_KEY = "ProvStatus";
private static final String SERVICE_FLOW_URL_KEY = "ServiceFlow_URL";
- private static final String PROVISION_TIME_LEFT_KEY = "ProvisionTimeLeft";
+ private static final String SERVICE_FLOW_USERDATA_KEY = "ServiceFlow_UserData";
private static final String DEFAULT_EAP_AKA_RESPONSE = "Default EAP AKA response";
/**
* UUID to report an anomaly if an unexpected error is received during entitlement check.
@@ -100,8 +100,7 @@
requestBuilder.setTerminalModel("modelY");
requestBuilder.setTerminalSoftwareVersion("versionZ");
requestBuilder.setAcceptContentType(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON);
- requestBuilder.setNetworkIdentifier(
- TelephonyManager.convertPremiumCapabilityToString(capability));
+ requestBuilder.setBoostType(getBoostTypeFromPremiumCapability(capability));
ServiceEntitlementRequest request = requestBuilder.build();
PremiumNetworkEntitlementResponse premiumNetworkEntitlementResponse =
new PremiumNetworkEntitlementResponse();
@@ -109,7 +108,7 @@
String response = null;
try {
response = mServiceEntitlement.queryEntitlementStatus(
- ServiceEntitlement.APP_PREMIUM_NETWORK_SLICE,
+ ServiceEntitlement.APP_DATA_PLAN_BOOST,
request);
} catch (ServiceEntitlementException e) {
Log.e(TAG, "queryEntitlementStatus failed", e);
@@ -123,10 +122,9 @@
JSONObject jsonAuthResponse = new JSONObject(response);
String entitlementStatus = null;
String provisionStatus = null;
- String provisionTimeLeft = null;
- if (jsonAuthResponse.has(ServiceEntitlement.APP_PREMIUM_NETWORK_SLICE)) {
+ if (jsonAuthResponse.has(ServiceEntitlement.APP_DATA_PLAN_BOOST)) {
JSONObject jsonToken = jsonAuthResponse.getJSONObject(
- ServiceEntitlement.APP_PREMIUM_NETWORK_SLICE);
+ ServiceEntitlement.APP_DATA_PLAN_BOOST);
if (jsonToken.has(ENTITLEMENT_STATUS_KEY)) {
entitlementStatus = jsonToken.getString(ENTITLEMENT_STATUS_KEY);
if (entitlementStatus == null) {
@@ -142,20 +140,17 @@
Integer.parseInt(provisionStatus);
}
}
- if (jsonToken.has(PROVISION_TIME_LEFT_KEY)) {
- provisionTimeLeft = jsonToken.getString(PROVISION_TIME_LEFT_KEY);
- if (provisionTimeLeft != null) {
- premiumNetworkEntitlementResponse.mProvisionTimeLeft =
- Integer.parseInt(provisionTimeLeft);
- }
- }
if (jsonToken.has(SERVICE_FLOW_URL_KEY)) {
premiumNetworkEntitlementResponse.mServiceFlowURL =
jsonToken.getString(SERVICE_FLOW_URL_KEY);
}
+ if (jsonToken.has(SERVICE_FLOW_USERDATA_KEY)) {
+ premiumNetworkEntitlementResponse.mServiceFlowUserData =
+ jsonToken.getString(SERVICE_FLOW_USERDATA_KEY);
+ }
+ } else {
+ Log.e(TAG, "queryEntitlementStatus failed with no app");
}
-
-
} catch (JSONException e) {
Log.e(TAG, "queryEntitlementStatus failed", e);
reportAnomaly(UUID_ENTITLEMENT_CHECK_UNEXPECTED_ERROR,
@@ -194,4 +189,12 @@
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY,
BYPASS_EAP_AKA_AUTH_FOR_SLICE_PURCHASE_ENABLED, false);
}
+
+ @NonNull private String getBoostTypeFromPremiumCapability(
+ @TelephonyManager.PremiumCapability int capability) {
+ if (capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY) {
+ return "0" /* REALTIME_INTERACTIVE_TRAFFIC */;
+ }
+ return "";
+ }
}
diff --git a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
index 4e63e35..242ca69 100644
--- a/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
+++ b/src/com/android/phone/slice/PremiumNetworkEntitlementResponse.java
@@ -30,40 +30,39 @@
public static final int PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING = 3;
public static final int PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED = 4;
- @IntDef(prefix = {"PREMIUM_NETWORK_ENTITLEMENT_STATUS_"},
- value = {
- PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED,
- PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED,
- PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCOMPATIBLE,
- PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING,
- PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED
- })
+ @IntDef(prefix = {"PREMIUM_NETWORK_ENTITLEMENT_STATUS_"}, value = {
+ PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED,
+ PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED,
+ PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCOMPATIBLE,
+ PREMIUM_NETWORK_ENTITLEMENT_STATUS_PROVISIONING,
+ PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED
+ })
public @interface PremiumNetworkEntitlementStatus {}
public static final int PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED = 0;
public static final int PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED = 1;
- public static final int PREMIUM_NETWORK_PROVISION_STATUS_NOT_REQUIRED = 2;
+ public static final int PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE = 2;
public static final int PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS = 3;
- @IntDef(prefix = {"PREMIUM_NETWORK_PROVISION_STATUS_"},
- value = {
- PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED,
- PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED,
- PREMIUM_NETWORK_PROVISION_STATUS_NOT_REQUIRED,
- PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS
- })
+ @IntDef(prefix = {"PREMIUM_NETWORK_PROVISION_STATUS_"}, value = {
+ PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED,
+ PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED,
+ PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE,
+ PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS
+ })
public @interface PremiumNetworkProvisionStatus {}
@PremiumNetworkEntitlementStatus public int mEntitlementStatus;
@PremiumNetworkProvisionStatus public int mProvisionStatus;
- public int mProvisionTimeLeft;
@NonNull public String mServiceFlowURL;
+ @NonNull public String mServiceFlowUserData;
/**
* @return {@code true} if the premium network is provisioned and {@code false} otherwise.
*/
public boolean isProvisioned() {
return mProvisionStatus == PREMIUM_NETWORK_PROVISION_STATUS_PROVISIONED
+ || mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED
|| mEntitlementStatus == PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCLUDED;
}
@@ -83,7 +82,10 @@
public boolean isPremiumNetworkCapabilityAllowed() {
switch (mEntitlementStatus) {
case PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCOMPATIBLE:
- case PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED:
+ return false;
+ }
+ switch (mProvisionStatus) {
+ case PREMIUM_NETWORK_PROVISION_STATUS_NOT_AVAILABLE:
return false;
}
return true;
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 7bbe9cf..755c85f 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -981,23 +981,25 @@
// event package; some carriers are known to keep a disconnected participant around in
// subsequent CEP updates with a state of disconnected, even though its no longer part
// of the conference.
- // Note: We consider 0 to still be a single party conference since some carriers will
- // send a conference event package with JUST the host in it when the conference is
- // disconnected. We don't want to change back to conference mode prior to disconnection
- // or we will not log the call.
- boolean isSinglePartyConference = participants.stream()
+ final long numActiveCepParticipantsOtherThanHost = participants.stream()
.filter(p -> {
Pair<Uri, Uri> pIdent = new Pair<>(p.getHandle(), p.getEndpoint());
return !Objects.equals(mHostParticipantIdentity, pIdent)
&& p.getState() != Connection.STATE_DISCONNECTED;
})
- .count() <= 1;
+ .count();
+ // We consider 0 to still be a single party conference since some carriers
+ // will send a conference event package with JUST the host in it when the conference
+ // is disconnected. We don't want to change back to conference mode prior to
+ // disconnection or we will not log the call.
+ final boolean isCepForSinglePartyConference =
+ numActiveCepParticipantsOtherThanHost <= 1;
// We will only process the CEP data if:
// 1. We're not emulating a single party call.
// 2. We're emulating a single party call and the CEP contains more than just the
// single party
- if ((!isMultiparty() && !isSinglePartyConference)
+ if ((!isMultiparty() && !isCepForSinglePartyConference)
|| isMultiparty()) {
// Add any new participants and update existing.
for (ConferenceParticipant participant : participants) {
@@ -1083,15 +1085,17 @@
int newParticipantCount = mConferenceParticipantConnections.size();
Log.v(this, "handleConferenceParticipantsUpdate: oldParticipantCount=%d, "
- + "newParticipantcount=%d", oldParticipantCount, newParticipantCount);
- // If the single party call emulation fature flag is enabled, we can potentially treat
+ + "newParticipantCount=%d, isMultiPty=%b, cepParticipantCt=%d",
+ oldParticipantCount, newParticipantCount, isMultiparty(),
+ numActiveCepParticipantsOtherThanHost);
+ // If the single party call emulation feature flag is enabled, we can potentially treat
// the conference as a single party call when there is just one participant.
if (mFeatureFlagProxy.isUsingSinglePartyCallEmulation() &&
!mConferenceHost.isAdhocConferenceCall()) {
if (oldParticipantCount != 1 && newParticipantCount == 1) {
// If number of participants goes to 1, emulate a single party call.
startEmulatingSinglePartyCall();
- } else if (!isMultiparty() && !isSinglePartyConference) {
+ } else if (!isMultiparty() && !isCepForSinglePartyConference) {
// Number of participants increased, so stop emulating a single party call.
stopEmulatingSinglePartyCall();
}
@@ -1115,8 +1119,8 @@
// OR if the conference had a single participant and is emulating a standalone
// call.
&& (oldParticipantCount > 0 || !isMultiparty())
- // AND the CEP says there is nobody left any more.
- && newParticipantCount == 0) {
+ // AND the CEP says there is nobody left anymore.
+ && numActiveCepParticipantsOtherThanHost == 0) {
Log.i(this, "handleConferenceParticipantsUpdate: empty conference; "
+ "local disconnect.");
onDisconnect();
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 6650eac..57e65ee 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -1593,9 +1593,8 @@
int subscriptionId = phone.getSubId();
Log.i(this, "setupAccounts: Phone with subscription id %d", subscriptionId);
// setupAccounts can be called multiple times during service changes.
- // Don't add an account if the Icc has not been set yet.
- if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)
- || phone.getFullIccSerialNumber() == null) {
+ // Don't add an account if subscription is not ready.
+ if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
Log.d(this, "setupAccounts: skipping invalid subid %d", subscriptionId);
continue;
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index f381f11..9f248b7 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -16,6 +16,10 @@
package com.android.services.telephony;
+import static android.telephony.ims.ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED;
+import static android.telephony.ims.ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL;
+import static android.telephony.ims.ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
@@ -2483,13 +2487,25 @@
ImsPhoneConnection imsPhoneConnection =
(ImsPhoneConnection) mOriginalConnection;
reasonInfo = imsPhoneConnection.getImsReasonInfo();
- if (reasonInfo != null && reasonInfo.getCode()
- == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
- EmergencyNumber emergencyNumber =
- imsPhoneConnection.getEmergencyNumberInfo();
- if (emergencyNumber != null) {
- mEmergencyServiceCategory =
- emergencyNumber.getEmergencyServiceCategoryBitmask();
+ if (reasonInfo != null) {
+ int reasonCode = reasonInfo.getCode();
+ int extraCode = reasonInfo.getExtraCode();
+ if ((reasonCode == CODE_SIP_ALTERNATE_EMERGENCY_CALL)
+ || (reasonCode == CODE_LOCAL_CALL_CS_RETRY_REQUIRED
+ && extraCode == EXTRA_CODE_CALL_RETRY_EMERGENCY)) {
+ EmergencyNumber numberInfo =
+ imsPhoneConnection.getEmergencyNumberInfo();
+ if (numberInfo != null) {
+ mEmergencyServiceCategory =
+ numberInfo.getEmergencyServiceCategoryBitmask();
+ } else {
+ Log.i(this, "mEmergencyServiceCategory no EmergencyNumber");
+ }
+
+ if (mEmergencyServiceCategory != null) {
+ Log.i(this, "mEmergencyServiceCategory="
+ + mEmergencyServiceCategory);
+ }
}
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 8cd0b13..7311113 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -83,6 +83,7 @@
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import com.android.internal.telephony.imsphone.ImsPhoneMmiCode;
+import com.android.internal.telephony.satellite.SatelliteSOSMessageRecommender;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.phone.FrameworksUtils;
@@ -119,6 +120,10 @@
// Timeout before we continue with the emergency call without waiting for DDS switch response
// from the modem.
private static final int DEFAULT_DATA_SWITCH_TIMEOUT_MS = 1000;
+
+ // Timeout before we terminate the outgoing DSDA call if HOLD did not complete in time on the
+ // existing call.
+ private static final int DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS = 1000;
private static final String KEY_DOMAIN_COMPARE_FEATURE_ENABLED_FLAG =
"is_domain_selection_compare_feature_enabled";
@@ -205,6 +210,7 @@
public Pair<WeakReference<TelephonyConnection>, Queue<Phone>> mEmergencyRetryCache;
private DeviceState mDeviceState = new DeviceState();
private EmergencyStateTracker mEmergencyStateTracker;
+ private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
private DomainSelectionResolver mDomainSelectionResolver;
private EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
private TelephonyConnection mEmergencyConnection;
@@ -568,6 +574,34 @@
}
};
+ private final TelephonyConnection.TelephonyConnectionListener
+ mEmergencyConnectionSatelliteListener =
+ new TelephonyConnection.TelephonyConnectionListener() {
+ @Override
+ public void onStateChanged(Connection connection,
+ @Connection.ConnectionState int state) {
+ if (connection == null) {
+ Log.d(this,
+ "onStateChanged for satellite listener: connection is null");
+ return;
+ }
+ if (mSatelliteSOSMessageRecommender == null) {
+ Log.d(this, "onStateChanged for satellite listener: "
+ + "mSatelliteSOSMessageRecommender is null");
+ return;
+ }
+
+ TelephonyConnection c = (TelephonyConnection) connection;
+ mSatelliteSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
+ c.getTelecomCallId(), state);
+ if (state == Connection.STATE_DISCONNECTED
+ || state == Connection.STATE_ACTIVE) {
+ c.removeTelephonyConnectionListener(mEmergencyConnectionSatelliteListener);
+ mSatelliteSOSMessageRecommender = null;
+ }
+ }
+ };
+
/**
* A listener for calls.
*/
@@ -599,6 +633,39 @@
}
};
+ private static class StateHoldingListener extends
+ TelephonyConnection.TelephonyConnectionListener {
+ private final CompletableFuture<Boolean> mStateHoldingFuture;
+
+ StateHoldingListener(CompletableFuture<Boolean> future) {
+ mStateHoldingFuture = future;
+ }
+
+ @Override
+ public void onStateChanged(
+ Connection connection, @Connection.ConnectionState int state) {
+ TelephonyConnection c = (TelephonyConnection) connection;
+ if (c != null) {
+ switch (c.getState()) {
+ case Connection.STATE_HOLDING: {
+ Log.d(LOG_TAG, "Connection " + connection
+ + " changed to STATE_HOLDING!");
+ mStateHoldingFuture.complete(true);
+ c.removeTelephonyConnectionListener(this);
+ }
+ break;
+ case Connection.STATE_DISCONNECTED: {
+ Log.d(LOG_TAG, "Connection " + connection
+ + " changed to STATE_DISCONNECTED!");
+ mStateHoldingFuture.complete(false);
+ c.removeTelephonyConnectionListener(this);
+ }
+ break;
+ }
+ }
+ }
+ }
+
private final DomainSelectionConnection.DomainSelectionConnectionCallback
mEmergencyDomainSelectionConnectionCallback =
new DomainSelectionConnection.DomainSelectionConnectionCallback() {
@@ -1083,6 +1150,21 @@
}
return resultConnection;
} else {
+ if (mTelephonyManagerProxy.isConcurrentCallsPossible()) {
+ delayDialForOtherSubHold(phone, request.getAccountHandle(), (result) -> {
+ Log.d(this,
+ "onCreateOutgoingConn - delayDialForOtherSubHold result = "
+ + result);
+ if (result) {
+ placeOutgoingConnection(request, resultConnection, phone);
+ } else {
+ ((TelephonyConnection) resultConnection).hangup(
+ android.telephony.DisconnectCause.LOCAL);
+ }
+ });
+ return resultConnection;
+ }
+ // The standard case.
return placeOutgoingConnection(request, resultConnection, phone);
}
} else {
@@ -1959,12 +2041,14 @@
}
});
}
+
final com.android.internal.telephony.Connection originalConnection;
try {
if (phone != null) {
boolean isEmergency = mTelephonyManagerProxy.isCurrentEmergencyNumber(number);
Log.i(this, "placeOutgoingConnection isEmergency=" + isEmergency);
if (isEmergency) {
+ handleEmergencyCallStartedForSatelliteSOSMessageRecommender(connection, phone);
if (!getAllConnections().isEmpty()) {
if (!shouldHoldForEmergencyCall(phone)) {
// If we do not support holding ongoing calls for an outgoing
@@ -2353,10 +2437,23 @@
return false;
}
- if (reasonInfo != null
- && reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
- onEmergencyRedial(c, c.getPhone().getDefaultPhone());
- return true;
+ if (reasonInfo != null) {
+ int reasonCode = reasonInfo.getCode();
+ int extraCode = reasonInfo.getExtraCode();
+ if ((reasonCode == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL)
+ || (reasonCode == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
+ && extraCode == ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY)) {
+ // clear normal call domain selector
+ c.removeTelephonyConnectionListener(mNormalCallConnectionListener);
+ if (mDomainSelectionConnection != null) {
+ mDomainSelectionConnection.finishSelection();
+ mDomainSelectionConnection = null;
+ }
+ mNormalCallConnection = null;
+
+ onEmergencyRedial(c, c.getPhone().getDefaultPhone());
+ return true;
+ }
}
return maybeReselectDomainForNormalCall(c, callFailCause, reasonInfo);
@@ -2367,14 +2464,8 @@
Log.i(this, "maybeReselectDomainForEmergencyCall "
+ "csCause=" + callFailCause + ", psCause=" + reasonInfo);
- // EMERGENCY_TEMP_FAILURE and EMERGENCY_PERM_FAILURE shall be handled after
- // reselecting new {@link Phone} in {@link #retryOutgoingOriginalConnection()}.
if (c.getOriginalConnection() != null
&& c.getOriginalConnection().getDisconnectCause()
- != android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
- && c.getOriginalConnection().getDisconnectCause()
- != android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE
- && c.getOriginalConnection().getDisconnectCause()
!= android.telephony.DisconnectCause.LOCAL
&& c.getOriginalConnection().getDisconnectCause()
!= android.telephony.DisconnectCause.POWER_OFF) {
@@ -2513,6 +2604,7 @@
mIsEmergencyCallPending = true;
c.addTelephonyConnectionListener(mEmergencyConnectionListener);
+ handleEmergencyCallStartedForSatelliteSOSMessageRecommender(c, phone);
if (mEmergencyStateTracker == null) {
mEmergencyStateTracker = EmergencyStateTracker.getInstance();
@@ -2683,6 +2775,12 @@
return mEmergencyConnectionListener;
}
+ @VisibleForTesting
+ public TelephonyConnection.TelephonyConnectionListener
+ getEmergencyConnectionSatelliteListener() {
+ return mEmergencyConnectionSatelliteListener;
+ }
+
private boolean isVideoCallHoldAllowed(Phone phone) {
CarrierConfigManager cfgManager = (CarrierConfigManager)
phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -2849,6 +2947,7 @@
if (phone == null) {
// Do not block indefinitely.
completeConsumer.accept(false);
+ return;
}
try {
// Waiting for PhoneSwitcher to complete the operation.
@@ -2968,6 +3067,64 @@
return modemResultFuture;
}
+ private void addTelephonyConnectionListener(Conferenceable c,
+ TelephonyConnection.TelephonyConnectionListener listener) {
+ if (c instanceof TelephonyConnection) {
+ TelephonyConnection telephonyConnection = (TelephonyConnection) c;
+ telephonyConnection.addTelephonyConnectionListener(listener);
+ } else if (c instanceof ImsConference) {
+ ImsConference imsConference = (ImsConference) c;
+ TelephonyConnection conferenceHost =
+ (TelephonyConnection) imsConference.getConferenceHost();
+ conferenceHost.addTelephonyConnectionListener(listener);
+ } else {
+ throw new IllegalArgumentException(
+ "addTelephonyConnectionListener(): Unexpected conferenceable! " + c);
+ }
+ }
+
+ private CompletableFuture<Boolean> listenForHoldStateChanged(
+ @NonNull Conferenceable conferenceable) {
+ CompletableFuture<Boolean> future = new CompletableFuture<>();
+ final StateHoldingListener stateHoldingListener = new StateHoldingListener(future);
+ addTelephonyConnectionListener(conferenceable, stateHoldingListener);
+ return future;
+ }
+
+ // If there are any live calls on the other subscription, sends a hold request for the live call
+ // and waits for the STATE_HOLDING confirmation, to sequence the dial of the outgoing call.
+ private void delayDialForOtherSubHold(Phone phone, PhoneAccountHandle phoneAccountHandle,
+ Consumer<Boolean> completeConsumer) {
+ Conferenceable c = maybeHoldCallsOnOtherSubs(phoneAccountHandle);
+ if (c == null) {
+ // Nothing to hold.
+ completeConsumer.accept(true);
+ return;
+ }
+
+ if (phone == null) {
+ completeConsumer.accept(false);
+ return;
+ }
+
+ try {
+ // We have dispatched a 'hold' command to a live call (Connection or Conference) on the
+ // other sub. Listen to state changed events to see if this entered hold state.
+ CompletableFuture<Boolean> stateHoldingFuture = listenForHoldStateChanged(c);
+ // a timeout that will complete the future to not block the outgoing call indefinitely.
+ CompletableFuture<Boolean> timeout = new CompletableFuture<>();
+ phone.getContext().getMainThreadHandler().postDelayed(
+ () -> timeout.complete(false), DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS);
+ // Ensure that the Consumer is completed on the main thread.
+ stateHoldingFuture.acceptEitherAsync(timeout, completeConsumer,
+ phone.getContext().getMainExecutor());
+ } catch (Exception e) {
+ Log.w(this, "delayDialForOtherSubHold - exception= "
+ + e.getMessage());
+ completeConsumer.accept(false);
+ }
+ }
+
/**
* Get the Phone to use for an emergency call of the given emergency number address:
* a) If there are multiple Phones with the Subscriptions that support the emergency number
@@ -3585,7 +3742,20 @@
});
}
- private static void onUnhold(Conferenceable conferenceable) {
+ static void onHold(Conferenceable conferenceable) {
+ if (conferenceable instanceof Connection) {
+ Connection connection = (Connection) conferenceable;
+ connection.onHold();
+ } else if (conferenceable instanceof Conference) {
+ Conference conference = (Conference) conferenceable;
+ conference.onHold();
+ } else {
+ throw new IllegalArgumentException(
+ "onHold(): Unexpected conferenceable! " + conferenceable);
+ }
+ }
+
+ static void onUnhold(Conferenceable conferenceable) {
if (conferenceable instanceof Connection) {
Connection connection = (Connection) conferenceable;
connection.onUnhold();
@@ -3593,40 +3763,28 @@
Conference conference = (Conference) conferenceable;
conference.onUnhold();
} else {
- throw new IllegalArgumentException("Unexpected conferenceable! " + conferenceable);
+ throw new IllegalArgumentException(
+ "onUnhold(): Unexpected conferenceable! " + conferenceable);
}
}
- /**
- * Where there are ongoing calls on multiple subscriptions for DSDA devices, let the 'hold'
- * button perform an unhold on the other sub's Connection or Conference. This covers for Dialer
- * apps that may not have a dedicated 'swap' button for calls across different subs.
- * @param incomingHandle The incoming {@link PhoneAccountHandle}.
- */
- public void maybeUnholdCallsOnOtherSubs(@NonNull PhoneAccountHandle incomingHandle) {
- Log.i(this, "maybeUnholdCallsOnOtherSubs: check for calls not on %s",
- incomingHandle);
- maybeUnholdCallsOnOtherSubs(getAllConnections(), getAllConferences(), incomingHandle,
- mTelephonyManagerProxy);
- }
-
- /**
- * Used by {@link #maybeUnholdCallsOnOtherSubs(PhoneAccountHandle)} to evaluate whether and on
- * which connection / conference to call onUnhold(). This method exists as a convenience so that
- * it is possible to unit test the core functionality.
+ /**
+ * Evaluates whether a connection or conference exists on subscriptions other than the one
+ * corresponding to the existing {@link PhoneAccountHandle}.
* @param connections all individual connections, including conference participants.
* @param conferences all conferences.
- * @param incomingHandle the incoming handle.
+ * @param currentHandle the existing call handle;
* @param telephonyManagerProxy the proxy to the {@link TelephonyManager} instance.
*/
- @VisibleForTesting
- public static void maybeUnholdCallsOnOtherSubs(@NonNull Collection<Connection> connections,
+ private static @Nullable Conferenceable maybeGetFirstConferenceableFromOtherSubscription(
+ @NonNull Collection<Connection> connections,
@NonNull Collection<Conference> conferences,
- @NonNull PhoneAccountHandle incomingHandle,
+ @NonNull PhoneAccountHandle currentHandle,
TelephonyManagerProxy telephonyManagerProxy) {
if (!telephonyManagerProxy.isConcurrentCallsPossible()) {
- return;
+ return null;
}
+
List<Conference> otherSubConferences = conferences.stream()
.filter(c ->
// Exclude multiendpoint calls as they're not on this device.
@@ -3634,11 +3792,10 @@
& Connection.PROPERTY_IS_EXTERNAL_CALL) == 0
// Include any conferences not on same sub as current connection.
&& !Objects.equals(c.getPhoneAccountHandle(),
- incomingHandle))
+ currentHandle))
.toList();
if (!otherSubConferences.isEmpty()) {
- onUnhold(otherSubConferences.get(0));
- return;
+ return otherSubConferences.get(0);
}
// Considers Connections (including conference participants) only if no conferences.
@@ -3648,15 +3805,91 @@
(c.getConnectionProperties() & Connection.PROPERTY_IS_EXTERNAL_CALL) == 0
// Include any calls not on same sub as current connection.
&& !Objects.equals(c.getPhoneAccountHandle(),
- incomingHandle)).toList();
+ currentHandle)).toList();
if (!otherSubConnections.isEmpty()) {
if (otherSubConnections.size() > 1) {
- Log.w(LOG_TAG, "Unexpected number of conferenceables: "
+ Log.w(LOG_TAG, "Unexpected number of connections: "
+ otherSubConnections.size() + " on other sub!");
}
- onUnhold(otherSubConnections.get(0));
+ return otherSubConnections.get(0);
}
+ return null;
+ }
+
+ /**
+ * Where there are ongoing calls on multiple subscriptions for DSDA devices, let the 'hold'
+ * button perform an unhold on the other sub's Connection or Conference. This covers for Dialer
+ * apps that may not have a dedicated 'swap' button for calls across different subs.
+ * @param currentHandle The {@link PhoneAccountHandle} of the current active voice call.
+ */
+ public void maybeUnholdCallsOnOtherSubs(
+ @NonNull PhoneAccountHandle currentHandle) {
+ Log.i(this, "maybeUnholdCallsOnOtherSubs: check for calls not on %s",
+ currentHandle);
+ maybeUnholdCallsOnOtherSubs(getAllConnections(), getAllConferences(),
+ currentHandle, mTelephonyManagerProxy);
+ }
+
+ /**
+ * Where there are ongoing calls on multiple subscriptions for DSDA devices, let the 'hold'
+ * button perform an unhold on the other sub's Connection or Conference. This is a convenience
+ * method to unit test the core functionality.
+ *
+ * @param connections all individual connections, including conference participants.
+ * @param conferences all conferences.
+ * @param currentHandle The {@link PhoneAccountHandle} of the current active call.
+ * @param telephonyManagerProxy the proxy to the {@link TelephonyManager} instance.
+ */
+ @VisibleForTesting
+ protected static void maybeUnholdCallsOnOtherSubs(@NonNull Collection<Connection> connections,
+ @NonNull Collection<Conference> conferences,
+ @NonNull PhoneAccountHandle currentHandle,
+ TelephonyManagerProxy telephonyManagerProxy) {
+ Conferenceable c = maybeGetFirstConferenceableFromOtherSubscription(
+ connections, conferences, currentHandle, telephonyManagerProxy);
+ if (c != null) {
+ onUnhold(c);
+ }
+ }
+
+ /**
+ * For DSDA devices, when an outgoing call is dialed out from the 2nd sub, holds the first call.
+ *
+ * @param outgoingHandle The outgoing {@link PhoneAccountHandle}.
+ * @return the Conferenceable representing the Connection or Conference to be held.
+ */
+ private @Nullable Conferenceable maybeHoldCallsOnOtherSubs(
+ @NonNull PhoneAccountHandle outgoingHandle) {
+ Log.i(this, "maybeHoldCallsOnOtherSubs: check for calls not on %s",
+ outgoingHandle);
+ return maybeHoldCallsOnOtherSubs(getAllConnections(), getAllConferences(),
+ outgoingHandle, mTelephonyManagerProxy);
+ }
+
+ /**
+ * For DSDA devices, when an outgoing call is dialed out from the 2nd sub, holds the first call.
+ * This is a convenience method to unit test the core functionality.
+ *
+ * @param connections all individual connections, including conference participants.
+ * @param conferences all conferences.
+ * @param outgoingHandle The outgoing {@link PhoneAccountHandle}.
+ * @param telephonyManagerProxy the proxy to the {@link TelephonyManager} instance.
+ * @return the {@link Conferenceable} representing the Connection or Conference to be held.
+ */
+ @VisibleForTesting
+ protected static @Nullable Conferenceable maybeHoldCallsOnOtherSubs(
+ @NonNull Collection<Connection> connections,
+ @NonNull Collection<Conference> conferences,
+ @NonNull PhoneAccountHandle outgoingHandle,
+ TelephonyManagerProxy telephonyManagerProxy) {
+ Conferenceable c = maybeGetFirstConferenceableFromOtherSubscription(
+ connections, conferences, outgoingHandle, telephonyManagerProxy);
+ if (c != null) {
+ onHold(c);
+ return c;
+ }
+ return null;
}
private void disconnectAllCallsOnOtherSubs (@NonNull PhoneAccountHandle handle) {
@@ -3698,4 +3931,14 @@
}
return NetworkRegistrationInfo.DOMAIN_UNKNOWN;
}
+
+ private void handleEmergencyCallStartedForSatelliteSOSMessageRecommender(
+ @NonNull TelephonyConnection connection, @NonNull Phone phone) {
+ if (mSatelliteSOSMessageRecommender == null) {
+ mSatelliteSOSMessageRecommender = new SatelliteSOSMessageRecommender(
+ phone.getContext().getMainLooper());
+ }
+ connection.addTelephonyConnectionListener(mEmergencyConnectionSatelliteListener);
+ mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection, phone);
+ }
}
diff --git a/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java b/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java
new file mode 100644
index 0000000..f1bb78c
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.REDIAL_TIMER_DISABLED;
+import static android.telephony.PreciseDisconnectCause.EMERGENCY_PERM_FAILURE;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.SystemProperties;
+import android.telephony.Annotation.PreciseDisconnectCauses;
+import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.util.ArrayList;
+
+/** Controls the cross stack redialing. */
+public class CrossSimRedialingController extends Handler {
+ private static final String TAG = "CrossSimRedialingCtrl";
+ private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
+ private static final int LOG_SIZE = 50;
+
+ /** An interface of a helper to check emergency number. */
+ public interface EmergencyNumberHelper {
+ /**
+ * Returns whether the number is an emergency number in the given modem slot.
+ *
+ * @param slotId The slot id to be checked.
+ * @param number The number.
+ * @return {@code true} if the number is an emergency number in the given slot.
+ */
+ boolean isEmergencyNumber(int slotId, String number);
+ }
+
+ @VisibleForTesting
+ public static final int MSG_CROSS_STACK_TIMEOUT = 1;
+ @VisibleForTesting
+ public static final int MSG_QUICK_CROSS_STACK_TIMEOUT = 2;
+
+ private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
+
+ private final ArrayList<Integer> mStackSelectionHistory = new ArrayList<>();
+ private final ArrayList<Integer> mPermanentRejectedSlots = new ArrayList<>();
+ private final TelephonyManager mTelephonyManager;
+
+ private EmergencyNumberHelper mEmergencyNumberHelper = new EmergencyNumberHelper() {
+ @Override
+ public boolean isEmergencyNumber(int slotId, String number) {
+ // TODO(b/258112541) Add System api to check emergency number per subscription.
+ try {
+ Phone phone = PhoneFactory.getPhone(slotId);
+ if (phone != null
+ && phone.getEmergencyNumberTracker() != null
+ && phone.getEmergencyNumberTracker().isEmergencyNumber(number)) {
+ return true;
+ }
+ } catch (IllegalStateException e) {
+ loge("isEmergencyNumber e=" + e);
+ }
+ return false;
+ }
+ };
+
+ private int mModemCount;
+
+ /** A cache of the carrier config {@link #KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT}. */
+ private int mCrossStackTimer;
+ /** A cache of the carrier config {@link #KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT}. */
+ private int mQuickCrossStackTimer;
+ /**
+ * A cache of the carrier config
+ * {@link #KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL}.
+ */
+ private boolean mStartQuickCrossStackTimerWhenInService;
+
+ private String mCallId;
+ private EmergencyCallDomainSelector mSelector;
+ private String mNumber;
+ private int mSlotId;
+ private int mSubId;
+
+ /**
+ * Creates an instance.
+ *
+ * @param context The Context this is associated with.
+ * @param looper The Looper to run the CrossSimRedialingController.
+ */
+ public CrossSimRedialingController(@NonNull Context context, @NonNull Looper looper) {
+ super(looper);
+
+ mTelephonyManager = context.getSystemService(TelephonyManager.class);
+ }
+
+ /** For unit test only */
+ @VisibleForTesting
+ public CrossSimRedialingController(@NonNull Context context, @NonNull Looper looper,
+ EmergencyNumberHelper emergencyNumberHelper) {
+ this(context, looper);
+
+ mEmergencyNumberHelper = emergencyNumberHelper;
+ }
+
+ /**
+ * Starts the timer.
+ *
+ * @param context The Context this is associated with.
+ * @param selector The instance of {@link EmergencyCallDomainSelector}.
+ * @param callId The call identifier.
+ * @param number The dialing number.
+ * @param inService Indiates that normal service is available.
+ * @param roaming Indicates that it's in roaming or non-domestic network.
+ * @param modemCount The number of active modem count
+ */
+ public void startTimer(@NonNull Context context,
+ @NonNull EmergencyCallDomainSelector selector,
+ @NonNull String callId, @NonNull String number,
+ boolean inService, boolean roaming, int modemCount) {
+ logi("startTimer callId=" + callId
+ + ", in service=" + inService + ", roaming=" + roaming);
+
+ if (!TextUtils.equals(mCallId, callId)) {
+ logi("startTimer callId changed");
+ mCallId = callId;
+ mStackSelectionHistory.clear();
+ mPermanentRejectedSlots.clear();
+ }
+ mSelector = selector;
+ mSlotId = selector.getSlotId();
+ mSubId = selector.getSubId();
+ mNumber = number;
+ mModemCount = modemCount;
+
+ updateCarrierConfiguration(context);
+
+ boolean firstAttempt = !mStackSelectionHistory.contains(mSlotId);
+ logi("startTimer slot=" + mSlotId + ", firstAttempt=" + firstAttempt);
+ mStackSelectionHistory.add(mSlotId);
+
+ if (firstAttempt && mQuickCrossStackTimer > REDIAL_TIMER_DISABLED && !roaming) {
+ if (inService || !mStartQuickCrossStackTimerWhenInService) {
+ logi("startTimer quick timer started");
+ sendEmptyMessageDelayed(MSG_QUICK_CROSS_STACK_TIMEOUT,
+ mQuickCrossStackTimer);
+ return;
+ }
+ }
+
+ if (mCrossStackTimer > REDIAL_TIMER_DISABLED) {
+ logi("startTimer timer started");
+ sendEmptyMessageDelayed(MSG_CROSS_STACK_TIMEOUT, mCrossStackTimer);
+ }
+ }
+
+ /** Stops the timers. */
+ public void stopTimer() {
+ logi("stopTimer");
+ removeMessages(MSG_CROSS_STACK_TIMEOUT);
+ removeMessages(MSG_QUICK_CROSS_STACK_TIMEOUT);
+ }
+
+ /**
+ * Informs the call failure.
+ * @param cause The call failure cause.
+ */
+ public void notifyCallFailure(@PreciseDisconnectCauses int cause) {
+ logi("notifyCallFailure cause=" + cause);
+ if (cause == EMERGENCY_PERM_FAILURE) {
+ mPermanentRejectedSlots.add(mSlotId);
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_CROSS_STACK_TIMEOUT:
+ case MSG_QUICK_CROSS_STACK_TIMEOUT:
+ handleCrossStackTimeout();
+ break;
+ default:
+ super.handleMessage(msg);
+ break;
+ }
+ }
+
+ private void handleCrossStackTimeout() {
+ logi("handleCrossStackTimeout");
+
+ if (isThereOtherSlot()) {
+ mSelector.notifyCrossStackTimerExpired();
+ }
+ }
+
+ /**
+ * Returns whether there is another slot emergency capable.
+ *
+ * @return {@code true} if there is another slot emergency capable,
+ * {@code false} otherwise.
+ */
+ public boolean isThereOtherSlot() {
+ logi("isThereOtherSlot modemCount=" + mModemCount);
+ if (mModemCount < 2) return false;
+
+ for (int i = 0; i < mModemCount; i++) {
+ if (i == mSlotId) continue;
+
+ if (mPermanentRejectedSlots.contains(i)) {
+ logi("isThereOtherSlot index=" + i + ", permanent rejected");
+ continue;
+ }
+
+ int simState = mTelephonyManager.getSimState(i);
+ if (simState != TelephonyManager.SIM_STATE_READY) {
+ logi("isThereOtherSlot index=" + i + ", simState=" + simState);
+ continue;
+ }
+
+ if (mEmergencyNumberHelper.isEmergencyNumber(i, mNumber)) {
+ logi("isThereOtherSlot index=" + i + ", found");
+ return true;
+ } else {
+ logi("isThereOtherSlot index=" + i + ", not emergency number");
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Caches the configuration.
+ */
+ private void updateCarrierConfiguration(Context context) {
+ CarrierConfigManager configMgr = context.getSystemService(CarrierConfigManager.class);
+ PersistableBundle b = configMgr.getConfigForSubId(mSubId,
+ KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT,
+ KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT,
+ KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL);
+ if (b == null) {
+ b = CarrierConfigManager.getDefaultConfig();
+ }
+
+ mCrossStackTimer = b.getInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT) * 1000;
+ mQuickCrossStackTimer =
+ b.getInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT) * 1000;
+ mStartQuickCrossStackTimerWhenInService =
+ b.getBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL);
+
+ logi("updateCarrierConfiguration "
+ + ", crossStackTimer=" + mCrossStackTimer
+ + ", quickCrossStackTimer=" + mQuickCrossStackTimer
+ + ", startQuickTimerInService=" + mStartQuickCrossStackTimerWhenInService);
+ }
+
+ /** Destroys the instance. */
+ public void destroy() {
+ if (DBG) logd("destroy");
+
+ removeMessages(MSG_CROSS_STACK_TIMEOUT);
+ removeMessages(MSG_QUICK_CROSS_STACK_TIMEOUT);
+ }
+
+ private void logd(String s) {
+ Log.d(TAG, "[" + mSlotId + "|" + mSubId + "] " + s);
+ }
+
+ private void logi(String s) {
+ Log.i(TAG, "[" + mSlotId + "|" + mSubId + "] " + s);
+ sLocalLog.log(s);
+ }
+
+ private void loge(String s) {
+ Log.e(TAG, "[" + mSlotId + "|" + mSubId + "] " + s);
+ sLocalLog.log(s);
+ }
+}
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index e2800a3..b1c288c 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -50,6 +50,8 @@
import static android.telephony.CarrierConfigManager.ImsWfc.KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL;
import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
+import static android.telephony.PreciseDisconnectCause.EMERGENCY_PERM_FAILURE;
+import static android.telephony.PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE;
import android.annotation.NonNull;
import android.content.Context;
@@ -194,6 +196,9 @@
private boolean mIsScanRequested = false;
/** Indicates whether selected domain has been notified. */
private boolean mDomainSelected = false;
+ /** Indicates whether the cross sim redialing timer has expired. */
+ private boolean mCrossStackTimerExpired = false;
+
/**
* Indicates whether {@link #selectDomain(SelectionAttributes, TransportSelectionCallback)}
* is called or not.
@@ -201,11 +206,13 @@
private boolean mDomainSelectionRequested = false;
private final PowerManager.WakeLock mPartialWakeLock;
+ private final CrossSimRedialingController mCrossSimRedialingController;
/** Constructor. */
public EmergencyCallDomainSelector(Context context, int slotId, int subId,
@NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
- @NonNull DestroyListener destroyListener) {
+ @NonNull DestroyListener destroyListener,
+ @NonNull CrossSimRedialingController csrController) {
super(context, slotId, subId, looper, imsStateTracker, destroyListener, TAG);
mImsStateTracker.addBarringInfoListener(this);
@@ -214,6 +221,7 @@
PowerManager pm = context.getSystemService(PowerManager.class);
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+ mCrossSimRedialingController = csrController;
acquireWakeLock();
}
@@ -320,6 +328,23 @@
private void reselectDomain() {
logi("reselectDomain tryCsWhenPsFails=" + mTryCsWhenPsFails);
+ int cause = mSelectionAttributes.getCsDisconnectCause();
+ mCrossSimRedialingController.notifyCallFailure(cause);
+
+ // TODO(b/258112541) make EMERGENCY_PERM_FAILURE and EMERGENCY_TEMP_FAILURE public api
+ if (cause == EMERGENCY_PERM_FAILURE
+ || cause == EMERGENCY_TEMP_FAILURE) {
+ logi("reselectDomain should redial on the other subscription");
+ terminateSelectionForCrossSimRedialing(cause == EMERGENCY_PERM_FAILURE);
+ return;
+ }
+
+ if (mCrossStackTimerExpired) {
+ logi("reselectDomain cross stack timer expired");
+ terminateSelectionForCrossSimRedialing(false);
+ return;
+ }
+
if (mIsTestEmergencyNumber) {
selectDomainForTestEmergencyNumber();
return;
@@ -389,6 +414,7 @@
logi("startDomainSelection modemCount=" + mModemCount);
updateCarrierConfiguration();
mDomainSelectionRequested = true;
+ startCrossStackTimer();
if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
selectDomain();
} else {
@@ -1135,7 +1161,7 @@
mDomainSelected = true;
mLastTransportType = TRANSPORT_TYPE_WLAN;
mVoWifiTrialCount++;
- mTransportSelectorCallback.onWlanSelected();
+ mTransportSelectorCallback.onWlanSelected(mVoWifiOverEmergencyPdn);
mWwanSelectorCallback = null;
}
@@ -1166,7 +1192,8 @@
if (accessNetworkType == EUTRAN || accessNetworkType == NGRAN) {
domain = NetworkRegistrationInfo.DOMAIN_PS;
}
- mWwanSelectorCallback.onDomainSelected(domain);
+ mWwanSelectorCallback.onDomainSelected(domain,
+ (domain == NetworkRegistrationInfo.DOMAIN_PS));
}
/**
@@ -1216,7 +1243,10 @@
int simState = tm.getSimState(getSlotId());
if (simState != TelephonyManager.SIM_STATE_READY) {
logi("allowEmergencyCalls not ready, simState=" + simState + ", iso=" + iso);
- return false;
+ if (mCrossSimRedialingController.isThereOtherSlot()) {
+ return false;
+ }
+ logi("allowEmergencyCalls there is no other slot available");
}
}
@@ -1225,7 +1255,18 @@
private void terminateSelectionPermanentlyForSlot() {
logi("terminateSelectionPermanentlyForSlot");
- mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.EMERGENCY_PERM_FAILURE);
+ terminateSelection(true);
+ }
+
+ private void terminateSelectionForCrossSimRedialing(boolean permanent) {
+ logi("terminateSelectionForCrossSimRedialing perm=" + permanent);
+ terminateSelection(permanent);
+ }
+
+ private void terminateSelection(boolean permanent) {
+ mTransportSelectorCallback.onSelectionTerminated(permanent
+ ? DisconnectCause.EMERGENCY_PERM_FAILURE
+ : DisconnectCause.EMERGENCY_TEMP_FAILURE);
if (mIsScanRequested && mCancelSignal != null) {
mCancelSignal.cancel();
@@ -1233,6 +1274,41 @@
}
}
+ /** Starts the cross stack timer. */
+ public void startCrossStackTimer() {
+ boolean inService = false;
+ boolean inRoaming = false;
+
+ if (mModemCount == 1) return;
+
+ EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+ if (regResult != null) {
+ int regState = regResult.getRegState();
+
+ if ((regResult.getDomain() > 0)
+ && (regState == REGISTRATION_STATE_HOME
+ || regState == REGISTRATION_STATE_ROAMING)) {
+ inService = true;
+ }
+ inRoaming = (regState == REGISTRATION_STATE_ROAMING) || isInRoaming();
+ }
+
+ mCrossSimRedialingController.startTimer(mContext, this, mSelectionAttributes.getCallId(),
+ mSelectionAttributes.getNumber(), inService, inRoaming, mModemCount);
+ }
+
+ /** Notifies that the cross stack redilaing timer has been expired. */
+ public void notifyCrossStackTimerExpired() {
+ logi("notifyCrossStackTimerExpired");
+
+ mCrossStackTimerExpired = true;
+ if (mDomainSelected) {
+ // When reselecting domain, terminateSelection will be called.
+ return;
+ }
+ terminateSelectionForCrossSimRedialing(false);
+ }
+
private static String arrayToString(int[] intArray, IntFunction<String> func) {
int length = intArray.length;
StringBuilder sb = new StringBuilder("{");
@@ -1303,6 +1379,7 @@
public void destroy() {
if (DBG) logd("destroy");
+ mCrossSimRedialingController.stopTimer();
releaseWakeLock();
mDestroyed = true;
diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
index 3da0044..f176d90 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -168,7 +168,7 @@
mStopDomainSelection = true;
if (mImsStateTracker.isImsRegisteredOverWlan()) {
logd("WLAN selected");
- mTransportSelectorCallback.onWlanSelected();
+ mTransportSelectorCallback.onWlanSelected(false);
} else {
if (mWwanSelectorCallback == null) {
mTransportSelectorCallback.onWwanSelected((callback) -> {
@@ -184,7 +184,7 @@
private void notifyPsSelectedInternal() {
if (mWwanSelectorCallback != null) {
logd("notifyPsSelected - onWwanSelected");
- mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS);
+ mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS, false);
} else {
loge("wwanSelectorCallback is null");
mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
@@ -207,7 +207,7 @@
private void notifyCsSelectedInternal() {
if (mWwanSelectorCallback != null) {
logd("wwanSelectorCallback -> onDomainSelected(DOMAIN_CS)");
- mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS);
+ mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS, false);
} else {
loge("wwanSelectorCallback is null");
mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
diff --git a/src/com/android/services/telephony/domainselection/SmsDomainSelector.java b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
index e7c9ac5..6930b13 100644
--- a/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
@@ -178,7 +178,7 @@
protected void notifyWlanSelected() {
logi("DomainSelected: WLAN");
- mTransportSelectorCallback.onWlanSelected();
+ mTransportSelectorCallback.onWlanSelected(false);
setDomainSelectionRequested(false);
}
@@ -199,7 +199,7 @@
logi("DomainSelected: WWAN/" + DomainSelectionService.getDomainName(domain));
if (mWwanSelectorCallback != null) {
- mWwanSelectorCallback.onDomainSelected(domain);
+ mWwanSelectorCallback.onDomainSelected(domain, false);
} else {
mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.LOCAL);
}
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
index 13db06b..3a8fc86 100644
--- a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -70,7 +70,8 @@
DomainSelectorBase create(Context context, int slotId, int subId,
@SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
@NonNull ImsStateTracker imsStateTracker,
- @NonNull DomainSelectorBase.DestroyListener listener);
+ @NonNull DomainSelectorBase.DestroyListener listener,
+ @NonNull CrossSimRedialingController crossSimRedialingController);
}
private static final class DefaultDomainSelectorFactory implements DomainSelectorFactory {
@@ -78,7 +79,8 @@
public DomainSelectorBase create(Context context, int slotId, int subId,
@SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
@NonNull ImsStateTracker imsStateTracker,
- @NonNull DomainSelectorBase.DestroyListener listener) {
+ @NonNull DomainSelectorBase.DestroyListener listener,
+ @NonNull CrossSimRedialingController crossSimRedialingController) {
DomainSelectorBase selector = null;
logi("create-DomainSelector: slotId=" + slotId + ", subId=" + subId
@@ -89,7 +91,7 @@
case SELECTOR_TYPE_CALLING:
if (isEmergency) {
selector = new EmergencyCallDomainSelector(context, slotId, subId, looper,
- imsStateTracker, listener);
+ imsStateTracker, listener, crossSimRedialingController);
} else {
selector = new NormalCallDomainSelector(context, slotId, subId, looper,
imsStateTracker, listener);
@@ -192,6 +194,7 @@
private final ImsStateTrackerFactory mImsStateTrackerFactory;
private final DomainSelectorFactory mDomainSelectorFactory;
private Handler mServiceHandler;
+ private CrossSimRedialingController mCrossSimRedialingController;
public TelephonyDomainSelectionService(Context context) {
this(context, ImsStateTracker::new, new DefaultDomainSelectorFactory());
@@ -221,6 +224,8 @@
loge("Adding OnSubscriptionChangedListener failed");
}
+ mCrossSimRedialingController = new CrossSimRedialingController(context, getLooper());
+
logi("TelephonyDomainSelectionService created");
}
@@ -258,6 +263,11 @@
sm.removeOnSubscriptionsChangedListener(mSubscriptionsChangedListener);
}
+ if (mCrossSimRedialingController != null) {
+ mCrossSimRedialingController.destroy();
+ mCrossSimRedialingController = null;
+ }
+
if (mServiceHandler != null) {
mServiceHandler.getLooper().quit();
mServiceHandler = null;
@@ -279,7 +289,8 @@
final boolean isEmergency = attr.isEmergency();
ImsStateTracker ist = getImsStateTracker(slotId);
DomainSelectorBase selector = mDomainSelectorFactory.create(mContext, slotId, subId,
- selectorType, isEmergency, getLooper(), ist, mDestroyListener);
+ selectorType, isEmergency, getLooper(), ist, mDestroyListener,
+ mCrossSimRedialingController);
if (selector != null) {
// Ensures that ImsStateTracker is started before selecting the domain if not started
diff --git a/testapps/TestRcsApp/TestApp/lint-baseline.xml b/testapps/TestRcsApp/TestApp/lint-baseline.xml
new file mode 100644
index 0000000..8971388
--- /dev/null
+++ b/testapps/TestRcsApp/TestApp/lint-baseline.xml
@@ -0,0 +1,829 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#bootstrapAuthenticationRequest`"
+ errorLine1=" telephonyManager.bootstrapAuthenticationRequest(mUiccType,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="130"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#build`"
+ errorLine1=" UaSecurityProtocolIdentifier spId = builder.build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="129"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setOrg`"
+ errorLine1=" builder.setOrg(mOrganization)"
+ errorLine2=" ~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="122"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setProtocol`"
+ errorLine1=" .setProtocol(mProtocol)"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="123"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setTlsCipherSuite`"
+ errorLine1=" .setTlsCipherSuite(Integer.parseInt(mTlsCs.getText().toString()));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="124"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.DelegateRegistrationState#getRegisteredFeatureTags`"
+ errorLine1=" Set<String> registeredFt = registrationState.getRegisteredFeatureTags();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="151"
+ column="66"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.FeatureTagState#getFeatureTag`"
+ errorLine1=' stringBuilder.append(featureTagState.getFeatureTag()).append(" ").append('
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="148"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.FeatureTagState#getState`"
+ errorLine1=" featureTagState.getState());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="149"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ImsManager#getSipDelegateManager`"
+ errorLine1=" mSipDelegateManager = imsManager.getSipDelegateManager(mDefaultSmsSubId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="220"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#isRcsVolteSingleRegistrationCapable`"
+ errorLine1=" boolean capable = mProvisioningManager.isRcsVolteSingleRegistrationCapable();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="204"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#isRcsVolteSingleRegistrationCapable`"
+ errorLine1=" mProvisioningManager.isRcsVolteSingleRegistrationCapable();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="166"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#registerRcsProvisioningCallback`"
+ errorLine1=" mProvisioningManager.registerRcsProvisioningCallback(mExecutorService,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="181"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#registerRcsProvisioningCallback`"
+ errorLine1=" mProvisioningManager.registerRcsProvisioningCallback(getMainExecutor(), mCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/FileUploadActivity.java"
+ line="221"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#setRcsClientConfiguration`"
+ errorLine1=" mProvisioningManager.setRcsClientConfiguration(getDefaultClientConfiguration());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="180"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#setRcsClientConfiguration`"
+ errorLine1=" mProvisioningManager.setRcsClientConfiguration(getDefaultClientConfiguration());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/FileUploadActivity.java"
+ line="220"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#unregisterRcsProvisioningCallback`"
+ errorLine1=" mProvisioningManager.unregisterRcsProvisioningCallback(mCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="195"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#unregisterRcsProvisioningCallback`"
+ errorLine1=" mProvisioningManager.unregisterRcsProvisioningCallback(mCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/FileUploadActivity.java"
+ line="348"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#unregisterRcsProvisioningCallback`"
+ errorLine1=" mProvisioningManager.unregisterRcsProvisioningCallback(mCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="152"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple#getContactUri`"
+ errorLine1=" b.append(t.getContactUri());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="220"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple#getServiceCapabilities`"
+ errorLine1=" t.getServiceCapabilities();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="227"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple#getServiceCapabilities`"
+ errorLine1=" if (t.getServiceCapabilities() != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="225"
+ column="23"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple#getServiceId`"
+ errorLine1=" b.append(t.getServiceId());"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="222"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple#getServiceVersion`"
+ errorLine1=" b.append(t.getServiceVersion());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="224"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities#getSupportedDuplexModes`"
+ errorLine1=" b.append(servCaps.getSupportedDuplexModes());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="233"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities#getUnsupportedDuplexModes`"
+ errorLine1=" b.append(servCaps.getUnsupportedDuplexModes());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="235"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities#isAudioCapable`"
+ errorLine1=" b.append(servCaps.isAudioCapable());"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="229"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities#isVideoCapable`"
+ errorLine1=" b.append(servCaps.isVideoCapable());"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="231"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactUceCapability#getCapabilityMechanism`"
+ errorLine1=" if (c.getCapabilityMechanism() == RcsContactUceCapability.CAPABILITY_MECHANISM_PRESENCE) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="216"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactUceCapability#getCapabilityTuples`"
+ errorLine1=" for (RcsContactPresenceTuple t : c.getCapabilityTuples()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="218"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactUceCapability#getContactUri`"
+ errorLine1=" b.append(c.getContactUri());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="211"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactUceCapability#getRequestResult`"
+ errorLine1=" b.append(c.getRequestResult());"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="213"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsContactUceCapability#getSourceType`"
+ errorLine1=" b.append(c.getSourceType());"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="215"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsUceAdapter#requestAvailability`"
+ errorLine1=" mImsRcsManager.getUceAdapter().requestAvailability(contactList.get(0),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="135"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.RcsUceAdapter#requestCapabilities`"
+ errorLine1=" mImsRcsManager.getUceAdapter().requestCapabilities(contactList, getMainExecutor(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="95"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getHomeDomain`"
+ errorLine1=' + ", \n\tmHomeDomain=" + config.getHomeDomain()'
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="341"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getImei`"
+ errorLine1=' + ", \n\tmImei=" + config.getImei()'
+ errorLine2=" ~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="342"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getIpSecConfiguration`"
+ errorLine1=' + ", \n\tmIpSecConfiguration=" + config.getIpSecConfiguration()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="354"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getLocalAddress`"
+ errorLine1=' + ", \n\tmLocalIpAddr=" + config.getLocalAddress()'
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="334"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getMaxUdpPayloadSizeBytes`"
+ errorLine1=' + ", \n\tmMaxUdpPayloadSize=" + config.getMaxUdpPayloadSizeBytes()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="338"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getNatSocketAddress`"
+ errorLine1=" + ", \n\tmNatConfiguration=" + config.getNatSocketAddress() + '}';"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="355"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPrivateUserIdentifier`"
+ errorLine1=' + ", \n\tmPrivateUserIdentifier=" + config.getPrivateUserIdentifier()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="340"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPublicGruuUri`"
+ errorLine1=' + ", \n\tmGruu=" + config.getPublicGruuUri()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="343"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPublicUserIdentifier`"
+ errorLine1=' + ", \n\tmPublicUserIdentifier=" + config.getPublicUserIdentifier()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="339"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAssociatedUriHeader`"
+ errorLine1=' + ", \n\tmAssociatedUriHeader=" + config.getSipAssociatedUriHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="353"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAuthenticationHeader`"
+ errorLine1=' + ", \n\tmSipAuthHeader=" + config.getSipAuthenticationHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="344"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAuthenticationNonce`"
+ errorLine1=' + ", \n\tmSipAuthNonce=" + config.getSipAuthenticationNonce()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="345"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipCniHeader`"
+ errorLine1=' + ", \n\tmCniHeader=" + config.getSipCniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="352"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipContactUserParameter`"
+ errorLine1=' + ", \n\tmContactUserParam=" + config.getSipContactUserParameter()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="349"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPaniHeader`"
+ errorLine1=' + ", \n\tmPaniHeader=" + config.getSipPaniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="350"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPathHeader`"
+ errorLine1=' + ", \n\tmPathHeader=" + config.getSipPathHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="347"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPlaniHeader`"
+ errorLine1=' + ", \n\tmPlaniHeader=" + config.getSipPlaniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="351"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServerAddress`"
+ errorLine1=' + ", \n\tmSipServerAddr=" + config.getSipServerAddress()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="335"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServiceRouteHeader`"
+ errorLine1=' + ", \n\tmServiceRouteHeader=" + config.getSipServiceRouteHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="346"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipUserAgentHeader`"
+ errorLine1=' + ", \n\tmUserAgentHeader=" + config.getSipUserAgentHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="348"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getTransportType`"
+ errorLine1=' + ", \n\tmTransportType=" + config.getTransportType()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="333"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getVersion`"
+ errorLine1=' + "mVersion=" + config.getVersion()'
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="332"
+ column="40"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#isSipCompactFormEnabled`"
+ errorLine1=' + ", \n\tmIsSipCompactFormEnabled=" + config.isSipCompactFormEnabled()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="336"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#isSipKeepaliveEnabled`"
+ errorLine1=' + ", \n\tmIsSipKeepaliveEnabled=" + config.isSipKeepaliveEnabled()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="337"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateManager#createSipDelegate`"
+ errorLine1=" mSipDelegateManager.createSipDelegate(new DelegateRequest(featureTags),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="231"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateManager#destroySipDelegate`"
+ errorLine1=" mSipDelegateManager.destroySipDelegate(mSipDelegateConnection,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="247"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateManager#destroySipDelegate`"
+ errorLine1=" mSipDelegateManager.destroySipDelegate(mSipDelegateConnection,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="322"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.gba.UaSecurityProtocolIdentifier.Builder`"
+ errorLine1=" new UaSecurityProtocolIdentifier.Builder();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="120"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.DelegateRequest`"
+ errorLine1=" mSipDelegateManager.createSipDelegate(new DelegateRequest(featureTags),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="231"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.RcsClientConfiguration`"
+ errorLine1=" return new RcsClientConfiguration("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/FileUploadActivity.java"
+ line="231"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.RcsClientConfiguration`"
+ errorLine1=" return new RcsClientConfiguration("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="106"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast to `BootstrapAuthenticationCallback` requires API level 31 (current min is 30)"
+ errorLine1=" new BootstrapAuthenticationCallback() {"
+ errorLine2=" ^">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="135"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast to `CapabilitiesCallback` requires API level 31 (current min is 30)"
+ errorLine1=" getMainExecutor(), new RcsUceAdapter.CapabilitiesCallback() {"
+ errorLine2=" ^">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="136"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast to `CapabilitiesCallback` requires API level 31 (current min is 30)"
+ errorLine1=" new RcsUceAdapter.CapabilitiesCallback() {"
+ errorLine2=" ^">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="96"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyManager.BootstrapAuthenticationCallback`"
+ errorLine1=" new BootstrapAuthenticationCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/GbaActivity.java"
+ line="135"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager.RcsProvisioningCallback`"
+ errorLine1=" new RcsProvisioningCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/FileUploadActivity.java"
+ line="89"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager.RcsProvisioningCallback`"
+ errorLine1=" new RcsProvisioningCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/ProvisioningActivity.java"
+ line="80"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.RcsUceAdapter.CapabilitiesCallback`"
+ errorLine1=" getMainExecutor(), new RcsUceAdapter.CapabilitiesCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="136"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.RcsUceAdapter.CapabilitiesCallback`"
+ errorLine1=" new RcsUceAdapter.CapabilitiesCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/UceActivity.java"
+ line="96"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.stub.DelegateConnectionMessageCallback`"
+ errorLine1=" new DelegateConnectionMessageCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="87"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.stub.DelegateConnectionStateCallback`"
+ errorLine1=" new DelegateConnectionStateCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/TestApp/src/com/google/android/sample/rcsclient/DelegateActivity.java"
+ line="117"
+ column="17"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/testapps/TestRcsApp/aosp_test_rcsclient/lint-baseline.xml b/testapps/TestRcsApp/aosp_test_rcsclient/lint-baseline.xml
new file mode 100644
index 0000000..e0c7c3e
--- /dev/null
+++ b/testapps/TestRcsApp/aosp_test_rcsclient/lint-baseline.xml
@@ -0,0 +1,928 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.net.ConnectivityManager#registerQosCallback`"
+ errorLine1=" connectivityManager.registerQosCallback(new QosSocketInfo(network, socket),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/protocol/msrp/MsrpSession.java"
+ line="118"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.net.ConnectivityManager#unregisterQosCallback`"
+ errorLine1=" connectivityManager.unregisterQosCallback(qosCallback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/protocol/msrp/MsrpSession.java"
+ line="181"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#bootstrapAuthenticationRequest`"
+ errorLine1=" telephonyManager.bootstrapAuthenticationRequest("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="97"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#build`"
+ errorLine1=" UaSecurityProtocolIdentifier spId = builder.build();"
+ errorLine2=" ~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="79"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setOrg`"
+ errorLine1=" builder.setOrg(organization)"
+ errorLine2=" ~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="67"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setProtocol`"
+ errorLine1=" .setProtocol(protocol);"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="68"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setTlsCipherSuite`"
+ errorLine1=" builder.setTlsCipherSuite(TlsParams.TLS_RSA_WITH_AES_128_CBC_SHA);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="70"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.gba.UaSecurityProtocolIdentifier.Builder#setTlsCipherSuite`"
+ errorLine1=" builder.setTlsCipherSuite(cipherSuite);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="72"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.DelegateRegistrationState#getRegisteredFeatureTags`"
+ errorLine1=" .getRegisteredFeatureTags()"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="139"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.DelegateRegistrationState#getRegisteredFeatureTags`"
+ errorLine1=" Set<String> registeredFt = registrationState.getRegisteredFeatureTags();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="223"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.FeatureTagState#getFeatureTag`"
+ errorLine1=' stringBuilder.append(featureTagState.getFeatureTag()).append(" ").append('
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="220"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.FeatureTagState#getState`"
+ errorLine1=" featureTagState.getState());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="221"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ImsManager#getSipDelegateManager`"
+ errorLine1=" this.sipDelegateManager = imsManager.getSipDelegateManager(subscriptionId);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="77"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#isRcsVolteSingleRegistrationCapable`"
+ errorLine1=" return provisioningManager.isRcsVolteSingleRegistrationCapable();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="166"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#registerRcsProvisioningCallback`"
+ errorLine1=" provisioningManager.registerRcsProvisioningCallback(executorService, callback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="147"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#setRcsClientConfiguration`"
+ errorLine1=" provisioningManager.setRcsClientConfiguration(clientConfiguration);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="111"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#triggerRcsReconfiguration`"
+ errorLine1=" provisioningManager.triggerRcsReconfiguration();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="176"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager#unregisterRcsProvisioningCallback`"
+ errorLine1=" provisioningManager.unregisterRcsProvisioningCallback(callback);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="158"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getHomeDomain`"
+ errorLine1=' + ", \n\tmHomeDomain=" + config.getHomeDomain()'
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="246"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getHomeDomain`"
+ errorLine1=" return mConfiguration.getHomeDomain();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="317"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getImei`"
+ errorLine1=' + ", \n\tmImei=" + config.getImei()'
+ errorLine2=" ~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="247"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getImei`"
+ errorLine1=" return mConfiguration.getImei();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="357"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getIpSecConfiguration`"
+ errorLine1=' + ", \n\tmIpSecConfiguration=" + config.getIpSecConfiguration()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="259"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getIpSecConfiguration`"
+ errorLine1=" SipDelegateConfiguration.IpSecConfiguration c = mConfiguration.getIpSecConfiguration();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="333"
+ column="76"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getLocalAddress`"
+ errorLine1=' + ", \n\tmLocalAddr=" + config.getLocalAddress()'
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="239"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getLocalAddress`"
+ errorLine1=" return mConfiguration.getLocalAddress().getAddress().getHostAddress();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="296"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getLocalAddress`"
+ errorLine1=" return mConfiguration.getLocalAddress().getPort();"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="301"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getMaxUdpPayloadSizeBytes`"
+ errorLine1=' + ", \n\tmMaxUdpPayloadSize=" + config.getMaxUdpPayloadSizeBytes()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="243"
+ column="60"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getMaxUdpPayloadSizeBytes`"
+ errorLine1=" ? mConfiguration.getMaxUdpPayloadSizeBytes() : 1500;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="378"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getMaxUdpPayloadSizeBytes`"
+ errorLine1=" return mConfiguration.getMaxUdpPayloadSizeBytes() > 0"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="377"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getNatSocketAddress`"
+ errorLine1=" + ", \n\tmNatConfiguration=" + config.getNatSocketAddress() + '}';"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="260"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPrivateUserIdentifier`"
+ errorLine1=' + ", \n\tmPrivateUserIdentifier=" + config.getPrivateUserIdentifier()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="245"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPublicGruuUri`"
+ errorLine1=' + ", \n\tmGruu=" + config.getPublicGruuUri()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="248"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPublicUserIdentifier`"
+ errorLine1=' + ", \n\tmPublicUserIdentifier=" + config.getPublicUserIdentifier()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="244"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getPublicUserIdentifier`"
+ errorLine1=" return mConfiguration.getPublicUserIdentifier();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="312"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAssociatedUriHeader`"
+ errorLine1=' + ", \n\tmAssociatedUriHeader=" + config.getSipAssociatedUriHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="258"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAssociatedUriHeader`"
+ errorLine1=" String associatedUris = mConfiguration.getSipAssociatedUriHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="322"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAuthenticationHeader`"
+ errorLine1=' + ", \n\tmSipAuthHeader=" + config.getSipAuthenticationHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="249"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipAuthenticationNonce`"
+ errorLine1=' + ", \n\tmSipAuthNonce=" + config.getSipAuthenticationNonce()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="250"
+ column="55"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipCniHeader`"
+ errorLine1=' + ", \n\tmCniHeader=" + config.getSipCniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="257"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipContactUserParameter`"
+ errorLine1=' + ", \n\tmContactUserParam=" + config.getSipContactUserParameter()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="254"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipContactUserParameter`"
+ errorLine1=" return mConfiguration.getSipContactUserParameter();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="352"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPaniHeader`"
+ errorLine1=' + ", \n\tmPaniHeader=" + config.getSipPaniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="255"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPaniHeader`"
+ errorLine1=" return mConfiguration.getSipPaniHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="362"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPathHeader`"
+ errorLine1=' + ", \n\tmPathHeader=" + config.getSipPathHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="252"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPlaniHeader`"
+ errorLine1=' + ", \n\tmPlaniHeader=" + config.getSipPlaniHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="256"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipPlaniHeader`"
+ errorLine1=" return mConfiguration.getSipPlaniHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="367"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServerAddress`"
+ errorLine1=' + ", \n\tmSipServerAddr=" + config.getSipServerAddress()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="240"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServerAddress`"
+ errorLine1=" return mConfiguration.getSipServerAddress().getAddress().getHostAddress();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="286"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServerAddress`"
+ errorLine1=" return mConfiguration.getSipServerAddress().getPort();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="291"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServiceRouteHeader`"
+ errorLine1=' + ", \n\tmServiceRouteHeader=" + config.getSipServiceRouteHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="251"
+ column="61"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipServiceRouteHeader`"
+ errorLine1=" mConfiguration.getSipServiceRouteHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="343"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipUserAgentHeader`"
+ errorLine1=' + ", \n\tmUserAgentHeader=" + config.getSipUserAgentHeader()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="253"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getSipUserAgentHeader`"
+ errorLine1=" return mConfiguration.getSipUserAgentHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="372"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getTransportType`"
+ errorLine1=' + ", \n\tmTransportType=" + config.getTransportType()'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="238"
+ column="56"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getTransportType`"
+ errorLine1=" int sipTransport = mConfiguration.getTransportType();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="306"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getVersion`"
+ errorLine1=" + registeredSipConfig.getVersion());"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="127"
+ column="63"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getVersion`"
+ errorLine1=' + "mVersion=" + config.getVersion()'
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="237"
+ column="44"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#getVersion`"
+ errorLine1=" return mConfiguration.getVersion();"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="281"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#isSipCompactFormEnabled`"
+ errorLine1=' + ", \n\tmIsSipCompactFormEnabled=" + config.isSipCompactFormEnabled()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="241"
+ column="66"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration#isSipKeepaliveEnabled`"
+ errorLine1=' + ", \n\tmIsSipKeepaliveEnabled=" + config.isSipKeepaliveEnabled()'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="242"
+ column="64"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration#getSipSecurityVerifyHeader`"
+ errorLine1=" return c.getSipSecurityVerifyHeader();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="337"
+ column="22"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateConnection#sendMessage`"
+ errorLine1=" sipDelegateConnection.sendMessage(MessageConverter.toPlatformMessage(message),"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="271"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateManager#createSipDelegate`"
+ errorLine1=" controller.sipDelegateManager.createSipDelegate("
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="205"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipDelegateManager#destroySipDelegate`"
+ errorLine1=" sipDelegateManager.destroySipDelegate(context.sipDelegateConnection,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="92"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#getContent`"
+ errorLine1=" return new SipMessage(message.getStartLine(), headers, message.getContent());"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="395"
+ column="76"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#getHeaderSection`"
+ errorLine1=' + message.getHeaderSection().substring(0, 10) + "->"'
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="392"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#getHeaderSection`"
+ errorLine1=" String headers = message.getHeaderSection();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="387"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#getStartLine`"
+ errorLine1=" return new SipMessage(message.getStartLine(), headers, message.getContent());"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="395"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#toEncodedMessage`"
+ errorLine1=" message.toEncodedMessage(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/MessageConverter.java"
+ line="91"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.ims.SipMessage#toEncodedMessage`"
+ errorLine1=" return (Message) method.invoke(new StringMsgParser(), message.toEncodedMessage());"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/MessageConverter.java"
+ line="101"
+ column="79"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.net.QosSocketInfo`"
+ errorLine1=" connectivityManager.registerQosCallback(new QosSocketInfo(network, socket),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/protocol/msrp/MsrpSession.java"
+ line="118"
+ column="53"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.gba.UaSecurityProtocolIdentifier.Builder`"
+ errorLine1=" new UaSecurityProtocolIdentifier.Builder();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="55"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.DelegateRequest`"
+ errorLine1=" DelegateRequest request = new DelegateRequest(imsService.getFeatureTags());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="203"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.RcsClientConfiguration`"
+ errorLine1=" return new RcsClientConfiguration("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="74"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.SipMessage`"
+ errorLine1=" return new SipMessage(message.getStartLine(), headers, message.getContent());"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="395"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.telephony.ims.SipMessage`"
+ errorLine1=" return new SipMessage(startLine, headers.toString(), rawContent);"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/MessageConverter.java"
+ line="72"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast to `BootstrapAuthenticationCallback` requires API level 31 (current min is 30)"
+ errorLine1=" new TelephonyManager.BootstrapAuthenticationCallback() {"
+ errorLine2=" ^">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="81"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast to `RcsProvisioningCallback` requires API level 31 (current min is 30)"
+ errorLine1=" new RcsProvisioningCallback() {"
+ errorLine2=" ^">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="114"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.net.QosCallback`"
+ errorLine1=" private final QosCallback qosCallback = new QosCallback() {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/protocol/msrp/MsrpSession.java"
+ line="94"
+ column="49"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyManager.BootstrapAuthenticationCallback`"
+ errorLine1=" new TelephonyManager.BootstrapAuthenticationCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/filetransfer/requestexecutor/GbaAuthenticationProvider.java"
+ line="81"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.ProvisioningManager.RcsProvisioningCallback`"
+ errorLine1=" new RcsProvisioningCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/provisioning/StaticConfigProvisioningController.java"
+ line="114"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.stub.DelegateConnectionMessageCallback`"
+ errorLine1=" new DelegateConnectionMessageCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="158"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.ims.stub.DelegateConnectionStateCallback`"
+ errorLine1=" new DelegateConnectionStateCallback() {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/services/Telephony/testapps/TestRcsApp/aosp_test_rcsclient/src/com/android/libraries/rcs/simpleclient/registration/RegistrationControllerImpl.java"
+ line="114"
+ column="21"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/tests/src/com/android/phone/PhoneUtilsTest.java b/tests/src/com/android/phone/PhoneUtilsTest.java
index b5ff0dc..3d7815c 100644
--- a/tests/src/com/android/phone/PhoneUtilsTest.java
+++ b/tests/src/com/android/phone/PhoneUtilsTest.java
@@ -82,8 +82,8 @@
public void testMakePstnPhoneAccountHandleWithPrefix() throws Exception {
PhoneAccountHandle phoneAccountHandleTest = new PhoneAccountHandle(
PSTN_CONNECTION_SERVICE_COMPONENT, mPhoneAccountHandleIdString);
- assertEquals(phoneAccountHandleTest, PhoneUtils.makePstnPhoneAccountHandleWithPrefix(
- mPhoneAccountHandleIdString, "", false, null));
+ assertEquals(phoneAccountHandleTest, PhoneUtils.makePstnPhoneAccountHandleWithId(
+ mPhoneAccountHandleIdString, null));
}
@Test
@@ -91,7 +91,7 @@
UserHandle userHandle = new UserHandle(10);
PhoneAccountHandle phoneAccountHandleTest = new PhoneAccountHandle(
PSTN_CONNECTION_SERVICE_COMPONENT, mPhoneAccountHandleIdString, userHandle);
- assertEquals(phoneAccountHandleTest, PhoneUtils.makePstnPhoneAccountHandleWithPrefix(
- mPhoneAccountHandleIdString, "", false, userHandle));
+ assertEquals(phoneAccountHandleTest, PhoneUtils.makePstnPhoneAccountHandleWithId(
+ mPhoneAccountHandleIdString, userHandle));
}
}
diff --git a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
index 921babb..544d7ea 100644
--- a/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
+++ b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
@@ -715,7 +715,7 @@
doReturn(TelephonyManager.NETWORK_TYPE_NR).when(mServiceState).getDataNetworkType();
// entitlement check passed
mEntitlementResponse.mEntitlementStatus =
- PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED;
+ PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_DISABLED;
// send purchase request
mSlicePurchaseController.purchasePremiumCapability(
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index fcef25a..e2a199b 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -643,7 +643,7 @@
ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
mMockTelephonyConnectionServiceProxy, mConferenceHost,
- null /* phoneAccountHandle */, () -> false /* featureFlagProxy */,
+ null /* phoneAccountHandle */, () -> true /* isUsingSinglePartyCallEmulation */,
new ImsConference.CarrierConfiguration.Builder()
.setShouldLocalDisconnectEmptyConference(true)
.build());
@@ -675,6 +675,109 @@
}
/**
+ * Preconditions: both single party emulation and local disconnect of empty conferences is
+ * enabled.
+ * Tests the case where we receive a repeat with the same single-party data that caused a
+ * conference to be treated as a single party; we need to verify that we do not disconnect the
+ * conference locally in this case.
+ * @throws Exception
+ */
+ @Test
+ @SmallTest
+ public void testNoLocalDisconnectSinglePartyConferenceOnRepeatedCep() throws Exception {
+ when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+ .thenReturn(false);
+
+ ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+ mMockTelephonyConnectionServiceProxy, mConferenceHost,
+ null /* phoneAccountHandle */, () -> true /* isUsingSinglePartyCallEmulation */,
+ new ImsConference.CarrierConfiguration.Builder()
+ .setShouldLocalDisconnectEmptyConference(true)
+ .build());
+
+ ConferenceParticipant participant1 = new ConferenceParticipant(
+ Uri.parse("tel:6505551212"),
+ "A",
+ Uri.parse("sip:6505551212@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ ConferenceParticipant participant2 = new ConferenceParticipant(
+ Uri.parse("tel:6505551213"),
+ "A",
+ Uri.parse("sip:6505551213@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1, participant2));
+ assertEquals(2, imsConference.getNumberOfParticipants());
+
+ // Drop to 1 participant which enters single party mode.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ assertEquals(0, imsConference.getNumberOfParticipants());
+
+ // Get a repeat CEP with the same participant data; we should still be in single party mode
+ // but we should NOT disconnect the conference.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ assertEquals(0, imsConference.getNumberOfParticipants());
+ verify(mConferenceHost.mMockCall, never()).hangup();
+ }
+
+ /**
+ * An extension of {@link #testNoLocalDisconnectSinglePartyConferenceOnRepeatedCep()} where we
+ * get a repeated CEP with the same single party state, but then finally get a CEP with no
+ * participants anymore. In this case we do expect a local disconnect as the final state.
+ * @throws Exception
+ */
+ @Test
+ @SmallTest
+ public void testLocalDisconnectSinglePartyConferenceOnRepeatedCep() throws Exception {
+ when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+ .thenReturn(false);
+
+ ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+ mMockTelephonyConnectionServiceProxy, mConferenceHost,
+ null /* phoneAccountHandle */, () -> true /* isUsingSinglePartyCallEmulation */,
+ new ImsConference.CarrierConfiguration.Builder()
+ .setShouldLocalDisconnectEmptyConference(true)
+ .build());
+
+ ConferenceParticipant participant1 = new ConferenceParticipant(
+ Uri.parse("tel:6505551212"),
+ "A",
+ Uri.parse("sip:6505551212@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ ConferenceParticipant participant2 = new ConferenceParticipant(
+ Uri.parse("tel:6505551213"),
+ "A",
+ Uri.parse("sip:6505551213@testims.com"),
+ Connection.STATE_ACTIVE,
+ Call.Details.DIRECTION_INCOMING);
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1, participant2));
+ assertEquals(2, imsConference.getNumberOfParticipants());
+
+ // Drop to 1 participant which enters single party mode.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ assertEquals(0, imsConference.getNumberOfParticipants());
+
+ // Get a repeat CEP with the same participant data; we should still be in single party mode
+ // but we should NOT disconnect the conference.
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+ Arrays.asList(participant1));
+ assertEquals(0, imsConference.getNumberOfParticipants());
+ verify(mConferenceHost.mMockCall, never()).hangup();
+
+ // Got another CEP that has no participants at all; we should disconnet in this case
+ imsConference.handleConferenceParticipantsUpdate(mConferenceHost, Collections.emptyList());
+ assertEquals(0, imsConference.getNumberOfParticipants());
+ verify(mConferenceHost.mMockCall).hangup();
+ }
+
+ /**
* Tests a scenario where a handover connection arrives via
* {@link TelephonyConnection#onOriginalConnectionRedialed(
* com.android.internal.telephony.Connection)}. During this process, the conference properties
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index b156103..f115a43 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -55,7 +55,9 @@
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.telecom.Conference;
+import android.telecom.Conferenceable;
import android.telecom.ConnectionRequest;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccountHandle;
@@ -91,6 +93,7 @@
import com.android.internal.telephony.emergency.EmergencyStateTracker;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.internal.telephony.satellite.SatelliteSOSMessageRecommender;
import org.junit.After;
import org.junit.Before;
@@ -122,6 +125,7 @@
public static class SimpleTelephonyConnection extends TelephonyConnection {
public boolean wasDisconnected = false;
public boolean wasUnheld = false;
+ public boolean wasHeld = false;
@Override
public TelephonyConnection cloneConnection() {
@@ -137,6 +141,11 @@
public void onUnhold() {
wasUnheld = true;
}
+
+ @Override
+ public void onHold() {
+ wasHeld = true;
+ }
}
public static class SimpleConference extends Conference {
@@ -190,6 +199,8 @@
@Mock EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
@Mock NormalCallDomainSelectionConnection mNormalCallDomainSelectionConnection;
@Mock ImsPhone mImsPhone;
+ @Mock
+ private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
private EmergencyStateTracker mEmergencyStateTracker;
private Phone mPhone0;
private Phone mPhone1;
@@ -216,6 +227,7 @@
@Before
public void setUp() throws Exception {
super.setUp();
+ doReturn(Looper.getMainLooper()).when(mContext).getMainLooper();
mTestConnectionService = new TestTelephonyConnectionService(mContext);
mTestConnectionService.setPhoneFactoryProxy(mPhoneFactoryProxy);
mTestConnectionService.setSubscriptionManagerProxy(mSubscriptionManagerProxy);
@@ -241,6 +253,11 @@
mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
replaceInstance(TelephonyConnectionService.class, "mEmergencyStateTracker",
mTestConnectionService, mEmergencyStateTracker);
+ replaceInstance(TelephonyConnectionService.class, "mSatelliteSOSMessageRecommender",
+ mTestConnectionService, mSatelliteSOSMessageRecommender);
+ doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), any());
+ doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallConnectionStateChanged(
+ anyString(), anyInt());
doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
.when(mEmergencyStateTracker)
.startEmergencyCall(any(), anyString(), eq(false));
@@ -1262,6 +1279,7 @@
// This shouldn't happen
fail();
}
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), any());
}
/**
@@ -1666,6 +1684,24 @@
}
/**
+ * For DSDA devices, placing an outgoing call on a 2nd sub will hold the existing connection on
+ * the first sub.
+ */
+ @Test
+ @SmallTest
+ public void testHoldOnOtherSubForVirtualDsdaDevice() {
+ when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true);
+
+ ArrayList<android.telecom.Connection> tcs = new ArrayList<>();
+ SimpleTelephonyConnection tc1 = createTestConnection(SUB1_HANDLE, 0, false);
+ tcs.add(tc1);
+ Conferenceable c = TelephonyConnectionService.maybeHoldCallsOnOtherSubs(
+ tcs, new ArrayList<>(), SUB2_HANDLE, mTelephonyManagerProxy);
+ assertTrue(c.equals(tc1));
+ assertTrue(tc1.wasHeld);
+ }
+
+ /**
* Verifies that TelephonyManager is used to determine whether a connection is Emergency when
* creating an outgoing connection.
*/
@@ -1699,6 +1735,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -1728,6 +1765,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -1758,6 +1796,7 @@
verify(mEmergencyStateTracker, times(1))
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mDomainSelectionResolver, times(0))
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyCallDomainSelectionConnection, times(0))
@@ -1851,6 +1890,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -1888,6 +1928,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -1928,6 +1969,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2191,6 +2233,7 @@
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
// dialing is canceled
mTestConnectionService.onLocalHangup(c);
@@ -2258,6 +2301,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
verify(mPhone0).dial(anyString(), any(), any());
@@ -2269,6 +2313,8 @@
TelephonyConnection.TelephonyConnectionListener connectionListener =
mTestConnectionService.getEmergencyConnectionListener();
+ TelephonyConnection.TelephonyConnectionListener connectionSatelliteListener =
+ mTestConnectionService.getEmergencyConnectionSatelliteListener();
connectionListener.onOriginalConnectionConfigured(c);
@@ -2277,32 +2323,44 @@
verify(mEmergencyStateTracker, times(0)).onEmergencyCallStateChanged(
any(), eq(TELECOM_CALL_ID1));
+ verify(mSatelliteSOSMessageRecommender, times(0))
+ .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
c.setActive();
doReturn(Call.State.ACTIVE).when(orgConn).getState();
connectionListener.onStateChanged(c, c.getState());
+ connectionSatelliteListener.onStateChanged(c, c.getState());
// ACTIVE sate is notified
verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
eq(Call.State.ACTIVE), eq(TELECOM_CALL_ID1));
+ verify(mSatelliteSOSMessageRecommender, times(1))
+ .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1),
+ eq(android.telecom.Connection.STATE_ACTIVE));
// state change to HOLDING
c.setOnHold();
doReturn(Call.State.HOLDING).when(orgConn).getState();
connectionListener.onStateChanged(c, c.getState());
+ connectionSatelliteListener.onStateChanged(c, c.getState());
// state change not notified any more after CONNECTED once
verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
any(), eq(TELECOM_CALL_ID1));
+ verify(mSatelliteSOSMessageRecommender, times(1))
+ .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
// state change to ACTIVE again
c.setActive();
doReturn(Call.State.ACTIVE).when(orgConn).getState();
connectionListener.onStateChanged(c, c.getState());
+ connectionSatelliteListener.onStateChanged(c, c.getState());
// state change not notified any more after CONNECTED once
verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
any(), eq(TELECOM_CALL_ID1));
+ verify(mSatelliteSOSMessageRecommender, times(1))
+ .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
// SRVCC happens
c.setIsImsConnection(false);
@@ -2318,10 +2376,51 @@
c.setDisconnected(null);
doReturn(Call.State.DISCONNECTED).when(orgConn).getState();
connectionListener.onStateChanged(c, c.getState());
+ connectionSatelliteListener.onStateChanged(c, c.getState());
// state change not notified
verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
any(), eq(TELECOM_CALL_ID1));
+ verify(mSatelliteSOSMessageRecommender, times(1))
+ .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
+ }
+
+ @Test
+ public void testDomainSelectionTempFailure() throws Exception {
+ setupForCallTest();
+
+ int preciseDisconnectCause =
+ com.android.internal.telephony.CallFailCause.EMERGENCY_TEMP_FAILURE;
+ int disconnectCause = android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE;
+ int selectedDomain = DOMAIN_CS;
+
+ TestTelephonyConnection c = setupForReDialForDomainSelection(
+ mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+ doReturn(new CompletableFuture()).when(mEmergencyCallDomainSelectionConnection)
+ .reselectDomain(any());
+
+ assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+ verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
+ }
+
+ @Test
+ public void testDomainSelectionPermFailure() throws Exception {
+ setupForCallTest();
+
+ int preciseDisconnectCause =
+ com.android.internal.telephony.CallFailCause.EMERGENCY_PERM_FAILURE;
+ int disconnectCause = android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE;
+ int selectedDomain = DOMAIN_CS;
+
+ TestTelephonyConnection c = setupForReDialForDomainSelection(
+ mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+ doReturn(new CompletableFuture()).when(mEmergencyCallDomainSelectionConnection)
+ .reselectDomain(any());
+
+ assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+ verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
}
@Test
@@ -2348,6 +2447,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2372,6 +2472,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index 758ded7..bf9fa01 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -1,6 +1,9 @@
package com.android.services.telephony;
import static android.telecom.Connection.STATE_DISCONNECTED;
+import static android.telephony.ims.ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED;
+import static android.telephony.ims.ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL;
+import static android.telephony.ims.ImsReasonInfo.EXTRA_CODE_CALL_RETRY_EMERGENCY;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -23,6 +26,8 @@
import android.telecom.Connection;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
+import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
import androidx.test.runner.AndroidJUnit4;
@@ -39,6 +44,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+
@RunWith(AndroidJUnit4.class)
public class TelephonyConnectionTest {
@Mock
@@ -306,4 +313,58 @@
assertNotEquals(STATE_DISCONNECTED, c.getState());
assertTrue(c.isOriginalConnectionCleared());
}
+
+ @Test
+ public void testDomainSelectionDisconnected_AlternateService() {
+ TestTelephonyConnection c = new TestTelephonyConnection();
+ c.setOriginalConnection(mImsPhoneConnection);
+ c.setIsImsConnection(true);
+ doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+ .getState();
+ doReturn(new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null))
+ .when(mImsPhoneConnection).getImsReasonInfo();
+ doReturn(getEmergencyNumber(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE))
+ .when(mImsPhoneConnection).getEmergencyNumberInfo();
+ c.setTelephonyConnectionService(mTelephonyConnectionService);
+ doReturn(true).when(mTelephonyConnectionService)
+ .maybeReselectDomain(any(), anyInt(), any());
+ c.updateState();
+
+ Integer serviceCategory = c.getEmergencyServiceCategory();
+
+ assertNotNull(serviceCategory);
+ assertEquals(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+ serviceCategory.intValue());
+ }
+
+ @Test
+ public void testDomainSelectionDisconnected_SilentRedialEmergency() {
+ TestTelephonyConnection c = new TestTelephonyConnection();
+ c.setOriginalConnection(mImsPhoneConnection);
+ c.setIsImsConnection(true);
+ doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+ .getState();
+ doReturn(new ImsReasonInfo(CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
+ EXTRA_CODE_CALL_RETRY_EMERGENCY, null))
+ .when(mImsPhoneConnection).getImsReasonInfo();
+ doReturn(getEmergencyNumber(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE))
+ .when(mImsPhoneConnection).getEmergencyNumberInfo();
+ c.setTelephonyConnectionService(mTelephonyConnectionService);
+ doReturn(true).when(mTelephonyConnectionService)
+ .maybeReselectDomain(any(), anyInt(), any());
+ c.updateState();
+
+ Integer serviceCategory = c.getEmergencyServiceCategory();
+
+ assertNotNull(serviceCategory);
+ assertEquals(EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+ serviceCategory.intValue());
+ }
+
+ private EmergencyNumber getEmergencyNumber(int eccCategory) {
+ return new EmergencyNumber("", "", "", eccCategory,
+ new ArrayList<String>(),
+ EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+ EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
+ }
}
diff --git a/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java b/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java
new file mode 100644
index 0000000..a32329d
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.REDIAL_TIMER_DISABLED;
+import static android.telephony.PreciseDisconnectCause.EMERGENCY_PERM_FAILURE;
+import static android.telephony.PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE;
+
+import static com.android.services.telephony.domainselection.CrossSimRedialingController.MSG_CROSS_STACK_TIMEOUT;
+import static com.android.services.telephony.domainselection.CrossSimRedialingController.MSG_QUICK_CROSS_STACK_TIMEOUT;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
+import android.testing.TestableLooper;
+import android.util.Log;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for CrossSimRedialingController
+ */
+public class CrossSimRedialingControllerTest {
+ private static final String TAG = "CrossSimRedialingControllerTest";
+
+ private static final int SLOT_0 = 0;
+ private static final int SLOT_1 = 1;
+
+ private static final String TELECOM_CALL_ID1 = "TC1";
+ private static final String TEST_EMERGENCY_NUMBER = "911";
+
+ @Mock private CarrierConfigManager mCarrierConfigManager;
+ @Mock private TelephonyManager mTelephonyManager;
+ @Mock private EmergencyCallDomainSelector mEcds;
+ @Mock private CrossSimRedialingController.EmergencyNumberHelper mEmergencyNumberHelper;
+
+ private Context mContext;
+
+ private HandlerThread mHandlerThread;
+ private TestableLooper mLooper;
+ private CrossSimRedialingController mCsrController;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = new TestContext() {
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ if (serviceClass == TelephonyManager.class) {
+ return Context.TELEPHONY_SERVICE;
+ } else if (serviceClass == CarrierConfigManager.class) {
+ return Context.CARRIER_CONFIG_SERVICE;
+ }
+ return super.getSystemServiceName(serviceClass);
+ }
+
+ @Override
+ public String getOpPackageName() {
+ return "";
+ }
+ };
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mHandlerThread = new HandlerThread("CrossSimRedialingControllerTest");
+ mHandlerThread.start();
+
+ try {
+ mLooper = new TestableLooper(mHandlerThread.getLooper());
+ } catch (Exception e) {
+ logd("Unable to create looper from handler.");
+ }
+
+ mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+ when(mTelephonyManager.createForSubscriptionId(anyInt()))
+ .thenReturn(mTelephonyManager);
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
+ doReturn(2).when(mTelephonyManager).getActiveModemCount();
+ doReturn(TelephonyManager.SIM_STATE_READY)
+ .when(mTelephonyManager).getSimState(anyInt());
+
+ mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+ doReturn(getDefaultPersistableBundle()).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ doReturn(true).when(mEmergencyNumberHelper).isEmergencyNumber(anyInt(), anyString());
+
+ doReturn(SLOT_0).when(mEcds).getSlotId();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mCsrController != null) {
+ mCsrController.destroy();
+ mCsrController = null;
+ }
+
+ if (mLooper != null) {
+ mLooper.destroy();
+ mLooper = null;
+ }
+ }
+
+ @Test
+ public void testDefaultStartTimerInService() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds).notifyCrossStackTimerExpired();
+ }
+
+ @Test
+ public void testDefaultStartTimerInServiceRoaming() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = true;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testDefaultStartTimerOutOfService() throws Exception {
+ createController();
+
+ boolean inService = false;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testDefaultStartTimerOutOfServiceRoaming() throws Exception {
+ createController();
+
+ boolean inService = false;
+ boolean inRoaming = true;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testQuickStartTimerInService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.sendEmptyMessage(MSG_QUICK_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds).notifyCrossStackTimerExpired();
+ }
+
+ @Test
+ public void testQuickStartTimerInServiceRoaming() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = true;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testQuickStartTimerOutOfService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = false;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testQuickStartTimerOutOfServiceRoaming() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = false;
+ boolean inRoaming = true;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testNoNormalStartTimerInService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testQuickWhenInServiceStartTimerOutOfService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL, true);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = false;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testQuickNoNormalStartTimerInService() throws Exception {
+ PersistableBundle bundle = getDefaultPersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
+ bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
+ doReturn(bundle).when(mCarrierConfigManager)
+ .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
+
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testDefaultSlot0ThenSlot1() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.removeMessages(MSG_CROSS_STACK_TIMEOUT);
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(SLOT_1).when(mEcds).getSlotId();
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+ }
+
+ @Test
+ public void testDefaultSlot0PermThenSlot1Timeout() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.notifyCallFailure(EMERGENCY_PERM_FAILURE);
+ mCsrController.stopTimer();
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(SLOT_1).when(mEcds).getSlotId();
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds, times(0)).notifyCrossStackTimerExpired();
+ }
+
+ @Test
+ public void testDefaultSlot0TempThenSlot1Timeout() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
+ mCsrController.stopTimer();
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(SLOT_1).when(mEcds).getSlotId();
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds).notifyCrossStackTimerExpired();
+ }
+
+ @Test
+ public void testDefaultSlot0TempThenSlot1TimeoutNotEmergencyNumber() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
+ mCsrController.stopTimer();
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(SLOT_1).when(mEcds).getSlotId();
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(false).when(mEmergencyNumberHelper).isEmergencyNumber(anyInt(), anyString());
+ mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds, times(0)).notifyCrossStackTimerExpired();
+ }
+
+ @Test
+ public void testDefaultSlot0TempThenSlot1TimeoutPinLocked() throws Exception {
+ createController();
+
+ boolean inService = true;
+ boolean inRoaming = false;
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
+ mCsrController.stopTimer();
+ assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(SLOT_1).when(mEcds).getSlotId();
+ mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
+ TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
+
+ assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
+
+ doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+ .when(mTelephonyManager).getSimState(anyInt());
+ mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
+ processAllMessages();
+
+ verify(mEcds, times(0)).notifyCrossStackTimerExpired();
+ }
+
+ private void createController() throws Exception {
+ mCsrController = new CrossSimRedialingController(mContext,
+ mHandlerThread.getLooper(), mEmergencyNumberHelper);
+ }
+
+ private static PersistableBundle getDefaultPersistableBundle() {
+ return getPersistableBundle(0, 120, false);
+ }
+
+ private static PersistableBundle getPersistableBundle(
+ int quickTimer, int timer, boolean startQuickInService) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, quickTimer);
+ bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, timer);
+ bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,
+ startQuickInService);
+
+ return bundle;
+ }
+
+ private void processAllMessages() {
+ while (!mLooper.getLooper().getQueue().isIdle()) {
+ mLooper.processAllMessages();
+ }
+ }
+
+ private static void logd(String str) {
+ Log.d(TAG, str);
+ }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 6c7f220..0821943 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -60,6 +60,7 @@
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
@@ -90,6 +91,7 @@
import android.telephony.DomainSelectionService.SelectionAttributes;
import android.telephony.EmergencyRegResult;
import android.telephony.NetworkRegistrationInfo;
+import android.telephony.PreciseDisconnectCause;
import android.telephony.TelephonyManager;
import android.telephony.TransportSelectorCallback;
import android.telephony.WwanSelectorCallback;
@@ -133,6 +135,7 @@
@Mock private ImsStateTracker mImsStateTracker;
@Mock private DomainSelectorBase.DestroyListener mDestroyListener;
@Mock private ProvisioningManager mProvisioningManager;
+ @Mock private CrossSimRedialingController mCsrdCtrl;
private Context mContext;
@@ -269,7 +272,7 @@
verify(mWwanSelectorCallback, times(0)).onRequestEmergencyNetworkScan(
any(), anyInt(), any(), any());
- verify(mWwanSelectorCallback, times(0)).onDomainSelected(anyInt());
+ verify(mWwanSelectorCallback, times(0)).onDomainSelected(anyInt(), eq(true));
}
@Test
@@ -984,13 +987,13 @@
assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
// Wi-Fi is not connected.
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected.
mNetworkCallback.onAvailable(null);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(eq(true));
}
@Test
@@ -1016,20 +1019,20 @@
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
// Wi-Fi is not connected.
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected. But Wi-Fi calling setting is disabled.
mNetworkCallback.onAvailable(null);
when(mMmTelManager.isVoWiFiRoamingSettingEnabled()).thenReturn(false);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected and Wi-Fi calling setting is enabled.
when(mMmTelManager.isVoWiFiSettingEnabled()).thenReturn(true);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(eq(true));
}
@Test
@@ -1055,19 +1058,19 @@
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
// Wi-Fi is not connected.
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected. But Wi-Fi calling s not activated.
mNetworkCallback.onAvailable(null);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected and Wi-Fi calling is activated.
doReturn("1").when(mProvisioningManager).getProvisioningStringValue(anyInt());
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(eq(true));
}
@Test
@@ -1088,19 +1091,19 @@
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
// Wi-Fi is not connected.
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// Wi-Fi is connected but IMS is not registered over Wi-Fi.
mNetworkCallback.onAvailable(null);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(0)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
// IMS is registered over Wi-Fi.
bindImsService(true);
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(eq(false));
}
@Test
@@ -1127,13 +1130,13 @@
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(eq(false));
// duplicated event
mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
// ignore duplicated callback, no change in interaction
- verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+ verify(mTransportSelectorCallback, times(1)).onWlanSelected(anyBoolean());
}
@Test
@@ -1143,6 +1146,7 @@
doReturn(2).when(mTelephonyManager).getActiveModemCount();
doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
.when(mTelephonyManager).getSimState(anyInt());
+ doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
0, false, false, 0, 0, "", "", "jp");
@@ -1158,6 +1162,29 @@
}
@Test
+ public void testDualSimInvalidSubscriptionButNoOtherSlot() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+ doReturn(2).when(mTelephonyManager).getActiveModemCount();
+ doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
+ .when(mTelephonyManager).getSimState(anyInt());
+ doReturn(false).when(mCsrdCtrl).isThereOtherSlot();
+
+ EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+ 0, false, false, 0, 0, "", "", "jp");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mTransportSelectorCallback, times(0))
+ .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_PERM_FAILURE));
+ verifyScanPsPreferred();
+ }
+
+ @Test
public void testEutranWithCsDomainOnly() throws Exception {
setupForHandleScanResult();
@@ -1478,6 +1505,149 @@
assertTrue(networks.indexOf(GERAN) < networks.indexOf(NGRAN));
}
+ @Test
+ public void testStartCrossStackTimer() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+
+ processAllMessages();
+ verify(mCsrdCtrl).startTimer(any(), eq(mDomainSelector), any(),
+ any(), anyBoolean(), anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void testStopCrossStackTimerOnCancel() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ mDomainSelector.cancelSelection();
+
+ verify(mCsrdCtrl).stopTimer();
+ }
+
+ @Test
+ public void testStopCrossStackTimerOnFinish() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ mDomainSelector.finishSelection();
+
+ verify(mCsrdCtrl).stopTimer();
+ }
+
+ @Test
+ public void testCrossStackTimerTempFailure() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+
+ verifyCsDialed();
+
+ attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+ .setEmergency(true)
+ .setEmergencyRegResult(regResult)
+ .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE)
+ .build();
+
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verify(mCsrdCtrl).notifyCallFailure(eq(PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE));
+ }
+
+ @Test
+ public void testCrossStackTimerPermFailure() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+
+ verifyCsDialed();
+
+ attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+ .setEmergency(true)
+ .setEmergencyRegResult(regResult)
+ .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_PERM_FAILURE)
+ .build();
+
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verify(mCsrdCtrl).notifyCallFailure(eq(PreciseDisconnectCause.EMERGENCY_PERM_FAILURE));
+ }
+
+ @Test
+ public void testCrossStackTimerExpired() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+
+ verifyScanPsPreferred();
+
+ mDomainSelector.notifyCrossStackTimerExpired();
+
+ verify(mTransportSelectorCallback)
+ .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+ }
+
+ @Test
+ public void testCrossStackTimerExpiredAfterDomainSelected() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.DOMAIN_CS,
+ true, true, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+
+ verifyCsDialed();
+
+ mDomainSelector.notifyCrossStackTimerExpired();
+
+ verify(mTransportSelectorCallback, times(0))
+ .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+
+ mDomainSelector.reselectDomain(attr);
+ processAllMessages();
+
+ verify(mTransportSelectorCallback)
+ .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+ }
+
private void setupForScanListTest(PersistableBundle bundle) throws Exception {
setupForScanListTest(bundle, false);
}
@@ -1551,7 +1721,7 @@
private void createSelector(int subId) throws Exception {
mDomainSelector = new EmergencyCallDomainSelector(
mContext, SLOT_0, subId, mHandlerThread.getLooper(),
- mImsStateTracker, mDestroyListener);
+ mImsStateTracker, mDestroyListener, mCsrdCtrl);
replaceInstance(DomainSelectorBase.class,
"mWwanSelectorCallback", mDomainSelector, mWwanSelectorCallback);
@@ -1559,12 +1729,12 @@
private void verifyCsDialed() {
processAllMessages();
- verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS));
+ verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS), eq(false));
}
private void verifyPsDialed() {
processAllMessages();
- verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_PS));
+ verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_PS), eq(true));
}
private void verifyScanPsPreferred() {
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
index 8b63530..1d89071 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
@@ -210,7 +210,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -413,7 +414,8 @@
// onDomainSelected will be invoked only once
// even though the domain selection was requested twice.
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -430,7 +432,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -446,7 +449,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -462,7 +466,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -478,7 +483,8 @@
processAllMessages();
// Expected: PS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
}
@Test
@@ -494,7 +500,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -510,7 +517,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -526,7 +534,8 @@
processAllMessages();
// Expected: PS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
}
@Test
@@ -542,7 +551,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -558,7 +568,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -574,7 +585,8 @@
processAllMessages();
// Expected: PS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
}
@Test
@@ -590,7 +602,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -606,7 +619,8 @@
processAllMessages();
// Expected: CS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -622,7 +636,7 @@
processAllMessages();
// Expected: WLAN
- verify(mTransportSelectorCallback).onWlanSelected();
+ verify(mTransportSelectorCallback).onWlanSelected(eq(false));
}
@Test
@@ -641,7 +655,8 @@
// if the emergency SMS messages over IMS is enabled in the carrier configuration and
// the PS network does not allow the emergency service, this MO SMS should be routed to
// CS domain.
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
}
@Test
@@ -657,7 +672,8 @@
processAllMessages();
// Expected: PS network
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
}
private void setUpCarrierConfig(boolean supported) {
diff --git a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
index 8780f1f..4dd1f3c 100644
--- a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
@@ -436,7 +436,7 @@
}
@Override
- public synchronized void onWlanSelected() {
+ public synchronized void onWlanSelected(boolean useEmergencyPdn) {
Log.d(TAG, "onWlanSelected");
mWlanSelected = true;
notifyAll();
@@ -504,7 +504,8 @@
}
- public synchronized void onDomainSelected(@NetworkRegistrationInfo.Domain int domain) {
+ public synchronized void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
+ boolean useEmergencyPdn) {
Log.i(TAG, "onDomainSelected - called");
mSelectedDomain = domain;
mDomainSelected = true;
diff --git a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
index 412d83d..785127c 100644
--- a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
@@ -142,7 +142,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -184,7 +185,8 @@
// onDomainSelected will be invoked only once
// even though the domain selection was requested twice.
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -230,7 +232,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
mDomainSelector.reselectDomain(mSelectionAttributes);
@@ -239,7 +242,7 @@
processAllMessages();
- verify(mTransportSelectorCallback).onWlanSelected();
+ verify(mTransportSelectorCallback).onWlanSelected(eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -256,9 +259,10 @@
mDomainSelector.reselectDomain(mSelectionAttributes);
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
- verify(mTransportSelectorCallback, never()).onWlanSelected();
+ verify(mTransportSelectorCallback, never()).onWlanSelected(eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -275,7 +279,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -292,7 +297,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -309,7 +315,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -326,7 +333,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -343,7 +351,8 @@
processAllMessages();
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+ eq(false));
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
@@ -358,9 +367,10 @@
processAllMessages();
if (accessNetworkType == AccessNetworkType.IWLAN) {
- verify(mTransportSelectorCallback).onWlanSelected();
+ verify(mTransportSelectorCallback).onWlanSelected(eq(false));
} else {
- verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+ verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+ eq(false));
}
assertFalse(mDomainSelector.isDomainSelectionRequested());
}
diff --git a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
index ace59e3..f340e94 100644
--- a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -77,7 +77,8 @@
public DomainSelectorBase create(Context context, int slotId, int subId,
@SelectorType int selectorType, boolean isEmergency,
@NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
- @NonNull DomainSelectorBase.DestroyListener listener) {
+ @NonNull DomainSelectorBase.DestroyListener listener,
+ @NonNull CrossSimRedialingController crossSimRedialingController) {
switch (selectorType) {
case DomainSelectionService.SELECTOR_TYPE_CALLING: // fallthrough
case DomainSelectionService.SELECTOR_TYPE_SMS: // fallthrough