Merge "Internal Telephony Support For Cellular Identifier Disclosure HALs" into main
diff --git a/Android.bp b/Android.bp
index 301343c..121236a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -106,6 +106,7 @@
"net-utils-framework-common",
"telephony-protos",
"modules-utils-build_system",
+ "modules-utils-fastxmlserializer",
"modules-utils-statemachine",
],
diff --git a/flags/messaging.aconfig b/flags/messaging.aconfig
index 3c20d69..1ba89ba 100644
--- a/flags/messaging.aconfig
+++ b/flags/messaging.aconfig
@@ -13,3 +13,10 @@
description: "This flag controls AP domain selection support for normal/emergency SMS."
bug: "262804071"
}
+
+flag {
+ name: "mms_disabled_error"
+ namespace: "telephony"
+ description: "This flag controls the support of the new MMS error code MMS_ERROR_MMS_DISABLED."
+ bug: "305062594"
+}
\ No newline at end of file
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 87acccc..e9e3169 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -20,4 +20,11 @@
namespace: "telephony"
description: "Enable system api isWpsCallNumber. Its an utility api to check if the dialed number is for Wireless Priority Service call."
bug: "304272356"
+}
+
+flag {
+ name: "ensure_access_to_call_settings_is_restricted"
+ namespace: "telephony"
+ description: "Check if access to mobile network configs restricted before displaying call options"
+ bug: "309655251"
}
\ No newline at end of file
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index 39b344b..3ef2301 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -1,4 +1,11 @@
package: "com.android.internal.telephony.flags"
+
+flag {
+ name: "esim_bootstrap_provisioning_flag"
+ namespace: "telephony"
+ description: "This flag controls eSIM Bootstrap provisioning feature support."
+ bug:"298567545"
+}
flag {
name: "imsi_key_retry_download_on_phone_unlock"
namespace: "telephony"
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 993aa4d..537f824 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -677,4 +677,7 @@
optional bool is_ims_registered = 3;
optional int32 cellular_service_state = 4;
optional int32 count = 5;
+ optional bool is_multi_sim = 6;
+ optional int32 recommending_handover_type = 7;
+ optional bool is_satellite_allowed_in_current_location = 8;
}
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index a796368..625a937 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -62,6 +62,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@@ -521,6 +522,27 @@
return sMetricsCollector;
}
+ /**
+ * Print all feature flag configurations that Telephony is using for debugging purposes.
+ */
+ private static void reflectAndPrintFlagConfigs(IndentingPrintWriter pw) {
+
+ try {
+ // Look away, a forbidden technique (reflection) is being used to allow us to get
+ // all flag configs without having to add them manually to this method.
+ Method[] methods = FeatureFlags.class.getMethods();
+ if (methods.length == 0) {
+ pw.println("NONE");
+ return;
+ }
+ for (Method m : methods) {
+ pw.println(m.getName() + "-> " + m.invoke(sFeatureFlags));
+ }
+ } catch (Exception e) {
+ pw.println("[ERROR]");
+ }
+ }
+
public static void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) {
IndentingPrintWriter pw = new IndentingPrintWriter(printwriter, " ");
pw.println("PhoneFactory:");
@@ -613,8 +635,15 @@
} catch (Exception e) {
e.printStackTrace();
}
-
pw.flush();
pw.decreaseIndent();
+
+ pw.println("++++++++++++++++++++++++++++++++");
+ pw.println("Flag Configurations:");
+ pw.increaseIndent();
+ reflectAndPrintFlagConfigs(pw);
+ pw.flush();
+ pw.decreaseIndent();
+ pw.println("++++++++++++++++++++++++++++++++");
}
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 14f71bd..a94875d 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -1946,16 +1946,15 @@
err = ((CommandException)(ar.exception)).getCommandError();
}
- if (mCi.getRadioState() != TelephonyManager.RADIO_POWER_ON) {
- log("handlePollStateResult: Invalid response due to radio off or unavailable. "
- + "Set ServiceState to out of service.");
- pollStateInternal(false);
- return;
- }
-
if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
- loge("handlePollStateResult: RIL returned RADIO_NOT_AVAILABLE when radio is on.");
- cancelPollState();
+ loge("handlePollStateResult: RIL returned RADIO_NOT_AVAILABLE.");
+ if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
+ cancelPollState();
+ } else {
+ handlePollStateInternalForRadioOffOrUnavailable(
+ mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
+ pollStateDone();
+ }
return;
}
@@ -3312,42 +3311,17 @@
private void pollStateInternal(boolean modemTriggered) {
mPollingContext = new int[1];
- NetworkRegistrationInfo nri;
log("pollState: modemTriggered=" + modemTriggered + ", radioState=" + mCi.getRadioState());
switch (mCi.getRadioState()) {
case TelephonyManager.RADIO_POWER_UNAVAILABLE:
- // Preserve the IWLAN registration state, because that should not be affected by
- // radio availability.
- nri = mNewSS.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- mNewSS.setOutOfService(false);
- // Add the IWLAN registration info back to service state.
- if (nri != null) {
- mNewSS.addNetworkRegistrationInfo(nri);
- }
- mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
- mLastNitzData = null;
- mNitzState.handleNetworkUnavailable();
+ handlePollStateInternalForRadioOffOrUnavailable(false);
pollStateDone();
break;
case TelephonyManager.RADIO_POWER_OFF:
- // Preserve the IWLAN registration state, because that should not be affected by
- // radio availability.
- nri = mNewSS.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- mNewSS.setOutOfService(true);
- // Add the IWLAN registration info back to service state.
- if (nri != null) {
- mNewSS.addNetworkRegistrationInfo(nri);
- }
- mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
- mLastNitzData = null;
- mNitzState.handleNetworkUnavailable();
+ handlePollStateInternalForRadioOffOrUnavailable(true);
// Don't poll when device is shutting down or the poll was not modemTriggered
// (they sent us new radio data) and the current network is not IWLAN
if (mDeviceShuttingDown ||
@@ -3391,6 +3365,21 @@
}
}
+ private void handlePollStateInternalForRadioOffOrUnavailable(boolean radioOff) {
+ // Preserve the IWLAN registration state, which should not be affected by radio availability
+ NetworkRegistrationInfo nri = mNewSS.getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+ mNewSS.setOutOfService(radioOff);
+ // Add the IWLAN registration info back to service state.
+ if (nri != null) {
+ mNewSS.addNetworkRegistrationInfo(nri);
+ }
+ mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
+ mLastNitzData = null;
+ mNitzState.handleNetworkUnavailable();
+ }
+
/**
* Get the highest-priority CellIdentity for a provided ServiceState.
*
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 0c5c9cb..4cf5ef9 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -2290,6 +2290,10 @@
}
}
+ if (mDataNetworkController.isEsimBootStrapProvisioningActivated()) {
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ }
+
// If one of the capabilities are for special use, for example, IMS, CBS, then this
// network should be restricted, regardless data is enabled or not.
if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())
@@ -3318,7 +3322,8 @@
TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
.getDataProfileForNetworkRequest(networkRequest, targetNetworkType,
- mPhone.getServiceState().isUsingNonTerrestrialNetwork(), false);
+ mPhone.getServiceState().isUsingNonTerrestrialNetwork(),
+ mDataNetworkController.isEsimBootStrapProvisioningActivated(), false);
// Some carriers have different profiles between cellular and IWLAN. We need to
// dynamically switch profile, but only when those profiles have same APN name.
if (dataProfile != null && dataProfile.getApnSetting() != null
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 2d91967..c29afa6 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -101,6 +101,8 @@
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.ims.ImsResolver;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;
@@ -1330,6 +1332,7 @@
.getDataProfileForNetworkRequest(requestList.getFirst(),
TelephonyManager.NETWORK_TYPE_IWLAN,
mServiceState.isUsingNonTerrestrialNetwork(),
+ isEsimBootStrapProvisioningActivated(),
false/*ignorePermanentFailure*/);
if (candidate != null && !dataNetwork.getDataProfile().equals(candidate)) {
logv("But skipped because found better data profile " + candidate
@@ -1494,7 +1497,8 @@
evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
evaluation.setCandidateDataProfile(mDataProfileManager.getDataProfileForNetworkRequest(
networkRequest, getDataNetworkType(transport),
- mServiceState.isUsingNonTerrestrialNetwork(), true));
+ mServiceState.isUsingNonTerrestrialNetwork(),
+ isEsimBootStrapProvisioningActivated(), true));
networkRequest.setEvaluation(evaluation);
log(evaluation.toString());
return evaluation;
@@ -1653,6 +1657,7 @@
DataProfile dataProfile = mDataProfileManager
.getDataProfileForNetworkRequest(networkRequest, networkType,
mServiceState.isUsingNonTerrestrialNetwork(),
+ isEsimBootStrapProvisioningActivated(),
// If the evaluation is due to environmental changes, then we should ignore
// the permanent failure reached earlier.
reason.isConditionBased());
@@ -2272,6 +2277,22 @@
}
/**
+ * Check if the device is in eSIM bootstrap provisioning state.
+ *
+ * @return {@code true} if the device is under eSIM bootstrap provisioning.
+ */
+ public boolean isEsimBootStrapProvisioningActivated() {
+ if (!mFeatureFlags.esimBootstrapProvisioningFlag()) {
+ return false;
+ }
+
+ SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
+ .getSubscriptionInfoInternal(mPhone.getSubId());
+ return subInfo != null
+ && subInfo.getProfileClass() == SubscriptionManager.PROFILE_CLASS_PROVISIONING;
+ }
+
+ /**
* Register for IMS feature registration state.
*
* @param subId The subscription index.
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index 273dc8b..df1fc92 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -255,6 +255,7 @@
cursor.close();
return dataProfile;
}
+
/**
* Update all data profiles, including preferred data profile, and initial attach data profile.
* Also send those profiles down to the modem if needed.
@@ -640,12 +641,12 @@
*/
public @Nullable DataProfile getDataProfileForNetworkRequest(
@NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
- boolean isNtn, boolean ignorePermanentFailure) {
+ boolean isNtn, boolean isEsimBootstrapProvisioning, boolean ignorePermanentFailure) {
ApnSetting apnSetting = null;
if (networkRequest.hasAttribute(TelephonyNetworkRequest
.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType, isNtn,
- ignorePermanentFailure);
+ isEsimBootstrapProvisioning, ignorePermanentFailure);
}
TrafficDescriptor.Builder trafficDescriptorBuilder = new TrafficDescriptor.Builder();
@@ -711,48 +712,52 @@
*/
private @Nullable ApnSetting getApnSettingForNetworkRequest(
@NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
- boolean isNtn, boolean ignorePermanentFailure) {
+ boolean isNtn, boolean isEsimBootStrapProvisioning, boolean ignorePermanentFailure) {
if (!networkRequest.hasAttribute(
TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
loge("Network request does not have APN setting attribute.");
return null;
}
- if (mFeatureFlags.carrierEnabledSatelliteFlag()) {
- // If the preferred data profile can be used, always use it if it can satisfy the
- // network request with current network type (even though it's been marked as permanent
- // failed.)
- if (mPreferredDataProfile != null
- && networkRequest.canBeSatisfiedBy(mPreferredDataProfile)
- && mPreferredDataProfile.getApnSetting() != null
- && mPreferredDataProfile.getApnSetting().canSupportNetworkType(networkType)
- && ((isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure(
- ApnSetting.INFRASTRUCTURE_SATELLITE))
- || (!isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure(
- ApnSetting.INFRASTRUCTURE_CELLULAR)))) {
- if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting()
- .getPermanentFailed()) {
- return mPreferredDataProfile.getApnSetting();
+ // if esim bootstrap provisioning in progress, do not apply preferred data profile
+ if (!isEsimBootStrapProvisioning) {
+ if (mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ // If the preferred data profile can be used, always use it if it can satisfy the
+ // network request with current network type (even though it's been marked as
+ // permanent failed.)
+ if (mPreferredDataProfile != null
+ && networkRequest.canBeSatisfiedBy(mPreferredDataProfile)
+ && mPreferredDataProfile.getApnSetting() != null
+ && mPreferredDataProfile.getApnSetting().canSupportNetworkType(networkType)
+ && ((isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_SATELLITE))
+ || (!isNtn && mPreferredDataProfile.getApnSetting().isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_CELLULAR)))) {
+ if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting()
+ .getPermanentFailed()) {
+ return mPreferredDataProfile.getApnSetting();
+ }
+ log("The preferred data profile is permanently failed. Only condition based "
+ + "retry can happen.");
+ return null;
}
- log("The preferred data profile is permanently failed. Only condition based "
- + "retry can happen.");
- return null;
- }
- } else {
- // If the preferred data profile can be used, always use it if it can satisfy the
- // network request with current network type (even though it's been marked as permanent
- // failed.)
- if (mPreferredDataProfile != null
- && networkRequest.canBeSatisfiedBy(mPreferredDataProfile)
- && mPreferredDataProfile.getApnSetting() != null
- && mPreferredDataProfile.getApnSetting().canSupportNetworkType(networkType)) {
- if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting()
- .getPermanentFailed()) {
- return mPreferredDataProfile.getApnSetting();
+ } else {
+ // If the preferred data profile can be used, always use it if it can satisfy the
+ // network request with current network type (even though it's been marked as
+ // permanent failed.)
+ if (mPreferredDataProfile != null
+ && networkRequest.canBeSatisfiedBy(mPreferredDataProfile)
+ && mPreferredDataProfile.getApnSetting() != null
+ && mPreferredDataProfile.getApnSetting()
+ .canSupportNetworkType(networkType)) {
+ if (ignorePermanentFailure || !mPreferredDataProfile.getApnSetting()
+ .getPermanentFailed()) {
+ return mPreferredDataProfile.getApnSetting();
+ }
+ log("The preferred data profile is permanently failed. Only condition based "
+ + "retry can happen.");
+ return null;
}
- log("The preferred data profile is permanently failed. Only condition based "
- + "retry can happen.");
- return null;
}
}
@@ -778,6 +783,8 @@
.filter((dp) -> {
if (dp.getApnSetting() == null) return false;
if (!dp.getApnSetting().canSupportNetworkType(networkType)) return false;
+ if (isEsimBootStrapProvisioning
+ != dp.getApnSetting().isEsimBootstrapProvisioning()) return false;
if (mFeatureFlags.carrierEnabledSatelliteFlag()) {
if (isNtn && !dp.getApnSetting().isForInfrastructure(
ApnSetting.INFRASTRUCTURE_SATELLITE)) {
@@ -820,6 +827,10 @@
return null;
}
+ if (isEsimBootStrapProvisioning) {
+ log("Found esim bootstrap provisioning data profile for network request: "
+ + dataProfiles.get(0).getApnSetting());
+ }
return dataProfiles.get(0).getApnSetting();
}
@@ -865,7 +876,9 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
.build(), mPhone);
return getDataProfileForNetworkRequest(networkRequest, networkType,
- mPhone.getServiceState().isUsingNonTerrestrialNetwork(), true) != null;
+ mPhone.getServiceState().isUsingNonTerrestrialNetwork(),
+ mDataNetworkController.isEsimBootStrapProvisioningActivated(),
+ true) != null;
}
/**
@@ -1040,6 +1053,8 @@
apnBuilder.setCarrierId(apn1.getCarrierId());
apnBuilder.setSkip464Xlat(apn1.getSkip464Xlat());
apnBuilder.setAlwaysOn(apn1.isAlwaysOn());
+ apnBuilder.setInfrastructureBitmask(apn1.getInfrastructureBitmask());
+ apnBuilder.setEsimBootstrapProvisioning(apn1.isEsimBootstrapProvisioning());
return new DataProfile.Builder()
.setApnSetting(apnBuilder.build())
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index bd7ce2a..8c1aae3 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -1336,7 +1336,10 @@
stats.countOfTimerStarted,
stats.isImsRegistered,
stats.cellularServiceState,
- stats.count);
+ stats.count,
+ stats.isMultiSim,
+ stats.recommendingHandoverType,
+ stats.isSatelliteAllowedInCurrentLocation);
}
/** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
index 1da0c46..d5d041a 100644
--- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
+++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
@@ -2070,7 +2070,9 @@
if (stats.isDisplaySosMessageSent == key.isDisplaySosMessageSent
&& stats.countOfTimerStarted == key.countOfTimerStarted
&& stats.isImsRegistered == key.isImsRegistered
- && stats.cellularServiceState == key.cellularServiceState) {
+ && stats.cellularServiceState == key.cellularServiceState
+ && stats.isMultiSim == key.isMultiSim
+ && stats.recommendingHandoverType == key.recommendingHandoverType) {
return stats;
}
}
diff --git a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
index 7ff370c..55eee1a 100644
--- a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
+++ b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
@@ -732,12 +732,19 @@
private final int mCountOfTimerStarted;
private final boolean mIsImsRegistered;
private final int mCellularServiceState;
+ private final boolean mIsMultiSim;
+ private final int mRecommendingHandoverType;
+ private final boolean mIsSatelliteAllowedInCurrentLocation;
private SatelliteSosMessageRecommenderParams(Builder builder) {
this.mIsDisplaySosMessageSent = builder.mIsDisplaySosMessageSent;
this.mCountOfTimerStarted = builder.mCountOfTimerStarted;
this.mIsImsRegistered = builder.mIsImsRegistered;
this.mCellularServiceState = builder.mCellularServiceState;
+ this.mIsMultiSim = builder.mIsMultiSim;
+ this.mRecommendingHandoverType = builder.mRecommendingHandoverType;
+ this.mIsSatelliteAllowedInCurrentLocation =
+ builder.mIsSatelliteAllowedInCurrentLocation;
}
public boolean isDisplaySosMessageSent() {
@@ -756,6 +763,18 @@
return mCellularServiceState;
}
+ public boolean isMultiSim() {
+ return mIsMultiSim;
+ }
+
+ public int getRecommendingHandoverType() {
+ return mRecommendingHandoverType;
+ }
+
+ public boolean isSatelliteAllowedInCurrentLocation() {
+ return mIsSatelliteAllowedInCurrentLocation;
+ }
+
/**
* A builder class to create {@link SatelliteProvisionParams} data structure class
*/
@@ -764,6 +783,10 @@
private int mCountOfTimerStarted = -1;
private boolean mIsImsRegistered = false;
private int mCellularServiceState = -1;
+ private boolean mIsMultiSim = false;
+ private int mRecommendingHandoverType = -1;
+ private boolean mIsSatelliteAllowedInCurrentLocation = false;
+
/**
* Sets resultCode value of {@link SatelliteSosMessageRecommender} atom
@@ -803,6 +826,34 @@
}
/**
+ * Sets isMultiSim value of {@link SatelliteSosMessageRecommender} atom
+ * then returns Builder class
+ */
+ public Builder setIsMultiSim(boolean isMultiSim) {
+ this.mIsMultiSim = isMultiSim;
+ return this;
+ }
+
+ /**
+ * Sets recommendingHandoverType value of {@link SatelliteSosMessageRecommender} atom
+ * then returns Builder class
+ */
+ public Builder setRecommendingHandoverType(int recommendingHandoverType) {
+ this.mRecommendingHandoverType = recommendingHandoverType;
+ return this;
+ }
+
+ /**
+ * Sets isSatelliteAllowedInCurrentLocation value of
+ * {@link SatelliteSosMessageRecommender} atom then returns Builder class.
+ */
+ public Builder setIsSatelliteAllowedInCurrentLocation(
+ boolean satelliteAllowedInCurrentLocation) {
+ mIsSatelliteAllowedInCurrentLocation = satelliteAllowedInCurrentLocation;
+ return this;
+ }
+
+ /**
* Returns SosMessageRecommenderParams, which contains whole component of
* {@link SatelliteSosMessageRecommenderParams} atom
*/
@@ -818,7 +869,11 @@
+ "isDisplaySosMessageSent=" + mIsDisplaySosMessageSent
+ ", countOfTimerStarted=" + mCountOfTimerStarted
+ ", isImsRegistered=" + mIsImsRegistered
- + ", cellularServiceState=" + mCellularServiceState + ")";
+ + ", cellularServiceState=" + mCellularServiceState
+ + ", isMultiSim=" + mIsMultiSim
+ + ", recommendingHandoverType=" + mRecommendingHandoverType
+ + ", isSatelliteAllowedInCurrentLocation="
+ + mIsSatelliteAllowedInCurrentLocation + ")";
}
}
@@ -899,6 +954,9 @@
proto.countOfTimerStarted = param.getCountOfTimerStarted();
proto.isImsRegistered = param.isImsRegistered();
proto.cellularServiceState = param.getCellularServiceState();
+ proto.isMultiSim = param.isMultiSim();
+ proto.recommendingHandoverType = param.getRecommendingHandoverType();
+ proto.isSatelliteAllowedInCurrentLocation = param.isSatelliteAllowedInCurrentLocation();
proto.count = 1;
mAtomsStorage.addSatelliteSosMessageRecommenderStats(proto);
}
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
index fd04779..695a563 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
@@ -496,7 +496,7 @@
*/
@SatelliteManager.SatelliteResult public int registerForSatelliteDatagram(int subId,
@NonNull ISatelliteDatagramCallback callback) {
- if (!SatelliteController.getInstance().isSatelliteSupported()) {
+ if (!SatelliteController.getInstance().isSatelliteSupportedViaOem()) {
return SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 5148ecb..1f31d5a 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -16,9 +16,14 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
import static android.telephony.satellite.SatelliteManager.KEY_NTN_SIGNAL_STRENGTH;
import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
@@ -51,10 +56,12 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
+import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.satellite.INtnSignalStrengthCallback;
@@ -68,6 +75,7 @@
import android.telephony.satellite.SatelliteManager;
import android.util.Log;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.uwb.UwbManager;
import com.android.internal.R;
@@ -77,6 +85,7 @@
import com.android.internal.telephony.DeviceStateMonitor;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.ProvisionMetricsStats;
@@ -111,6 +120,7 @@
/** Value to pass for the setting key SATELLITE_MODE_ENABLED, enabled = 1, disabled = 0 */
public static final int SATELLITE_MODE_ENABLED_TRUE = 1;
public static final int SATELLITE_MODE_ENABLED_FALSE = 0;
+ public static final int INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE = -1;
/** Message codes used in handleMessage() */
//TODO: Move the Commands and events related to position updates to PointingAppController
@@ -146,8 +156,9 @@
private static final int CMD_REQUEST_NTN_SIGNAL_STRENGTH = 32;
private static final int EVENT_REQUEST_NTN_SIGNAL_STRENGTH_DONE = 33;
private static final int EVENT_NTN_SIGNAL_STRENGTH_CHANGED = 34;
- private static final int CMD_START_SENDING_NTN_SIGNAL_STRENGTH = 35;
- private static final int EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING = 36;
+ private static final int CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING = 35;
+ private static final int EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE = 36;
+ private static final int EVENT_SERVICE_STATE_CHANGED = 37;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -159,12 +170,12 @@
@NonNull private final ProvisionMetricsStats mProvisionMetricsStats;
@NonNull private final SubscriptionManagerService mSubscriptionManagerService;
private final CommandsInterface mCi;
- private ContentResolver mContentResolver = null;
+ private ContentResolver mContentResolver;
private final DeviceStateMonitor mDSM;
private final Object mRadioStateLock = new Object();
- /** Flags to indicate whether the resepective radio is enabled */
+ /** Flags to indicate whether the respective radio is enabled */
@GuardedBy("mRadioStateLock")
private boolean mBTStateEnabled = false;
@GuardedBy("mRadioStateLock")
@@ -261,6 +272,32 @@
@NonNull private final Map<Integer, Boolean> mIsSatelliteAttachEnabledForCarrierArrayPerSub =
new HashMap<>();
@NonNull private final FeatureFlags mFeatureFlags;
+ @NonNull private final Object mSatelliteConnectedLock = new Object();
+ /** Key: Subscription ID; Value: Last satellite connected time */
+ @GuardedBy("mSatelliteConnectedLock")
+ @NonNull private final SparseArray<Long> mLastSatelliteDisconnectedTimesMillis =
+ new SparseArray<>();
+ /**
+ * Key: Subscription ID; Value: {@code true} if satellite was just connected,
+ * {@code false} otherwise.
+ */
+ @GuardedBy("mSatelliteConnectedLock")
+ @NonNull private final SparseBooleanArray
+ mWasSatelliteConnectedViaCarrier = new SparseBooleanArray();
+
+ @GuardedBy("mSatelliteConnectedLock")
+ @NonNull private final SparseBooleanArray
+ mIsSatelliteConnectedViaCarrierHysteresisTimeExpired = new SparseBooleanArray();
+
+ /**
+ * This is used for testing only. When mEnforcedEmergencyCallToSatelliteHandoverType is valid,
+ * Telephony will ignore the IMS registration status and cellular availability, and always send
+ * the connection event EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
+ */
+ private int mEnforcedEmergencyCallToSatelliteHandoverType =
+ INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+ private int mDelayInSendingEventDisplayEmergencyMessage = 0;
+
/**
* @return The singleton instance of SatelliteController.
*/
@@ -332,6 +369,7 @@
registerForSatelliteProvisionStateChanged();
registerForPendingDatagramCount();
registerForSatelliteModemStateChanged();
+ registerForServiceStateChanged();
mContentResolver = mContext.getContentResolver();
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
@@ -356,7 +394,7 @@
handleCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId);
mCarrierConfigManager.registerCarrierConfigChangeListener(
new HandlerExecutor(new Handler(looper)), mCarrierConfigChangeListener);
- mDSM.registerForSignalStrengthReportDecision(this, CMD_START_SENDING_NTN_SIGNAL_STRENGTH,
+ mDSM.registerForSignalStrengthReportDecision(this, CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING,
null);
}
@@ -1133,16 +1171,16 @@
break;
}
- case CMD_START_SENDING_NTN_SIGNAL_STRENGTH: {
+ case CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING: {
ar = (AsyncResult) msg.obj;
boolean shouldReport = (boolean) ar.result;
- logd("CMD_START_SENDING_NTN_SIGNAL_STRENGTH: shouldReport=" + shouldReport);
+ logd("CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING: shouldReport=" + shouldReport);
request = new SatelliteControllerHandlerRequest(shouldReport,
SatelliteServiceUtils.getPhone());
if (SATELLITE_RESULT_SUCCESS != evaluateOemSatelliteRequestAllowed(true)) {
return;
}
- onCompleted = obtainMessage(EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING,
+ onCompleted = obtainMessage(EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE,
request);
if (shouldReport) {
mSatelliteModemInterface.startSendingNtnSignalStrength(onCompleted);
@@ -1152,11 +1190,11 @@
break;
}
- case EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING: {
+ case EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE: {
ar = (AsyncResult) msg.obj;
request = (SatelliteControllerHandlerRequest) ar.userObj;
int errorCode = SatelliteServiceUtils.getSatelliteError(ar,
- "EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING");
+ "EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE");
if (errorCode != SATELLITE_RESULT_SUCCESS) {
loge(((boolean) request.argument ? "startSendingNtnSignalStrength"
: "stopSendingNtnSignalStrength") + "returns " + errorCode);
@@ -1164,6 +1202,11 @@
break;
}
+ case EVENT_SERVICE_STATE_CHANGED: {
+ handleEventServiceStateChanged();
+ break;
+ }
+
default:
Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
msg.what);
@@ -1475,7 +1518,7 @@
return null;
}
- Boolean satelliteProvisioned = isSatelliteProvisioned();
+ Boolean satelliteProvisioned = isSatelliteViaOemProvisioned();
if (satelliteProvisioned != null && satelliteProvisioned) {
result.accept(SATELLITE_RESULT_SUCCESS);
return null;
@@ -1515,7 +1558,7 @@
return;
}
- Boolean satelliteProvisioned = isSatelliteProvisioned();
+ Boolean satelliteProvisioned = isSatelliteViaOemProvisioned();
if (satelliteProvisioned == null) {
result.accept(SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
return;
@@ -2072,6 +2115,53 @@
}
/**
+ * This API can be used in only testing to override connectivity status in monitoring emergency
+ * calls and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
+ *
+ * @param handoverType The type of handover from emergency call to satellite messaging. Use one
+ * of the following values to enable the override:
+ * 0 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS
+ * 1 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911
+ * To disable the override, use -1 for handoverType.
+ * @param delaySeconds The event EVENT_DISPLAY_EMERGENCY_MESSAGE will be sent to Dialer
+ * delaySeconds after the emergency call starts.
+ * @return {@code true} if the handover type is set successfully, {@code false} otherwise.
+ */
+ public boolean setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds) {
+ if (!isMockModemAllowed()) {
+ loge("setEmergencyCallToSatelliteHandoverType: mock modem not allowed");
+ return false;
+ }
+ if (isHandoverTypeValid(handoverType)) {
+ mEnforcedEmergencyCallToSatelliteHandoverType = handoverType;
+ mDelayInSendingEventDisplayEmergencyMessage = delaySeconds > 0 ? delaySeconds : 0;
+ } else {
+ mEnforcedEmergencyCallToSatelliteHandoverType =
+ INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+ mDelayInSendingEventDisplayEmergencyMessage = 0;
+ }
+ return true;
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ protected int getEnforcedEmergencyCallToSatelliteHandoverType() {
+ return mEnforcedEmergencyCallToSatelliteHandoverType;
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ protected int getDelayInSendingEventDisplayEmergencyMessage() {
+ return mDelayInSendingEventDisplayEmergencyMessage;
+ }
+
+ private boolean isHandoverTypeValid(int handoverType) {
+ if (handoverType == EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS
+ || handoverType == EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
* This function is used by {@link SatelliteModemInterface} to notify
* {@link SatelliteController} that the satellite vendor service was just connected.
* <p>
@@ -2132,14 +2222,15 @@
}
/**
- * @return {@code true} is satellite is supported on the device, {@code false} otherwise.
+ * @return {@code true} if satellite is supported via OEM on the device,
+ * {@code false} otherwise.
*/
- public boolean isSatelliteSupported() {
+ public boolean isSatelliteSupportedViaOem() {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
logd("isSatelliteSupported: oemEnabledSatelliteFlag is disabled");
return false;
}
- Boolean supported = isSatelliteSupportedInternal();
+ Boolean supported = isSatelliteSupportedViaOemInternal();
return (supported != null ? supported : false);
}
@@ -2218,10 +2309,92 @@
}
/**
+ * @return {@code true} if satellite is supported via carrier by any subscription on the device,
+ * {@code false} otherwise.
+ */
+ public boolean isSatelliteSupportedViaCarrier() {
+ if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("isSatelliteSupportedViaCarrier: carrierEnabledSatelliteFlag is disabled");
+ return false;
+ }
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (isSatelliteSupportedViaCarrier(phone.getSubId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return {@code true} if any subscription on the device is connected to satellite,
+ * {@code false} otherwise.
+ */
+ private boolean isUsingNonTerrestrialNetworkViaCarrier() {
+ if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("isUsingNonTerrestrialNetwork: carrierEnabledSatelliteFlag is disabled");
+ return false;
+ }
+ for (Phone phone : PhoneFactory.getPhones()) {
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState != null && serviceState.isUsingNonTerrestrialNetwork()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return {@code true} if the device is connected to satellite via any carrier within the
+ * {@link CarrierConfigManager#KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT}
+ * duration, {@code false} otherwise.
+ */
+ public boolean isSatelliteConnectedViaCarrierWithinHysteresisTime() {
+ if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("isSatelliteConnectedViaCarrierWithinHysteresisTime: carrierEnabledSatelliteFlag"
+ + " is disabled");
+ return false;
+ }
+ if (isUsingNonTerrestrialNetworkViaCarrier()) {
+ return true;
+ }
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (isSatelliteSupportedViaCarrier(phone.getSubId())) {
+ synchronized (mSatelliteConnectedLock) {
+ Boolean isHysteresisTimeExpired =
+ mIsSatelliteConnectedViaCarrierHysteresisTimeExpired.get(
+ phone.getSubId());
+ if (isHysteresisTimeExpired != null && isHysteresisTimeExpired) {
+ continue;
+ }
+
+ Long lastDisconnectedTime =
+ mLastSatelliteDisconnectedTimesMillis.get(phone.getSubId());
+ long satelliteConnectionHysteresisTime =
+ getSatelliteConnectionHysteresisTimeMillis(phone.getSubId());
+ if (lastDisconnectedTime != null
+ && (getElapsedRealtime() - lastDisconnectedTime)
+ <= satelliteConnectionHysteresisTime) {
+ return true;
+ } else {
+ mIsSatelliteConnectedViaCarrierHysteresisTimeExpired.put(
+ phone.getSubId(), true);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected long getElapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
+
+ /**
* If we have not successfully queried the satellite modem for its satellite service support,
* we will retry the query one more time. Otherwise, we will return the cached result.
*/
- private Boolean isSatelliteSupportedInternal() {
+ private Boolean isSatelliteSupportedViaOemInternal() {
synchronized (mIsSatelliteSupportedLock) {
if (mIsSatelliteSupported != null) {
/* We have already successfully queried the satellite modem. */
@@ -2352,7 +2525,7 @@
* @return true if satellite is provisioned on the given subscription else return false.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- protected Boolean isSatelliteProvisioned() {
+ protected Boolean isSatelliteViaOemProvisioned() {
synchronized (mIsSatelliteProvisionedLock) {
if (mIsSatelliteProvisioned != null) {
return mIsSatelliteProvisioned;
@@ -2724,16 +2897,16 @@
mCarrierConfigArray.put(subId, config);
}
return SatelliteServiceUtils.parseSupportedSatelliteServices(
- config.getPersistableBundle(CarrierConfigManager
- .KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE));
+ config.getPersistableBundle(
+ KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE));
}
}
@NonNull private PersistableBundle getConfigForSubId(int subId) {
PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId,
- CarrierConfigManager
- .KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
- CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL);
+ KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
+ KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+ KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT);
if (config == null || config.isEmpty()) {
config = CarrierConfigManager.getDefaultConfig();
}
@@ -2799,10 +2972,9 @@
return strArray;
}
- private boolean isSatelliteSupportedForCarrier(int subId) {
+ private boolean isSatelliteSupportedViaCarrier(int subId) {
return getConfigForSubId(subId)
- .getBoolean(CarrierConfigManager
- .KEY_SATELLITE_ATTACH_SUPPORTED_BOOL);
+ .getBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL);
}
/**
@@ -2951,7 +3123,7 @@
+ "SetSatelliteAttachEnableForCarrier error code =" + errorCode);
}
- if (!isSatelliteSupportedForCarrier(subId)) {
+ if (!isSatelliteSupportedViaCarrier(subId)) {
logd("Satellite for carrier is not supported. Only user setting is stored");
callback.accept(SATELLITE_RESULT_SUCCESS);
return;
@@ -2991,7 +3163,7 @@
return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
}
- Boolean satelliteSupported = isSatelliteSupportedInternal();
+ Boolean satelliteSupported = isSatelliteSupportedViaOemInternal();
if (satelliteSupported == null) {
return SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
}
@@ -3000,7 +3172,7 @@
}
if (isProvisionRequired) {
- Boolean satelliteProvisioned = isSatelliteProvisioned();
+ Boolean satelliteProvisioned = isSatelliteViaOemProvisioned();
if (satelliteProvisioned == null) {
return SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
}
@@ -3036,6 +3208,56 @@
.reportSessionMetrics();
}
+ private void registerForServiceStateChanged() {
+ if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ return;
+ }
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
+ }
+ }
+
+ private void handleEventServiceStateChanged() {
+ handleServiceStateForSatelliteConnectionViaCarrier();
+ }
+
+ private void handleServiceStateForSatelliteConnectionViaCarrier() {
+ for (Phone phone : PhoneFactory.getPhones()) {
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState != null) {
+ synchronized (mSatelliteConnectedLock) {
+ if (serviceState.isUsingNonTerrestrialNetwork()) {
+ mWasSatelliteConnectedViaCarrier.put(phone.getSubId(), true);
+ mIsSatelliteConnectedViaCarrierHysteresisTimeExpired.put(
+ phone.getSubId(), false);
+ } else {
+ Boolean connected = mWasSatelliteConnectedViaCarrier.get(phone.getSubId());
+ if (connected != null && connected) {
+ // The device just got disconnected from a satellite network.
+ mLastSatelliteDisconnectedTimesMillis.put(
+ phone.getSubId(), getElapsedRealtime());
+ mIsSatelliteConnectedViaCarrierHysteresisTimeExpired.put(
+ phone.getSubId(), false);
+ }
+ mWasSatelliteConnectedViaCarrier.put(phone.getSubId(), false);
+ }
+ }
+ }
+ }
+ }
+
+ private long getSatelliteConnectionHysteresisTimeMillis(int subId) {
+ synchronized (mCarrierConfigArrayLock) {
+ PersistableBundle config = mCarrierConfigArray.get(subId);
+ if (config == null) {
+ config = getConfigForSubId(subId);
+ mCarrierConfigArray.put(subId, config);
+ }
+ return (config.getInt(
+ KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT) * 1000L);
+ }
+ }
+
private static void logd(@NonNull String log) {
Rlog.d(TAG, log);
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 9bf82d1..f40880b 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -16,16 +16,31 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.ServiceState.STATE_EMERGENCY_ONLY;
+import static android.telephony.ServiceState.STATE_IN_SERVICE;
+import static android.telephony.ServiceState.STATE_OUT_OF_SERVICE;
+import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
+import static com.android.internal.telephony.satellite.SatelliteController.INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+
import android.annotation.NonNull;
-import android.os.AsyncResult;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.ResultReceiver;
+import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.telecom.Connection;
import android.telephony.Rlog;
@@ -36,16 +51,20 @@
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.RegistrationManager;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.text.TextUtils;
import android.util.Pair;
+import android.util.SparseArray;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.metrics.SatelliteStats;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -56,74 +75,48 @@
*/
public class SatelliteSOSMessageRecommender extends Handler {
private static final String TAG = "SatelliteSOSMessageRecommender";
-
- /**
- * Device config for the timeout duration in milliseconds to determine whether to recommend
- * Dialer to show the SOS button to users.
- * <p>
- * The timer is started when there is an ongoing emergency call, and the IMS is not registered,
- * and cellular service is not available. When the timer expires, SatelliteSOSMessageRecommender
- * will send the event EVENT_DISPLAY_SOS_MESSAGE to Dialer, which will then prompt user to
- * switch to using satellite SOS messaging.
- */
- public static final String EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS =
- "emergency_call_to_sos_msg_hysteresis_timeout_millis";
- /**
- * The default value of {@link #EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS} when it is
- * not provided in the device config.
- */
- public static final long DEFAULT_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 20000;
-
+ private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
+ private static final String BOOT_ALLOW_MOCK_MODEM_PROPERTY = "ro.boot.radio.allow_mock_modem";
private static final int EVENT_EMERGENCY_CALL_STARTED = 1;
- protected static final int EVENT_CELLULAR_SERVICE_STATE_CHANGED = 2;
- private static final int EVENT_IMS_REGISTRATION_STATE_CHANGED = 3;
- protected static final int EVENT_TIME_OUT = 4;
- private static final int EVENT_SATELLITE_PROVISIONED_STATE_CHANGED = 5;
- private static final int EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED = 6;
+ protected static final int EVENT_SERVICE_STATE_CHANGED = 2;
+ protected static final int EVENT_TIME_OUT = 3;
+ private static final int EVENT_SATELLITE_PROVISIONED_STATE_CHANGED = 4;
+ private static final int EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED = 5;
+ private static final int CMD_SEND_EVENT_DISPLAY_EMERGENCY_MESSAGE_FORCEFULLY = 6;
+ @NonNull private final Context mContext;
@NonNull
private final SatelliteController mSatelliteController;
private ImsManager mImsManager;
private Connection mEmergencyConnection = null;
- /* The phone used for emergency call */
- private Phone mPhone = null;
private final ISatelliteProvisionStateCallback mISatelliteProvisionStateCallback;
- @ServiceState.RegState
- private AtomicInteger mCellularServiceState = new AtomicInteger();
- private AtomicBoolean mIsImsRegistered = new AtomicBoolean();
+ /** Key: Phone ID; Value: IMS RegistrationCallback */
+ private SparseArray<RegistrationManager.RegistrationCallback>
+ mImsRegistrationCallbacks = new SparseArray<>();
private AtomicBoolean mIsSatelliteAllowedInCurrentLocation = new AtomicBoolean();
private final ResultReceiver mReceiverForRequestIsSatelliteAllowedForCurrentLocation;
private final long mTimeoutMillis;
+ private final AtomicBoolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime =
+ new AtomicBoolean(false);
protected int mCountOfTimerStarted = 0;
- private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
- new RegistrationManager.RegistrationCallback() {
- @Override
- public void onRegistered(ImsRegistrationAttributes attributes) {
- sendMessage(obtainMessage(EVENT_IMS_REGISTRATION_STATE_CHANGED, true));
- }
-
- @Override
- public void onUnregistered(ImsReasonInfo info) {
- sendMessage(obtainMessage(EVENT_IMS_REGISTRATION_STATE_CHANGED, false));
- }
- };
-
/**
* Create an instance of SatelliteSOSMessageRecommender.
*
+ * @param context The Context for the SatelliteSOSMessageRecommender.
* @param looper The looper used with the handler of this class.
*/
- public SatelliteSOSMessageRecommender(@NonNull Looper looper) {
- this(looper, SatelliteController.getInstance(), null,
- getEmergencyCallToSosMsgHysteresisTimeoutMillis());
+ public SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper) {
+ this(context, looper, SatelliteController.getInstance(), null,
+ getEmergencyCallWaitForConnectionTimeoutMillis(context));
}
/**
* Create an instance of SatelliteSOSMessageRecommender. This constructor should be used in
* only unit tests.
*
+ * @param context The Context for the SatelliteSOSMessageRecommender.
* @param looper The looper used with the handler of this class.
* @param satelliteController The SatelliteController singleton instance.
* @param imsManager The ImsManager instance associated with the phone, which is used for making
@@ -131,10 +124,11 @@
* @param timeoutMillis The timeout duration of the timer.
*/
@VisibleForTesting
- protected SatelliteSOSMessageRecommender(@NonNull Looper looper,
+ protected SatelliteSOSMessageRecommender(@NonNull Context context, @NonNull Looper looper,
@NonNull SatelliteController satelliteController, ImsManager imsManager,
long timeoutMillis) {
super(looper);
+ mContext = context;
mSatelliteController = satelliteController;
mImsManager = imsManager;
mTimeoutMillis = timeoutMillis;
@@ -176,7 +170,7 @@
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case EVENT_EMERGENCY_CALL_STARTED:
- handleEmergencyCallStartedEvent((Pair<Connection, Phone>) msg.obj);
+ handleEmergencyCallStartedEvent((Connection) msg.obj);
break;
case EVENT_TIME_OUT:
handleTimeoutEvent();
@@ -187,12 +181,11 @@
case EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED:
handleEmergencyCallConnectionStateChangedEvent((Pair<String, Integer>) msg.obj);
break;
- case EVENT_IMS_REGISTRATION_STATE_CHANGED:
- handleImsRegistrationStateChangedEvent((boolean) msg.obj);
+ case EVENT_SERVICE_STATE_CHANGED:
+ handleStateChangedEventForHysteresisTimer();
break;
- case EVENT_CELLULAR_SERVICE_STATE_CHANGED:
- AsyncResult ar = (AsyncResult) msg.obj;
- handleCellularServiceStateChangedEvent((ServiceState) ar.result);
+ case CMD_SEND_EVENT_DISPLAY_EMERGENCY_MESSAGE_FORCEFULLY:
+ handleCmdSendEventDisplayEmergencyMessageForcefully((Connection) msg.obj);
break;
default:
logd("handleMessage: unexpected message code: " + msg.what);
@@ -205,15 +198,23 @@
*
* @param connection The connection created by TelephonyConnectionService for the emergency
* call.
- * @param phone The phone used for the emergency call.
*/
- public void onEmergencyCallStarted(@NonNull Connection connection, @NonNull Phone phone) {
- if (!mSatelliteController.isSatelliteSupported()) {
+ public void onEmergencyCallStarted(@NonNull Connection connection) {
+ if (!mSatelliteController.isSatelliteSupportedViaOem()
+ && !mSatelliteController.isSatelliteSupportedViaCarrier()) {
logd("onEmergencyCallStarted: satellite is not supported");
return;
}
- Pair<Connection, Phone> argument = new Pair<>(connection, phone);
- sendMessage(obtainMessage(EVENT_EMERGENCY_CALL_STARTED, argument));
+
+ /**
+ * Right now, assume that the device is connected to satellite via carrier within hysteresis
+ * time. However, this might not be correct when the monitoring timer expires. Thus, we
+ * should do this check now so that we have higher chance of sending the event
+ * EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
+ */
+ mIsSatelliteConnectedViaCarrierWithinHysteresisTime.set(
+ mSatelliteController.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+ sendMessage(obtainMessage(EVENT_EMERGENCY_CALL_STARTED, connection));
}
/**
@@ -225,7 +226,8 @@
*/
public void onEmergencyCallConnectionStateChanged(
String callId, @Connection.ConnectionState int state) {
- if (!mSatelliteController.isSatelliteSupported()) {
+ if (!mSatelliteController.isSatelliteSupportedViaOem()
+ && !mSatelliteController.isSatelliteSupportedViaCarrier()) {
logd("onEmergencyCallConnectionStateChanged: satellite is not supported");
return;
}
@@ -233,21 +235,23 @@
sendMessage(obtainMessage(EVENT_EMERGENCY_CALL_CONNECTION_STATE_CHANGED, argument));
}
- private void handleEmergencyCallStartedEvent(@NonNull Pair<Connection, Phone> arg) {
- mSatelliteController.requestIsSatelliteCommunicationAllowedForCurrentLocation(
- SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- mReceiverForRequestIsSatelliteAllowedForCurrentLocation);
- if (mPhone != null) {
- logd("handleEmergencyCallStartedEvent: new emergency call started while there is "
- + " an ongoing call");
- unregisterForInterestedStateChangedEvents(mPhone);
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected ComponentName getDefaultSmsApp() {
+ return SmsApplication.getDefaultSmsApplication(mContext, false);
+ }
+
+ private void handleEmergencyCallStartedEvent(@NonNull Connection connection) {
+ if (sendEventDisplayEmergencyMessageForcefully(connection)) {
+ return;
}
- mPhone = arg.second;
- mEmergencyConnection = arg.first;
- mCellularServiceState.set(mPhone.getServiceState().getState());
- mIsImsRegistered.set(mPhone.isImsRegistered());
- handleStateChangedEventForHysteresisTimer();
- registerForInterestedStateChangedEvents(mPhone);
+ if (mEmergencyConnection == null) {
+ mSatelliteController.requestIsSatelliteCommunicationAllowedForCurrentLocation(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mReceiverForRequestIsSatelliteAllowedForCurrentLocation);
+ handleStateChangedEventForHysteresisTimer();
+ registerForInterestedStateChangedEvents();
+ }
+ mEmergencyConnection = connection;
}
private void handleSatelliteProvisionStateChangedEvent(boolean provisioned) {
@@ -257,20 +261,49 @@
}
private void handleTimeoutEvent() {
+ /**
+ * The device might be connected to satellite after the emergency call started. Thus, we
+ * need to do this check again so that we will have higher chance of sending the event
+ * EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
+ */
+ updateSatelliteViaCarrierAvailability();
+
boolean isDialerNotified = false;
- if (!mIsImsRegistered.get() && !isCellularAvailable()
+ if (!isImsRegistered() && !isCellularAvailable()
&& mIsSatelliteAllowedInCurrentLocation.get()
- && mSatelliteController.isSatelliteProvisioned()
+ && (isSatelliteViaOemAvailable() || isSatelliteViaCarrierAvailable())
&& shouldTrackCall(mEmergencyConnection.getState())) {
- logd("handleTimeoutEvent: Sending EVENT_DISPLAY_SOS_MESSAGE to Dialer...");
- mEmergencyConnection.sendConnectionEvent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE,
- null);
+ logd("handleTimeoutEvent: Sent EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer");
+ Bundle extras = createExtraBundleForEventDisplayEmergencyMessage();
+ mEmergencyConnection.sendConnectionEvent(
+ TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE, extras);
isDialerNotified = true;
+
}
+ logd("handleTimeoutEvent: isImsRegistered=" + isImsRegistered()
+ + ", isCellularAvailable=" + isCellularAvailable()
+ + ", mIsSatelliteAllowedInCurrentLocation="
+ + mIsSatelliteAllowedInCurrentLocation.get()
+ + ", shouldTrackCall=" + shouldTrackCall(mEmergencyConnection.getState()));
reportEsosRecommenderDecision(isDialerNotified);
cleanUpResources();
}
+ private void updateSatelliteViaCarrierAvailability() {
+ if (!mIsSatelliteConnectedViaCarrierWithinHysteresisTime.get()) {
+ mIsSatelliteConnectedViaCarrierWithinHysteresisTime.set(
+ mSatelliteController.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+ }
+ }
+
+ private boolean isSatelliteViaOemAvailable() {
+ return mSatelliteController.isSatelliteViaOemProvisioned();
+ }
+
+ private boolean isSatelliteViaCarrierAvailable() {
+ return mIsSatelliteConnectedViaCarrierWithinHysteresisTime.get();
+ }
+
private void handleEmergencyCallConnectionStateChangedEvent(
@NonNull Pair<String, Integer> arg) {
if (mEmergencyConnection == null) {
@@ -299,78 +332,117 @@
}
}
- private void handleImsRegistrationStateChangedEvent(boolean registered) {
- if (registered != mIsImsRegistered.get()) {
- mIsImsRegistered.set(registered);
- handleStateChangedEventForHysteresisTimer();
- }
- }
-
- private void handleCellularServiceStateChangedEvent(@NonNull ServiceState serviceState) {
- int state = serviceState.getState();
- if (mCellularServiceState.get() != state) {
- mCellularServiceState.set(state);
- handleStateChangedEventForHysteresisTimer();
- }
- }
-
private void reportEsosRecommenderDecision(boolean isDialerNotified) {
SatelliteStats.getInstance().onSatelliteSosMessageRecommender(
new SatelliteStats.SatelliteSosMessageRecommenderParams.Builder()
.setDisplaySosMessageSent(isDialerNotified)
.setCountOfTimerStarted(mCountOfTimerStarted)
- .setImsRegistered(mIsImsRegistered.get())
- .setCellularServiceState(mCellularServiceState.get())
+ .setImsRegistered(isImsRegistered())
+ .setCellularServiceState(getBestCellularServiceState())
+ .setIsMultiSim(isMultiSim())
+ .setRecommendingHandoverType(getEmergencyCallToSatelliteHandoverType())
+ .setIsSatelliteAllowedInCurrentLocation(
+ mIsSatelliteAllowedInCurrentLocation.get())
.build());
}
private void cleanUpResources() {
stopTimer();
- if (mPhone != null) {
- unregisterForInterestedStateChangedEvents(mPhone);
- mPhone = null;
+ if (mEmergencyConnection != null) {
+ unregisterForInterestedStateChangedEvents();
}
mEmergencyConnection = null;
mCountOfTimerStarted = 0;
}
- private void registerForInterestedStateChangedEvents(@NonNull Phone phone) {
+ private void registerForInterestedStateChangedEvents() {
mSatelliteController.registerForSatelliteProvisionStateChanged(
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mISatelliteProvisionStateCallback);
- phone.registerForServiceStateChanged(this, EVENT_CELLULAR_SERVICE_STATE_CHANGED, null);
- registerForImsRegistrationStateChanged(phone);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.registerForServiceStateChanged(
+ this, EVENT_SERVICE_STATE_CHANGED, null);
+ registerForImsRegistrationStateChanged(phone);
+ }
}
private void registerForImsRegistrationStateChanged(@NonNull Phone phone) {
ImsManager imsManager = (mImsManager != null) ? mImsManager : ImsManager.getInstance(
phone.getContext(), phone.getPhoneId());
try {
- imsManager.addRegistrationCallback(mImsRegistrationCallback, this::post);
+ imsManager.addRegistrationCallback(
+ getOrCreateImsRegistrationCallback(phone.getPhoneId()), this::post);
} catch (ImsException ex) {
loge("registerForImsRegistrationStateChanged: ex=" + ex);
}
}
- private void unregisterForInterestedStateChangedEvents(@NonNull Phone phone) {
+ private void unregisterForInterestedStateChangedEvents() {
mSatelliteController.unregisterForSatelliteProvisionStateChanged(
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mISatelliteProvisionStateCallback);
- phone.unregisterForServiceStateChanged(this);
- unregisterForImsRegistrationStateChanged(phone);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ phone.unregisterForServiceStateChanged(this);
+ unregisterForImsRegistrationStateChanged(phone);
+ }
}
private void unregisterForImsRegistrationStateChanged(@NonNull Phone phone) {
- ImsManager imsManager = (mImsManager != null) ? mImsManager : ImsManager.getInstance(
- phone.getContext(), phone.getPhoneId());
- imsManager.removeRegistrationListener(mImsRegistrationCallback);
+ if (mImsRegistrationCallbacks.contains(phone.getPhoneId())) {
+ ImsManager imsManager =
+ (mImsManager != null) ? mImsManager : ImsManager.getInstance(
+ phone.getContext(), phone.getPhoneId());
+ imsManager.removeRegistrationListener(
+ mImsRegistrationCallbacks.get(phone.getPhoneId()));
+ } else {
+ loge("Phone ID=" + phone.getPhoneId() + " was not registered with ImsManager");
+ }
}
private boolean isCellularAvailable() {
- return (mCellularServiceState.get() == ServiceState.STATE_IN_SERVICE
- || mCellularServiceState.get() == ServiceState.STATE_EMERGENCY_ONLY);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState != null) {
+ int state = serviceState.getState();
+ if ((state == STATE_IN_SERVICE || state == STATE_EMERGENCY_ONLY)
+ && !serviceState.isUsingNonTerrestrialNetwork()) {
+ return true;
+ }
+ }
+ }
+ return false;
}
- private void handleStateChangedEventForHysteresisTimer() {
- if (!mIsImsRegistered.get() && !isCellularAvailable()) {
+ /**
+ * @return {@link ServiceState#STATE_IN_SERVICE} if any subscription is in this state; else
+ * {@link ServiceState#STATE_EMERGENCY_ONLY} if any subscription is in this state; else
+ * {@link ServiceState#STATE_OUT_OF_SERVICE}.
+ */
+ private int getBestCellularServiceState() {
+ boolean isStateOutOfService = true;
+ for (Phone phone : PhoneFactory.getPhones()) {
+ ServiceState serviceState = phone.getServiceState();
+ if (serviceState != null) {
+ int state = serviceState.getState();
+ if (!serviceState.isUsingNonTerrestrialNetwork()) {
+ if ((state == STATE_IN_SERVICE)) {
+ return STATE_IN_SERVICE;
+ } else if (state == STATE_EMERGENCY_ONLY) {
+ isStateOutOfService = false;
+ }
+ }
+ }
+ }
+ return isStateOutOfService ? STATE_OUT_OF_SERVICE : STATE_EMERGENCY_ONLY;
+ }
+
+ private boolean isImsRegistered() {
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (phone.isImsRegistered()) return true;
+ }
+ return false;
+ }
+
+ private synchronized void handleStateChangedEventForHysteresisTimer() {
+ if (!isImsRegistered() && !isCellularAvailable()) {
startTimer();
} else {
stopTimer();
@@ -389,10 +461,61 @@
removeMessages(EVENT_TIME_OUT);
}
- private static long getEmergencyCallToSosMsgHysteresisTimeoutMillis() {
- return DeviceConfig.getLong(DeviceConfig.NAMESPACE_TELEPHONY,
- EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS,
- DEFAULT_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+ private static long getEmergencyCallWaitForConnectionTimeoutMillis(@NonNull Context context) {
+ return context.getResources().getInteger(
+ R.integer.config_emergency_call_wait_for_connection_timeout_millis);
+ }
+
+ /**
+ * @return The Pair(PackageName, ClassName) of the oem-enabled satellite handover app.
+ */
+ @NonNull
+ private static Pair<String, String> getOemEnabledSatelliteHandoverAppFromOverlayConfig(
+ @NonNull Context context) {
+ String app = null;
+ try {
+ app = context.getResources().getString(
+ R.string.config_oem_enabled_satellite_sos_handover_app);
+ } catch (Resources.NotFoundException ex) {
+ loge("getOemEnabledSatelliteHandoverAppFromOverlayConfig: ex=" + ex);
+ }
+ if (TextUtils.isEmpty(app) && isMockModemAllowed()) {
+ logd("getOemEnabledSatelliteHandoverAppFromOverlayConfig: Read "
+ + "config_oem_enabled_satellite_sos_handover_app from device config");
+ app = DeviceConfig.getString(DeviceConfig.NAMESPACE_TELEPHONY,
+ "config_oem_enabled_satellite_sos_handover_app", "");
+ }
+ if (TextUtils.isEmpty(app)) return new Pair<>("", "");
+
+ String[] appComponent = app.split(";");
+ if (appComponent.length == 2) {
+ return new Pair<>(appComponent[0], appComponent[1]);
+ } else {
+ loge("getOemEnabledSatelliteHandoverAppFromOverlayConfig: invalid configured app="
+ + app);
+ }
+ return new Pair<>("", "");
+ }
+
+
+ @Nullable
+ private static String getSatelliteEmergencyHandoverIntentActionFromOverlayConfig(
+ @NonNull Context context) {
+ String action;
+ try {
+ action = context.getResources().getString(
+ R.string.config_satellite_emergency_handover_intent_action);
+ } catch (Resources.NotFoundException ex) {
+ loge("getSatelliteEmergencyHandoverIntentFilterActionFromOverlayConfig: ex=" + ex);
+ action = null;
+ }
+ if (TextUtils.isEmpty(action) && isMockModemAllowed()) {
+ logd("getSatelliteEmergencyHandoverIntentActionFromOverlayConfig: Read "
+ + "config_satellite_emergency_handover_intent_action from device config");
+ action = DeviceConfig.getString(DeviceConfig.NAMESPACE_TELEPHONY,
+ "config_satellite_emergency_handover_intent_action", null);
+ }
+ return action;
}
private boolean shouldTrackCall(int connectionState) {
@@ -405,6 +528,110 @@
&& connectionState != Connection.STATE_DISCONNECTED);
}
+ @NonNull
+ private RegistrationManager.RegistrationCallback getOrCreateImsRegistrationCallback(
+ int phoneId) {
+ RegistrationManager.RegistrationCallback callback =
+ mImsRegistrationCallbacks.get(phoneId);
+ if (callback == null) {
+ callback = new RegistrationManager.RegistrationCallback() {
+ @Override
+ public void onRegistered(ImsRegistrationAttributes attributes) {
+ sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED));
+ }
+
+ @Override
+ public void onUnregistered(ImsReasonInfo info) {
+ sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED));
+ }
+ };
+ mImsRegistrationCallbacks.put(phoneId, callback);
+ }
+ return callback;
+ }
+
+ @NonNull private Bundle createExtraBundleForEventDisplayEmergencyMessage() {
+ int handoverType = EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+ Pair<String, String> oemSatelliteMessagingApp =
+ getOemEnabledSatelliteHandoverAppFromOverlayConfig(mContext);
+ String packageName = oemSatelliteMessagingApp.first;
+ String className = oemSatelliteMessagingApp.second;
+ String action = getSatelliteEmergencyHandoverIntentActionFromOverlayConfig(mContext);
+
+ if (isSatelliteViaCarrierAvailable()
+ || isEmergencyCallToSatelliteHandoverTypeT911Enforced()) {
+ ComponentName defaultSmsAppComponent = getDefaultSmsApp();
+ handoverType = EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
+ packageName = defaultSmsAppComponent.getPackageName();
+ className = defaultSmsAppComponent.getClassName();
+ }
+ logd("EVENT_DISPLAY_EMERGENCY_MESSAGE: handoverType=" + handoverType + ", packageName="
+ + packageName + ", className=" + className + ", action=" + action);
+
+ Bundle result = new Bundle();
+ result.putInt(EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE, handoverType);
+ if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {
+ result.putParcelable(EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT,
+ createHandoverAppLaunchPendingIntent(packageName, className, action));
+ }
+ return result;
+ }
+
+ @NonNull private PendingIntent createHandoverAppLaunchPendingIntent(
+ @NonNull String packageName, @NonNull String className, @Nullable String action) {
+ Intent intent = new Intent(action);
+ intent.setComponent(new ComponentName(packageName, className));
+ return PendingIntent.getActivity(mContext, 0, intent,
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
+ }
+
+ private boolean isEmergencyCallToSatelliteHandoverTypeT911Enforced() {
+ return (mSatelliteController.getEnforcedEmergencyCallToSatelliteHandoverType()
+ == EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911);
+ }
+
+ private boolean sendEventDisplayEmergencyMessageForcefully(@NonNull Connection connection) {
+ if (mSatelliteController.getEnforcedEmergencyCallToSatelliteHandoverType()
+ == INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE) {
+ return false;
+ }
+
+ long delaySeconds = mSatelliteController.getDelayInSendingEventDisplayEmergencyMessage();
+ sendMessageDelayed(
+ obtainMessage(CMD_SEND_EVENT_DISPLAY_EMERGENCY_MESSAGE_FORCEFULLY, connection),
+ delaySeconds * 1000);
+ return true;
+ }
+
+ private void handleCmdSendEventDisplayEmergencyMessageForcefully(
+ @NonNull Connection connection) {
+ logd("Sent EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer forcefully.");
+ Bundle extras = createExtraBundleForEventDisplayEmergencyMessage();
+ connection.sendConnectionEvent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE, extras);
+ }
+
+ private boolean isMultiSim() {
+ TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+ if (telephonyManager == null) {
+ loge("isMultiSim: telephonyManager is null");
+ return false;
+ }
+ return telephonyManager.isMultiSimEnabled();
+ }
+
+ private int getEmergencyCallToSatelliteHandoverType() {
+ if (isSatelliteViaCarrierAvailable()) {
+ return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
+ } else {
+ return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+ }
+ }
+
+ private static boolean isMockModemAllowed() {
+ return (SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false)
+ || SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false));
+ }
+
private static void logd(@NonNull String log) {
Rlog.d(TAG, log);
}
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 8146983..1bf866b 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -1161,7 +1161,16 @@
builder.setDisplayName(nickName);
builder.setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER);
}
- builder.setProfileClass(embeddedProfile.getProfileClass());
+
+ if (android.os.Build.isDebuggable() &&
+ SystemProperties.getInt("telephony.test.bootstrap_cid", -2)
+ == carrierId) {
+ // Force set as provisioning profile for test purpose
+ log("Hardcording as bootstrap subscription for cid=" + carrierId);
+ builder.setProfileClass(SimInfo.PROFILE_CLASS_PROVISIONING);
+ } else {
+ builder.setProfileClass(embeddedProfile.getProfileClass());
+ }
builder.setPortIndex(getPortIndex(embeddedProfile.getIccid()));
CarrierIdentifier cid = embeddedProfile.getCarrierIdentifier();
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
index 80167d6..2df688d 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
@@ -48,7 +48,7 @@
@RunWith(AndroidJUnit4.class)
public class ImsFeatureTest {
// Public for Mockito testing
- public class CapabilityCallback extends IImsCapabilityCallback.Stub {
+ public static class CapabilityCallback extends IImsCapabilityCallback.Stub {
@Override
public void onQueryCapabilityConfiguration(int capability, int radioTech, boolean enabled)
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
index 337e296..df53374 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
@@ -41,7 +41,7 @@
ITelephony mMockTelephonyInterface;
BinderCacheManager<ITelephony> mBinderCache;
- public class LocalCallback extends ImsMmTelManager.RegistrationCallback {
+ public static class LocalCallback extends ImsMmTelManager.RegistrationCallback {
int mRegResult = -1;
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 3c8db99..2dac867 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -108,7 +108,7 @@
* Controls a test {@link Context} as would be provided by the Android framework to an
* {@code Activity}, {@code Service} or other system-instantiated component.
*
- * Contains Fake<Component> classes like FakeContext for components that require complex and
+ * Contains {@code Fake<Component>} classes like FakeContext for components that require complex and
* reusable stubbing. Others can be mocked using Mockito functions in tests or constructor/public
* methods of this class.
*/
@@ -117,7 +117,6 @@
public static final String PERMISSION_ENABLE_ALL = "android.permission.STUB_PERMISSION";
public static class FakeContentProvider extends MockContentProvider {
- private String[] mColumns = {"name", "value"};
private HashMap<String, String> mKeyValuePairs = new HashMap<String, String>();
private int mNumKeyValuePairs = 0;
private HashMap<String, String> mFlags = new HashMap<>();
@@ -747,18 +746,14 @@
doAnswer(new Answer<List<ResolveInfo>>() {
@Override
public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
- return doQueryIntentServices(
- (Intent) invocation.getArguments()[0],
- (Integer) invocation.getArguments()[1]);
+ return doQueryIntentServices((Intent) invocation.getArguments()[0]);
}
}).when(mPackageManager).queryIntentServices((Intent) any(), anyInt());
doAnswer(new Answer<List<ResolveInfo>>() {
@Override
public List<ResolveInfo> answer(InvocationOnMock invocation) throws Throwable {
- return doQueryIntentServices(
- (Intent) invocation.getArguments()[0],
- (Integer) invocation.getArguments()[1]);
+ return doQueryIntentServices((Intent) invocation.getArguments()[0]);
}
}).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), any());
@@ -766,6 +761,7 @@
doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(nullable(String.class),
anyInt());
} catch (NameNotFoundException e) {
+ Log.d(TAG, "NameNotFoundException: e=" + e);
}
doAnswer((Answer<Boolean>)
@@ -775,7 +771,7 @@
try {
doReturn(mResources).when(mPackageManager).getResourcesForApplication(anyString());
} catch (NameNotFoundException ex) {
- Log.d(TAG, "NameNotFoundException: " + ex);
+ Log.d(TAG, "NameNotFoundException: ex=" + ex);
}
doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
@@ -851,7 +847,7 @@
mMockBindingFailureForPackage.add(packageName);
}
- private List<ResolveInfo> doQueryIntentServices(Intent intent, int flags) {
+ private List<ResolveInfo> doQueryIntentServices(Intent intent) {
List<ResolveInfo> result = new ArrayList<ResolveInfo>();
for (ComponentName componentName : mComponentNamesByAction.get(intent.getAction())) {
ResolveInfo resolveInfo = new ResolveInfo();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 0b25c55..378907b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -2065,6 +2065,79 @@
}
@Test
+ public void testPollStateExceptionRadioPowerOn() {
+ assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
+ assertEquals(ServiceState.STATE_IN_SERVICE, sst.getServiceState().getState());
+ assertEquals(ServiceState.STATE_IN_SERVICE,
+ sst.getServiceState().getDataRegistrationState());
+
+ sst.mPollingContext[0] = 1;
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_OPERATOR,
+ new AsyncResult(sst.mPollingContext, null,
+ new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE))));
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ assertEquals(ServiceState.STATE_IN_SERVICE, sst.getServiceState().getState());
+ assertEquals(ServiceState.STATE_IN_SERVICE,
+ sst.getServiceState().getDataRegistrationState());
+ assertEquals(0, sst.mPollingContext[0]);
+ }
+
+ @Test
+ public void testPollStateExceptionRadioPowerOff() {
+ // Turn off radio first.
+ sst.setRadioPower(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getState());
+ assertEquals(ServiceState.STATE_POWER_OFF,
+ sst.getServiceState().getDataRegistrationState());
+ // Override service state
+ sst.getServiceState().setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ sst.getServiceState().setDataRegState(ServiceState.STATE_IN_SERVICE);
+
+ sst.mPollingContext[0] = 1;
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_OPERATOR,
+ new AsyncResult(sst.mPollingContext, null,
+ new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE))));
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getVoiceRegState());
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getDataRegState());
+ assertEquals(1, sst.mPollingContext[0]);
+ }
+
+ @Test
+ public void testPollStateExceptionRadioPowerOffOnIwlan() {
+ // Turn off radio first.
+ sst.setRadioPower(false);
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getState());
+ assertEquals(ServiceState.STATE_POWER_OFF,
+ sst.getServiceState().getDataRegistrationState());
+ // Override service state
+ sst.getServiceState().setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ sst.getServiceState().setDataRegState(ServiceState.STATE_IN_SERVICE);
+ // Override to IWLAN
+ sst.mSS.setRilDataRadioTechnology(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN);
+
+ sst.mPollingContext[0] = 1;
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_OPERATOR,
+ new AsyncResult(sst.mPollingContext, null,
+ new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE))));
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ assertNull(null, sst.getServiceState().getOperatorAlpha());
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getVoiceRegState());
+ assertEquals(ServiceState.STATE_POWER_OFF, sst.getServiceState().getDataRegState());
+ assertEquals(1, sst.mPollingContext[0]);
+ }
+
+ @Test
public void testCSEmergencyRegistrationState() throws Exception {
CellIdentityGsm cellIdentity =
new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 95a6154..39c0cac 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -1014,7 +1014,6 @@
@VisibleForTesting
public int getGetOperatorCallCount() {
- final int count = mGetOperatorCallCount.get();
return mGetOperatorCallCount.get();
}
@@ -1153,7 +1152,7 @@
"fd00:976a:c305:1d::8 fd00:976a:c202:1d::7 fd00:976a:c305:1d::5"));
mSetupDataCallResult.mtu = 1440;
} catch (Exception e) {
-
+ Rlog.e(LOG_TAG, "setupDataCall: e=" + e);
}
}
@@ -1993,7 +1992,7 @@
if (!mShouldReturnCellInfo) return;
if (mCellInfoList == null) {
- ArrayList<CellInfo> mCellInfoList = new ArrayList();
+ mCellInfoList = new ArrayList();
mCellInfoList.add(getCellInfoGsm());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index c613155..1274aa3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -64,6 +64,7 @@
import android.os.RegistrantList;
import android.os.ServiceManager;
import android.os.StrictMode;
+import android.os.SystemClock;
import android.os.UserManager;
import android.permission.LegacyPermissionManager;
import android.provider.BlockedNumberContract;
@@ -148,8 +149,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -300,7 +299,7 @@
protected Context mContext;
protected FakeBlockedNumberContentProvider mFakeBlockedNumberContentProvider;
private final ContentProvider mContentProvider = spy(new ContextFixture.FakeContentProvider());
- private Object mLock = new Object();
+ private final Object mLock = new Object();
private boolean mReady;
protected HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>();
protected Phone[] mPhones;
@@ -314,9 +313,9 @@
private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
- private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
+ private final List<InstanceKey> mInstanceKeys = new ArrayList<>();
- private class InstanceKey {
+ private static class InstanceKey {
public final Class mClass;
public final String mInstName;
public final Object mObj;
@@ -333,7 +332,7 @@
@Override
public boolean equals(Object obj) {
- if (obj == null || obj.getClass() != getClass()) {
+ if (obj == null || !(obj instanceof InstanceKey)) {
return false;
}
@@ -345,15 +344,18 @@
protected void waitUntilReady() {
synchronized (mLock) {
- if (!mReady) {
+ long now = SystemClock.elapsedRealtime();
+ long deadline = now + MAX_INIT_WAIT_MS;
+ while (!mReady && now < deadline) {
try {
mLock.wait(MAX_INIT_WAIT_MS);
- } catch (InterruptedException ie) {
+ } catch (Exception e) {
+ fail("Telephony tests failed to initialize: e=" + e);
}
-
- if (!mReady) {
- fail("Telephony tests failed to initialize");
- }
+ now = SystemClock.elapsedRealtime();
+ }
+ if (!mReady) {
+ fail("Telephony tests failed to initialize");
}
}
}
@@ -392,10 +394,8 @@
}
protected synchronized void restoreInstances() throws Exception {
- Iterator<InstanceKey> it = mInstanceKeys.descendingIterator();
-
- while (it.hasNext()) {
- InstanceKey key = it.next();
+ for (int i = mInstanceKeys.size() - 1; i >= 0; i--) {
+ InstanceKey key = mInstanceKeys.get(i);
Field field = key.mClass.getDeclaredField(key.mInstName);
field.setAccessible(true);
field.set(key.mObj, mOldInstances.get(key));
@@ -710,7 +710,7 @@
doReturn(mSimRecords).when(mUiccProfile).getIccRecords();
doAnswer(new Answer<IccRecords>() {
public IccRecords answer(InvocationOnMock invocation) {
- return (mPhone.isPhoneTypeGsm()) ? mSimRecords : mRuimRecords;
+ return mSimRecords;
}
}).when(mUiccProfile).getIccRecords();
@@ -920,7 +920,9 @@
}
if (mContext != null) {
SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0);
- sharedPreferences.edit().clear().commit();
+ if (sharedPreferences != null) {
+ sharedPreferences.edit().clear().commit();
+ }
}
restoreInstances();
TelephonyManager.enableServiceHandleCaching();
@@ -944,7 +946,6 @@
mContextFixture = null;
mContext = null;
mFakeBlockedNumberContentProvider = null;
- mLock = null;
mServiceManagerMockedServices.clear();
mServiceManagerMockedServices = null;
mPhone = null;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index a09994b..01a82ba 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -415,6 +415,47 @@
.setPreferred(false)
.build();
+ private final DataProfile mEsimBootstrapDataProfile = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName("ESIM BOOTSTRAP")
+ .setApnName("ESIM BOOTSTRAP")
+ .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
+ .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR)
+ .setCarrierEnabled(true)
+ .setEsimBootstrapProvisioning(true)
+ .build())
+ .setPreferred(false)
+ .build();
+
+ private final DataProfile mEsimBootstrapImsProfile = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName("IMS BOOTSTRAP")
+ .setApnName("IMS BOOTSTRAP")
+ .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+ .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR)
+ .setCarrierEnabled(true)
+ .setEsimBootstrapProvisioning(true)
+ .build())
+ .setPreferred(false)
+ .build();
+
+ private final DataProfile mEsimBootstrapRcsInfraStructureProfile =
+ new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName("INFRASTRUCTURE BOOTSTRAP")
+ .setApnName("INFRASTRUCTURE BOOTSTRAP")
+ .setApnTypeBitmask(ApnSetting.TYPE_RCS)
+ .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR)
+ .setCarrierEnabled(true)
+ .setInfrastructureBitmask(2)
+ .setEsimBootstrapProvisioning(true)
+ .build())
+ .setPreferred(false)
+ .build();
+
/** Data call response map. The first key is the transport type, the second key is the cid. */
private final Map<Integer, Map<Integer, DataCallResponse>> mDataCallResponses = new HashMap<>();
@@ -919,7 +960,8 @@
mGeneralPurposeDataProfileAlternative, mImsCellularDataProfile,
mImsIwlanDataProfile, mEmergencyDataProfile, mFotaDataProfile,
mTetheringDataProfile, mMmsOnWlanDataProfile, mLowLatencyDataProfile,
- mNtnDataProfile);
+ mNtnDataProfile, mEsimBootstrapDataProfile,
+ mEsimBootstrapImsProfile, mEsimBootstrapRcsInfraStructureProfile);
doAnswer(invocation -> {
DataProfile dp = (DataProfile) invocation.getArguments()[0];
@@ -951,7 +993,8 @@
(TelephonyNetworkRequest) invocation.getArguments()[0];
int networkType = (int) invocation.getArguments()[1];
boolean isNtn = (boolean) invocation.getArguments()[2];
- boolean ignorePermanentFailure = (boolean) invocation.getArguments()[3];
+ boolean isEsimBootstrapProvisioning = (boolean) invocation.getArguments()[3];
+ boolean ignorePermanentFailure = (boolean) invocation.getArguments()[4];
for (DataProfile dataProfile : profiles) {
ApnSetting apnSetting = dataProfile.getApnSetting();
@@ -960,20 +1003,24 @@
&& (apnSetting.getNetworkTypeBitmask() == 0
|| (apnSetting.getNetworkTypeBitmask()
& ServiceState.getBitmaskForTech(networkType)) != 0)
+ && (isEsimBootstrapProvisioning
+ == apnSetting.isEsimBootstrapProvisioning())
&& ((isNtn && apnSetting.isForInfrastructure(
- ApnSetting.INFRASTRUCTURE_SATELLITE))
- || ((!isNtn && apnSetting.isForInfrastructure(
- ApnSetting.INFRASTRUCTURE_CELLULAR))))
+ ApnSetting.INFRASTRUCTURE_SATELLITE))
+ || (!isNtn && apnSetting.isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_CELLULAR)))
&& (ignorePermanentFailure || !apnSetting.getPermanentFailed())) {
return dataProfile;
}
}
logd("Cannot find data profile to satisfy " + networkRequest + ", network type="
+ TelephonyManager.getNetworkTypeName(networkType) + ", ignorePermanentFailure="
- + ignorePermanentFailure + ", isNtn=" + isNtn);
+ + ignorePermanentFailure + ", isNtn=" + isNtn + ","
+ + "isEsimBootstrapProvisioning=" + isEsimBootstrapProvisioning);
return null;
}).when(mDataProfileManager).getDataProfileForNetworkRequest(
- any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean());
+ any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean(),
+ anyBoolean());
doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
.getPreferredTransportByNetworkCapability(anyInt());
@@ -1181,6 +1228,18 @@
+ dataNetworkList);
}
+ private void verifyConnectedNetworkHasNoDataProfile(@NonNull DataProfile dataProfile)
+ throws Exception {
+ List<DataNetwork> dataNetworkList = getDataNetworks();
+ for (DataNetwork dataNetwork : getDataNetworks()) {
+ if (dataNetwork.isConnected() && dataNetwork.getDataProfile().equals(dataProfile)) {
+ fail("network with " + dataProfile + " is connected. dataNetworkList="
+ + dataNetworkList);
+ }
+ }
+ return;
+ }
+
private void verifyAllDataDisconnected() throws Exception {
List<DataNetwork> dataNetworkList = getDataNetworks();
assertWithMessage("All data should be disconnected but it's not. " + dataNetworkList)
@@ -1255,7 +1314,8 @@
+ TelephonyManager.getNetworkTypeName(networkType));
return null;
}).when(mDataProfileManager).getDataProfileForNetworkRequest(
- any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean());
+ any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean(),
+ anyBoolean());
// verify the network still connects
verify(mMockedDataNetworkControllerCallback).onConnectedInternetDataNetworksChanged(any());
@@ -1300,7 +1360,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
NetworkCapabilities netCaps = new NetworkCapabilities();
netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
@@ -1515,7 +1575,7 @@
// Now RAT changes from UMTS to GSM
doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_GSM),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
serviceStateChanged(TelephonyManager.NETWORK_TYPE_GSM,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
verifyAllDataDisconnected();
@@ -1529,14 +1589,14 @@
// Now RAT changes from GSM to UMTS
doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_UMTS),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
doReturn(mGeneralPurposeDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
// Now RAT changes from UMTS to LTE
serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
@@ -3531,7 +3591,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
NetworkCapabilities netCaps = new NetworkCapabilities();
netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
@@ -4593,7 +4653,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
@@ -4631,7 +4691,7 @@
createDataCallResponse(2, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mLowLatencyDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
processAllFutureMessages();
dataNetworkList = getDataNetworks();
@@ -4664,7 +4724,7 @@
// Mock the designated MMS profile when WLAN is preferred
doReturn(mMmsOnWlanDataProfile).when(mDataProfileManager).getDataProfileForNetworkRequest(
any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_IWLAN),
- anyBoolean(), anyBoolean());
+ anyBoolean(), anyBoolean(), anyBoolean());
setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager,
createDataCallResponse(2, DataCallResponse.LINK_STATUS_ACTIVE));
@@ -4686,4 +4746,132 @@
processAllMessages();
verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
}
+
+ @Test
+ public void testIsEsimBootStrapProvisioningActivatedWithFlagEnabledAndProvisioningClass() {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isTrue();
+ }
+
+ @Test
+ public void testIsEsimBootStrapProvisioningActivatedWithFlagEnabledAndNoProvisioningClass() {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_UNSET).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isFalse();
+ }
+
+ @Test
+ public void testIsEsimBootStrapProvisioningActivatedWithFlagDisabledAndNoProvisioningClass() {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(false);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_UNSET).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isFalse();
+ }
+
+ @Test
+ public void testIsEsimBootStrapProvisioningActivatedWithFlagDisabledAndProvisioningClass() {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(false);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isFalse();
+ }
+
+ @Test
+ public void testNetworkOnProvisioningProfileClass_WithFlagEnabled() throws Exception {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ processAllMessages();
+ verifyConnectedNetworkHasDataProfile(mEsimBootstrapDataProfile);
+
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
+ NetworkCapabilities.NET_CAPABILITY_MMTEL));
+ setSuccessfulSetupDataResponse(mMockedDataServiceManagers
+ .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
+ processAllMessages();
+ verifyConnectedNetworkHasDataProfile(mEsimBootstrapImsProfile);
+
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+ processAllMessages();
+ verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
+ }
+
+ @Test
+ public void testNetworkOnNonProvisioningProfileClass_WithFlagEnabled() throws Exception {
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_UNSET).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ processAllMessages();
+ verifyConnectedNetworkHasNoDataProfile(mEsimBootstrapDataProfile);
+
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
+ NetworkCapabilities.NET_CAPABILITY_MMTEL));
+ setSuccessfulSetupDataResponse(mMockedDataServiceManagers
+ .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
+ processAllMessages();
+ verifyConnectedNetworkHasNoDataProfile(mEsimBootstrapImsProfile);
+ }
+
+ @Test
+ public void testNtnNetworkOnProvisioningProfileClass_WithFlagEnabled() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+ mIsNonTerrestrialNetwork = true;
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+ processAllMessages();
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isTrue();
+ verifyConnectedNetworkHasNoDataProfile(mNtnDataProfile);
+ verifyConnectedNetworkHasDataProfile(mEsimBootstrapRcsInfraStructureProfile);
+ }
+
+ @Test
+ public void testNonNtnNetworkOnProvisioningProfileClass_WithFlagEnabled() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+ when(mFeatureFlags.esimBootstrapProvisioningFlag()).thenReturn(true);
+ doReturn(new SubscriptionInfoInternal.Builder().setId(1)
+ .setProfileClass(SubscriptionManager.PROFILE_CLASS_PROVISIONING).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+ processAllMessages();
+
+ assertThat(mDataNetworkControllerUT.isEsimBootStrapProvisioningActivated()).isTrue();
+ verifyConnectedNetworkHasNoDataProfile(mNtnDataProfile);
+ verifyConnectedNetworkHasNoDataProfile(mEsimBootstrapRcsInfraStructureProfile);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index f9a11be..f8d22cd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -84,8 +84,12 @@
private static final String TETHERING_APN = "DUN_APN";
private static final String APN_SET_ID_1_APN = "APN_SET_ID_1_APN";
private static final String RCS_APN = "RCS_APN";
+ private static final String RCS_APN1 = "RCS_APN1";
private static final String APN_SET_ID_1_TETHERING_APN = "APN_SET_ID_1_TETHERING_APN";
private static final String MATCH_ALL_APN_SET_ID_IMS_APN = "MATCH_ALL_APN_SET_ID_IMS_APN";
+ private static final String ESIM_BOOTSTRAP_PROVISIONING_APN = "ESIM_BOOTSTRAP_PROVISIONING_APN";
+ private static final String TEST_BOOTSTRAP_APN =
+ "TEST_BOOTSTRAP_APN";
private static final String PLMN = "330123";
private static final int DEFAULT_APN_SET_ID = Telephony.Carriers.NO_APN_SET_ID;
private static final int APN_SET_ID_1 = 1;
@@ -137,7 +141,8 @@
Telephony.Carriers.CARRIER_ID,
Telephony.Carriers.SKIP_464XLAT,
Telephony.Carriers.ALWAYS_ON,
- Telephony.Carriers.INFRASTRUCTURE_BITMASK
+ Telephony.Carriers.INFRASTRUCTURE_BITMASK,
+ Telephony.Carriers.ESIM_BOOTSTRAP_PROVISIONING
};
private int mPreferredApnSet = 0;
@@ -177,7 +182,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
// default internet data profile for RAT CDMA, to test update preferred data profile
new Object[]{
@@ -213,7 +219,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
2, // id
@@ -248,7 +255,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
3, // id
@@ -283,7 +291,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
4, // id
@@ -319,7 +328,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
// This APN entry is created to test de-duping.
new Object[]{
@@ -356,7 +366,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
6, // id
@@ -392,7 +403,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
7, // id
@@ -428,7 +440,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
8, // id
@@ -464,7 +477,8 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 1 // INFRASTRUCTURE_CELLULAR
+ 1, // INFRASTRUCTURE_CELLULAR
+ 0 // esim_bootstrap_provisioning
},
new Object[]{
9, // id
@@ -500,7 +514,156 @@
-1, // carrier_id
-1, // skip_464xlat
0, // always_on
- 2 // INFRASTRUCTURE_SATELLITE
+ 2, // INFRASTRUCTURE_SATELLITE
+ 0 // esim_bootstrap_provisioning
+ },
+ new Object[]{
+ 10, // id
+ PLMN, // numeric
+ ESIM_BOOTSTRAP_PROVISIONING_APN, // name
+ ESIM_BOOTSTRAP_PROVISIONING_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "default,supl", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ MATCH_ALL_APN_SET_ID, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0, // always_on
+ 1, // INFRASTRUCTURE_CELLULAR
+ 1 // esim_bootstrap_provisioning
+ },
+ new Object[]{
+ 11, // id
+ PLMN, // numeric
+ IMS_APN, // name
+ IMS_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "ims", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ MATCH_ALL_APN_SET_ID, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0, // always_on
+ 1, // INFRASTRUCTURE_SATELLITE
+ 1 // esim_bootstrap_provisioning
+ },
+ new Object[]{
+ 12, // id
+ PLMN, // numeric
+ TEST_BOOTSTRAP_APN, // name
+ TEST_BOOTSTRAP_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "default", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ MATCH_ALL_APN_SET_ID, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0, // always_on
+ 2, // INFRASTRUCTURE_SATELLITE
+ 1 // esim_bootstrap_provisioning
+ },
+ new Object[]{
+ 13, // id
+ PLMN, // numeric
+ RCS_APN1, // name
+ RCS_APN1, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "rcs", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ DEFAULT_APN_SET_ID, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0, // always_on
+ 2, // INFRASTRUCTURE_SATELLITE
+ 1 // esim_bootstrap_provisioning
}
);
@@ -716,7 +879,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -727,7 +890,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -737,7 +900,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(IMS_APN);
@@ -746,7 +909,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dp).isNull();
doReturn(new NetworkRegistrationInfo.Builder()
@@ -759,7 +922,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_NR, false, false);
+ TelephonyManager.NETWORK_TYPE_NR, false, false , false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(TETHERING_APN);
}
@@ -771,7 +934,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_GSM, false, false);
+ TelephonyManager.NETWORK_TYPE_GSM, false, false, false);
// Should not find data profile due to RAT incompatible.
assertThat(dp).isNull();
}
@@ -783,14 +946,14 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
logd("Set setLastSetupTimestamp on " + dataProfile);
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
// See if another one can be returned.
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
}
@@ -801,7 +964,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -814,7 +977,7 @@
.addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
0, NetworkRequest.Type.REQUEST), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -830,7 +993,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -846,7 +1009,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -864,7 +1027,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, true, false);
+ TelephonyManager.NETWORK_TYPE_LTE, true, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(RCS_APN);
@@ -877,7 +1040,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
dataProfile.setPreferred(true);
@@ -891,14 +1054,14 @@
// Test See if the same one can be returned.
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
// Test Another default internet network connected due to RAT changed. Verify the preferred
// data profile is updated.
DataProfile legacyRatDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_CDMA, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_CDMA, false, false, false);
DataNetwork legacyRatInternetNetwork = Mockito.mock(DataNetwork.class);
doReturn(legacyRatDataProfile).when(legacyRatInternetNetwork).getDataProfile();
doReturn(new DataNetworkController.NetworkRequestList(List.of(tnr)))
@@ -917,7 +1080,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
.build(), mPhone);
DataProfile dunDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- dunTnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ dunTnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
DataNetwork dunInternetNetwork = Mockito.mock(DataNetwork.class);
doReturn(dunDataProfile).when(dunInternetNetwork).getDataProfile();
doReturn(new DataNetworkController.NetworkRequestList(List.of(dunTnr)))
@@ -1016,7 +1179,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile).isNull();
// expect default EIMS when SIM absent
@@ -1025,7 +1188,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
// expect no default IMS when SIM absent
@@ -1034,7 +1197,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile).isEqualTo(null);
// Verify null as initial attached data profile is sent to modem
@@ -1064,7 +1227,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile).isNull();
// expect default EIMS when SIM absent
@@ -1073,7 +1236,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
// expect no default IMS when SIM absent
@@ -1082,7 +1245,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile).isEqualTo(null);
// Verify in legacy mode, null IA should NOT be sent to modem
@@ -1117,7 +1280,7 @@
new TelephonyNetworkRequest(new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone),
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(IMS_APN);
}
@@ -1129,7 +1292,7 @@
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
// This should get the merged data profile after deduping.
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
}
@@ -1266,7 +1429,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApn()).isEqualTo("sos");
assertThat(dataProfile.getTrafficDescriptor().getDataNetworkName()).isEqualTo("sos");
@@ -1283,7 +1446,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
DataNetwork internetNetwork = Mockito.mock(DataNetwork.class);
@@ -1354,7 +1517,7 @@
// The carrier configured data profile should be the preferred APN after APN reset
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
@@ -1367,7 +1530,7 @@
// The carrier configured data profile should be the preferred APN after APN reset
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
}
@@ -1648,7 +1811,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
// Mark the APN as permanent failed.
dp.getApnSetting().setPermanentFailed(true);
@@ -1656,7 +1819,8 @@
// Data profile manager should return a different data profile for setup as the previous
// data profile has been marked as permanent failed.
assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNotEqualTo(dp);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false))
+ .isNotEqualTo(dp);
}
@Test
@@ -1671,7 +1835,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false);
// Mark the APN as permanent failed.
dp.getApnSetting().setPermanentFailed(true);
@@ -1679,7 +1843,8 @@
// Since preferred APN is already set, and that data profile was marked as permanent failed,
// so this should result in getting nothing.
assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNull();
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false))
+ .isNull();
}
private void changeSimStateTo(@TelephonyManager.SimState int simState) {
@@ -1700,6 +1865,98 @@
// Verify the we can get the previously permanent failed data profile again.
assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(
new TelephonyNetworkRequest(request, mPhone),
- TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNotNull();
+ TelephonyManager.NETWORK_TYPE_LTE, false, false, false))
+ .isNotNull();
}
+
+ @Test
+ public void testDifferentNetworkRequestProfilesOnEsimBootStrapProvisioning() {
+ Mockito.clearInvocations(mDataProfileManagerCallback);
+ Mockito.clearInvocations(mMockedWwanDataServiceManager);
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ // SIM inserted
+ mDataProfileManagerUT.obtainMessage(3 /* EVENT_SIM_REFRESH */).sendToTarget();
+ processAllMessages();
+
+ // expect default profile for internet network request, when esim bootstrap provisioning
+ // flag is enabled at data profile, during esim bootstrap provisioning
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build(), mPhone);
+ DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
+ assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(
+ "ESIM_BOOTSTRAP_PROVISIONING_APN");
+
+ // expect IMS profile for ims network request, when esim bootstrap provisioning flag
+ // is enabled at data profile, during esim bootstrap provisioning
+ tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+ .build(), mPhone);
+ dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
+ assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("IMS_APN");
+
+ // expect no mms profile for mms network request, when esim bootstrap provisioning flag
+ // is disabled at data profile, during esim bootstrap provisioning
+ tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
+ .build(), mPhone);
+ dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
+ assertThat(dataProfile).isEqualTo(null);
+
+ // expect no rcs profile for rcs network request, when esim bootstrap provisioning flag
+ // is disabled at data profile, during esim bootstrap provisioning
+ tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .build(), mPhone);
+ dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
+ assertThat(dataProfile).isEqualTo(null);
+ }
+
+ @Test
+ public void testEsimBootstrapProvisioningEnabled_MultipleProfile() {
+ Mockito.clearInvocations(mDataProfileManagerCallback);
+ Mockito.clearInvocations(mMockedWwanDataServiceManager);
+
+ // SIM inserted
+ mDataProfileManagerUT.obtainMessage(3 /* EVENT_SIM_REFRESH */).sendToTarget();
+ processAllMessages();
+
+ // expect initial default profile entry selected for internet network request, when
+ // multiple esim bootstrap provisioning flag is enabled at data profile for same apn
+ // type
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build(), mPhone);
+ DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, true, false);
+ assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(
+ ESIM_BOOTSTRAP_PROVISIONING_APN);
+ }
+
+ @Test
+ public void testInfrastructureProfileOnEsimBootStrapProvisioning() {
+ Mockito.clearInvocations(mDataProfileManagerCallback);
+ Mockito.clearInvocations(mMockedWwanDataServiceManager);
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ // SIM inserted
+ mDataProfileManagerUT.obtainMessage(3 /* EVENT_SIM_REFRESH */).sendToTarget();
+ processAllMessages();
+
+ // expect initial default profile entry selected for internet network request, when
+ // multiple esim bootstrap provisioning flag is enabled at data profile for same apn
+ // type
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .build(), mPhone);
+ DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, true, true, false);
+ assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(RCS_APN1);
+ }
+
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index aa24c46..0cbb0f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -1034,6 +1034,9 @@
mSatelliteSosMessageRecommender1.isImsRegistered = false;
mSatelliteSosMessageRecommender1.cellularServiceState =
TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE;
+ mSatelliteSosMessageRecommender1.isMultiSim = true;
+ mSatelliteSosMessageRecommender1.recommendingHandoverType = 1;
+ mSatelliteSosMessageRecommender1.isSatelliteAllowedInCurrentLocation = true;
mSatelliteSosMessageRecommender1.count = 1;
mSatelliteSosMessageRecommender2 = new SatelliteSosMessageRecommender();
@@ -1042,6 +1045,9 @@
mSatelliteSosMessageRecommender2.isImsRegistered = true;
mSatelliteSosMessageRecommender2.cellularServiceState =
TelephonyProtoEnums.SERVICE_STATE_POWER_OFF;
+ mSatelliteSosMessageRecommender2.isMultiSim = false;
+ mSatelliteSosMessageRecommender2.recommendingHandoverType = 0;
+ mSatelliteSosMessageRecommender2.isSatelliteAllowedInCurrentLocation = true;
mSatelliteSosMessageRecommender2.count = 1;
mSatelliteSosMessageRecommenders =
@@ -4689,7 +4695,11 @@
== expectedStats.isDisplaySosMessageSent
&& stats.countOfTimerStarted == expectedStats.countOfTimerStarted
&& stats.isImsRegistered == expectedStats.isImsRegistered
- && stats.cellularServiceState == expectedStats.cellularServiceState) {
+ && stats.cellularServiceState == expectedStats.cellularServiceState
+ && stats.isMultiSim == expectedStats.isMultiSim
+ && stats.recommendingHandoverType == expectedStats.recommendingHandoverType
+ && stats.isSatelliteAllowedInCurrentLocation
+ == expectedStats.isSatelliteAllowedInCurrentLocation) {
actualCount = stats.count;
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
index 4393f1c..959b643 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
@@ -225,6 +225,9 @@
.setCountOfTimerStarted(5)
.setImsRegistered(false)
.setCellularServiceState(TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE)
+ .setIsMultiSim(false)
+ .setRecommendingHandoverType(0)
+ .setIsSatelliteAllowedInCurrentLocation(true)
.build();
mSatelliteStats.onSatelliteSosMessageRecommender(param);
@@ -238,6 +241,10 @@
assertEquals(param.getCountOfTimerStarted(), stats.countOfTimerStarted);
assertEquals(param.isImsRegistered(), stats.isImsRegistered);
assertEquals(param.getCellularServiceState(), stats.cellularServiceState);
+ assertEquals(param.isMultiSim(), stats.isMultiSim);
+ assertEquals(param.getRecommendingHandoverType(), stats.recommendingHandoverType);
+ assertEquals(param.isSatelliteAllowedInCurrentLocation(),
+ stats.isSatelliteAllowedInCurrentLocation);
verifyNoMoreInteractions(mPersistAtomsStorage);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
index 3578707..94f56b4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
@@ -429,7 +429,7 @@
@Test
public void testRegisterForSatelliteDatagram_satelliteNotSupported() {
- when(mMockSatelliteController.isSatelliteSupported()).thenReturn(false);
+ when(mMockSatelliteController.isSatelliteSupportedViaOem()).thenReturn(false);
ISatelliteDatagramCallback callback = new ISatelliteDatagramCallback() {
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 221aa0e..0556ef5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_GOOD;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_GREAT;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
@@ -92,6 +94,7 @@
import android.os.ResultReceiver;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
+import android.telephony.ServiceState;
import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
@@ -109,6 +112,8 @@
import com.android.internal.R;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.IVoidConsumer;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
@@ -121,6 +126,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -154,6 +160,7 @@
private TestSatelliteController mSatelliteControllerUT;
private TestSharedPreferences mSharedPreferences;
private PersistableBundle mCarrierConfigBundle;
+ private ServiceState mServiceState2;
@Mock private DatagramController mMockDatagramController;
@Mock private SatelliteModemInterface mMockSatelliteModemInterface;
@@ -433,6 +440,13 @@
mMockSessionMetricsStats);
replaceInstance(SubscriptionManagerService.class, "sInstance", null,
mMockSubscriptionManagerService);
+ replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, mPhone2});
+
+ mServiceState2 = Mockito.mock(ServiceState.class);
+ when(mPhone.getServiceState()).thenReturn(mServiceState);
+ when(mPhone.getSubId()).thenReturn(SUB_ID);
+ when(mPhone2.getServiceState()).thenReturn(mServiceState2);
+ when(mPhone2.getSubId()).thenReturn(SUB_ID1);
mContextFixture.putStringArrayResource(
R.array.config_satellite_providers,
@@ -2318,6 +2332,70 @@
.stopSendingNtnSignalStrength(any(Message.class));
}
+ @Test
+ public void testIsSatelliteSupportedViaCarrier() {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
+ assertFalse(mSatelliteControllerUT.isSatelliteSupportedViaCarrier());
+
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+ assertFalse(mSatelliteControllerUT.isSatelliteSupportedViaCarrier());
+
+ mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true);
+ for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
+ : mCarrierConfigChangedListenerList) {
+ pair.first.execute(() -> pair.second.onCarrierConfigChanged(
+ /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0)
+ );
+ }
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isSatelliteSupportedViaCarrier());
+ }
+
+ @Test
+ public void testCarrierEnabledSatelliteConnectionHysteresisTime() {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
+ assertFalse(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+ mCarrierConfigBundle.putInt(KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, 1 * 60);
+ mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true);
+ for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
+ : mCarrierConfigChangedListenerList) {
+ pair.first.execute(() -> pair.second.onCarrierConfigChanged(
+ /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0)
+ );
+ }
+ processAllMessages();
+ mSatelliteControllerUT.elapsedRealtime = 0;
+ assertFalse(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+
+ when(mServiceState.isUsingNonTerrestrialNetwork()).thenReturn(false);
+ when(mServiceState2.isUsingNonTerrestrialNetwork()).thenReturn(false);
+ sendServiceStateChangedEvent();
+ processAllMessages();
+ assertFalse(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+
+ // Last satellite connected time of Phone2 should be 0
+ when(mServiceState2.isUsingNonTerrestrialNetwork()).thenReturn(true);
+ sendServiceStateChangedEvent();
+ processAllMessages();
+ // 2 minutes later and hysteresis timeout is 1 minute
+ mSatelliteControllerUT.elapsedRealtime = 2 * 60 * 1000;
+ // But Phone2 is connected to NTN right now
+ assertTrue(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+
+ // Last satellite disconnected time of Phone2 should be 2 * 60 * 1000
+ when(mServiceState2.isUsingNonTerrestrialNetwork()).thenReturn(false);
+ sendServiceStateChangedEvent();
+ processAllMessages();
+ // Current time (2) - last disconnected time (2) < hysteresis timeout (1)
+ assertTrue(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+
+ // Current time (4) - last disconnected time (2) > hysteresis timeout (1)
+ mSatelliteControllerUT.elapsedRealtime = 4 * 60 * 1000;
+ assertFalse(mSatelliteControllerUT.isSatelliteConnectedViaCarrierWithinHysteresisTime());
+ }
+
private void resetSatelliteControllerUTEnabledState() {
logd("resetSatelliteControllerUTEnabledState");
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
@@ -2841,7 +2919,7 @@
private void sendCmdStartSendingNtnSignalStrengthChangedEvent(boolean shouldReport) {
Message msg = mSatelliteControllerUT.obtainMessage(
- 35 /* CMD_START_SENDING_NTN_SIGNAL_STRENGTH */);
+ 35 /* CMD_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING */);
msg.obj = new AsyncResult(null, shouldReport, null);
msg.sendToTarget();
}
@@ -2850,12 +2928,17 @@
@NtnSignalStrength.NtnSignalStrengthLevel int ntnSignalStrengthLevel,
Throwable exception) {
Message msg = mSatelliteControllerUT.obtainMessage(
- 36 /* EVENT_START_SENDING_NTN_SIGNAL_STRENGTH_DONE */);
+ 36 /* EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE */);
msg.obj = new AsyncResult(null, new NtnSignalStrength(ntnSignalStrengthLevel),
exception);
msg.sendToTarget();
}
+ private void sendServiceStateChangedEvent() {
+ mSatelliteControllerUT.obtainMessage(37 /* EVENT_SERVICE_STATE_CHANGED */).sendToTarget();
+
+ }
+
private void setRadioPower(boolean on) {
mSimulatedCommands.setRadioPower(on, false, false, null);
}
@@ -3008,6 +3091,7 @@
private static class TestSatelliteController extends SatelliteController {
public boolean setSettingsKeyForSatelliteModeCalled = false;
public boolean allRadiosDisabled = true;
+ public long elapsedRealtime = 0;
public int satelliteModeSettingValue = SATELLITE_MODE_ENABLED_FALSE;
TestSatelliteController(
@@ -3039,5 +3123,10 @@
logd("getCurrentNtnRadioTechnology: val=" + ntRadioTechnology);
return ntRadioTechnology;
}
+
+ @Override
+ protected long getElapsedRealtime() {
+ return elapsedRealtime;
+ }
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
index 3a108aa..589f32b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -16,6 +16,11 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -26,17 +31,17 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
-import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
-import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.telecom.Connection;
import android.telephony.BinderCacheManager;
-import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -45,11 +50,14 @@
import android.telephony.satellite.SatelliteManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.text.TextUtils;
import android.util.Log;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
+import com.android.internal.R;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.flags.FeatureFlags;
@@ -61,8 +69,10 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -76,13 +86,16 @@
private static final String TAG = "SatelliteSOSMessageRecommenderTest";
private static final long TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500;
private static final int PHONE_ID = 0;
+ private static final int PHONE_ID2 = 1;
private static final String CALL_ID = "CALL_ID";
private static final String WRONG_CALL_ID = "WRONG_CALL_ID";
+ private static final String DEFAULT_SATELLITE_MESSAGING_PACKAGE = "android.com.google.default";
+ private static final String DEFAULT_SATELLITE_MESSAGING_CLASS =
+ "android.com.google.default.SmsMmsApp";
+ private static final String DEFAULT_HANDOVER_INTENT_ACTION =
+ "android.com.vendor.action.EMERGENCY_MESSAGING";
private TestSatelliteController mTestSatelliteController;
private TestImsManager mTestImsManager;
-
- @Mock
- private Context mMockContext;
@Mock
private Resources mResources;
@Mock
@@ -91,40 +104,38 @@
private FeatureFlags mFeatureFlags;
private TestConnection mTestConnection;
private TestSOSMessageRecommender mTestSOSMessageRecommender;
+ private ServiceState mServiceState2;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
MockitoAnnotations.initMocks(this);
- when(mMockContext.getMainLooper()).thenReturn(Looper.myLooper());
- when(mMockContext.getResources()).thenReturn(mResources);
- when(mResources.getString(com.android.internal.R.string.config_satellite_service_package))
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getString(R.string.config_satellite_service_package))
.thenReturn("");
- when(mMockContext.getSystemServiceName(CarrierConfigManager.class))
- .thenReturn("CarrierConfigManager");
- when(mMockContext.getSystemService(CarrierConfigManager.class))
- .thenReturn(mCarrierConfigManager);
- when(mMockContext.getSystemServiceName(SubscriptionManager.class))
- .thenReturn("SubscriptionManager");
- when(mMockContext.getSystemService(SubscriptionManager.class))
- .thenReturn(mSubscriptionManager);
- when(mMockContext.getSystemServiceName(ActivityManager.class))
- .thenReturn("ActivityManager");
- when(mMockContext.getSystemService(ActivityManager.class))
- .thenReturn(mActivityManager);
+ when(mResources.getString(R.string.config_satellite_emergency_handover_intent_action))
+ .thenReturn(DEFAULT_HANDOVER_INTENT_ACTION);
when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
- mTestSatelliteController = new TestSatelliteController(mMockContext,
+ mTestSatelliteController = new TestSatelliteController(mContext,
Looper.myLooper(), mFeatureFlags);
mTestImsManager = new TestImsManager(
- mMockContext, PHONE_ID, mMmTelFeatureConnectionFactory, null, null, null);
+ mContext, PHONE_ID, mMmTelFeatureConnectionFactory, null, null, null);
mTestConnection = new TestConnection(CALL_ID);
+ mPhones = new Phone[] {mPhone, mPhone2};
+ replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+ mServiceState2 = Mockito.mock(ServiceState.class);
when(mPhone.getServiceState()).thenReturn(mServiceState);
- mTestSOSMessageRecommender = new TestSOSMessageRecommender(Looper.myLooper(),
+ when(mPhone.getPhoneId()).thenReturn(PHONE_ID);
+ when(mPhone2.getServiceState()).thenReturn(mServiceState2);
+ when(mPhone2.getPhoneId()).thenReturn(PHONE_ID2);
+ mTestSOSMessageRecommender = new TestSOSMessageRecommender(mContext, Looper.myLooper(),
mTestSatelliteController, mTestImsManager,
TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+ when(mServiceState2.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
when(mPhone.isImsRegistered()).thenReturn(false);
+ when(mPhone2.isImsRegistered()).thenReturn(false);
}
@After
@@ -133,18 +144,103 @@
}
@Test
- public void testTimeoutBeforeEmergencyCallEnd() {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ public void testTimeoutBeforeEmergencyCallEnd_T911() {
+ testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
+ DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS,
+ DEFAULT_HANDOVER_INTENT_ACTION);
+ }
+
+ @Test
+ public void testTimeoutBeforeEmergencyCallEnd_SOS_WithValidHandoverAppConfigured() {
+ String satelliteHandoverApp =
+ "android.com.vendor.message;android.com.vendor.message.SmsApp";
+ when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
+ .thenReturn(satelliteHandoverApp);
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS,
+ "android.com.vendor.message", "android.com.vendor.message.SmsApp",
+ DEFAULT_HANDOVER_INTENT_ACTION);
+ }
+
+ @Test
+ public void testTimeoutBeforeEmergencyCallEnd_SOS_WithInValidHandoverAppConfigured() {
+ String satelliteHandoverApp =
+ "android.com.vendor.message;android.com.vendor.message.SmsApp;abc";
+ when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
+ .thenReturn(satelliteHandoverApp);
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS, "", "",
+ DEFAULT_HANDOVER_INTENT_ACTION);
+ }
+
+ @Test
+ public void testTimeoutBeforeEmergencyCallEnd_SOS_WithoutHandoverAppConfigured() {
+ when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
+ .thenReturn("");
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS, "", "",
+ DEFAULT_HANDOVER_INTENT_ACTION);
+ }
+
+ private void testTimeoutBeforeEmergencyCallEnd(int expectedHandoverType,
+ String expectedPackageName, String expectedClassName, String expectedAction) {
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
// Wait for the timeout to expires
moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
processAllMessages();
+ if (TextUtils.isEmpty(expectedPackageName) || TextUtils.isEmpty(expectedClassName)) {
+ assertTrue(mTestConnection.isEventWithoutLaunchIntentSent(
+ TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE, expectedHandoverType));
+ } else {
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ expectedHandoverType, expectedPackageName, expectedClassName, expectedAction));
+ }
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+ }
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
- assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ @Test
+ public void testTimeoutBeforeEmergencyCallEnd_EventDisplayEmergencyMessageNotSent() {
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ mTestSatelliteController.setIsSatelliteViaOemProvisioned(false);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ processAllMessages();
+ assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+
+ // Wait for the timeout to expires
+ moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+ processAllMessages();
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+ }
+
+ @Test
+ public void testTimeoutBeforeEmergencyCallEnd_T911_FromNotConnectedToConnected() {
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ processAllMessages();
+ assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
+ // Wait for the timeout to expires
+ moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
+ processAllMessages();
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
+ DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS,
+ DEFAULT_HANDOVER_INTENT_ACTION));
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
}
@Test
@@ -159,22 +255,34 @@
@Test
public void testImsRegistrationStateChangedBeforeTimeout() {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
- mTestImsManager.sendImsRegistrationStateChangedEvent(true);
+ when(mPhone.isImsRegistered()).thenReturn(true);
+ mTestImsManager.sendImsRegistrationStateChangedEvent(0, true);
processAllMessages();
- assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
- mTestImsManager.sendImsRegistrationStateChangedEvent(false);
+ when(mPhone.isImsRegistered()).thenReturn(false);
+ when(mPhone2.isImsRegistered()).thenReturn(true);
+ mTestImsManager.sendImsRegistrationStateChangedEvent(1, true);
+ processAllMessages();
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
+ assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+ assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
+
+ when(mPhone2.isImsRegistered()).thenReturn(false);
+ mTestImsManager.sendImsRegistrationStateChangedEvent(1, false);
processAllMessages();
assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
@@ -182,19 +290,23 @@
moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
processAllMessages();
- assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
+ DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_HANDOVER_INTENT_ACTION));
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
}
@Test
public void testSatelliteProvisionStateChangedBeforeTimeout() {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
mTestSatelliteController.sendProvisionStateChangedEvent(
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false);
@@ -202,13 +314,15 @@
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 2, 2, 2);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 2, 4, 2);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 2, 4, 2);
mTestSatelliteController.sendProvisionStateChangedEvent(
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true);
@@ -217,57 +331,44 @@
moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
processAllMessages();
- assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
+ DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_HANDOVER_INTENT_ACTION));
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 2, 2);
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 4, 2);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 2, 4, 2);
}
@Test
public void testEmergencyCallRedialBeforeTimeout() {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
- Phone newPhone = Mockito.mock(Phone.class);
- when(newPhone.getServiceState()).thenReturn(mServiceState);
- when(newPhone.isImsRegistered()).thenReturn(false);
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, newPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- /**
- * Since {@link SatelliteSOSMessageRecommender} always uses
- * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} when registering for provision state
- * changed events with {@link SatelliteController}, registerForProvisionCount does
- * not depend on Phone.
- * <p>
- * Since we use a single mocked ImsManager instance, registerForImsCount does not depend on
- * Phone.
- */
- assertRegisterForStateChangedEventsTriggered(newPhone, 2, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
// Wait for the timeout to expires
moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
processAllMessages();
- assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
- /**
- * Since {@link SatelliteSOSMessageRecommender} always uses
- * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} when unregistering for provision
- * state changed events with {@link SatelliteController}, unregisterForProvisionCount does
- * not depend on Phone.
- * <p>
- * Since we use a single mocked ImsManager instance, unregisterForImsCount does not depend
- * on Phone.
- */
- assertUnregisterForStateChangedEventsTriggered(newPhone, 2, 2, 1);
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
+ DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_HANDOVER_INTENT_ACTION));
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertFalse(mTestSOSMessageRecommender.isTimerStarted());
}
@Test
@@ -296,50 +397,55 @@
@Test
public void testOnEmergencyCallConnectionStateChangedWithWrongCallId() {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
WRONG_CALL_ID, Connection.STATE_ACTIVE);
processAllMessages();
- assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
}
@Test
public void testSatelliteNotAllowedInCurrentLocation() {
mTestSatelliteController.setIsSatelliteCommunicationAllowed(false);
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
/**
- * We should have registered for the state change events abd started the timer when
+ * We should have registered for the state change events and started the timer when
* receiving the event onEmergencyCallStarted. After getting the callback for the result of
* the request requestIsSatelliteCommunicationAllowedForCurrentLocation, the resources
* should be cleaned up.
*/
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
}
@Test
public void testOnEmergencyCallStarted() {
SatelliteController satelliteController = new SatelliteController(
- mMockContext, Looper.myLooper(), mFeatureFlags);
+ mContext, Looper.myLooper(), mFeatureFlags);
TestSOSMessageRecommender testSOSMessageRecommender = new TestSOSMessageRecommender(
+ mContext,
Looper.myLooper(),
satelliteController, mTestImsManager,
TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
- testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertFalse(testSOSMessageRecommender.isTimerStarted());
@@ -348,51 +454,68 @@
private void testStopTrackingCallBeforeTimeout(
@Connection.ConnectionState int connectionState) {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(CALL_ID, connectionState);
processAllMessages();
- assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
}
private void testCellularServiceStateChangedBeforeTimeout(
@ServiceState.RegState int availableServiceState,
@ServiceState.RegState int unavailableServiceState) {
- mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, mPhone);
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
- assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
- mTestSOSMessageRecommender.sendServiceStateChangedEvent(availableServiceState);
+ when(mServiceState.getState()).thenReturn(availableServiceState);
+ mTestSOSMessageRecommender.sendServiceStateChangedEvent();
processAllMessages();
-
- assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
+ assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
assertFalse(mTestSOSMessageRecommender.isTimerStarted());
assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0, 0);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 0, 0, 0);
- mTestSOSMessageRecommender.sendServiceStateChangedEvent(unavailableServiceState);
+ when(mServiceState.getState()).thenReturn(unavailableServiceState);
+ when(mServiceState2.getState()).thenReturn(availableServiceState);
+ mTestSOSMessageRecommender.sendServiceStateChangedEvent();
+ processAllMessages();
+ assertFalse(mTestSOSMessageRecommender.isTimerStarted());
+ assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
+
+ when(mServiceState2.getState()).thenReturn(unavailableServiceState);
+ mTestSOSMessageRecommender.sendServiceStateChangedEvent();
processAllMessages();
assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertTrue(mTestSOSMessageRecommender.isTimerStarted());
// Wait for the timeout to expires
moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
processAllMessages();
- assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE));
- assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1, 1);
+ assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
+ EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
+ DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_HANDOVER_INTENT_ACTION));
+ assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 2, 1);
+ assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 2, 1);
assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
+ assertFalse(mTestSOSMessageRecommender.isTimerStarted());
}
private void assertRegisterForStateChangedEventsTriggered(
@@ -421,8 +544,9 @@
mProvisionStateChangedCallbacks;
private int mRegisterForSatelliteProvisionStateChangedCalls = 0;
private int mUnregisterForSatelliteProvisionStateChangedCalls = 0;
- private boolean mIsSatelliteProvisioned = true;
+ private boolean mIsSatelliteViaOemProvisioned = true;
private boolean mIsSatelliteCommunicationAllowed = true;
+ private boolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = true;
/**
* Create a SatelliteController to act as a backend service of
@@ -437,12 +561,12 @@
}
@Override
- public Boolean isSatelliteProvisioned() {
- return mIsSatelliteProvisioned;
+ public Boolean isSatelliteViaOemProvisioned() {
+ return mIsSatelliteViaOemProvisioned;
}
@Override
- public boolean isSatelliteSupported() {
+ public boolean isSatelliteSupportedViaOem() {
return true;
}
@@ -477,10 +601,25 @@
result.send(SatelliteManager.SATELLITE_RESULT_SUCCESS, bundle);
}
+ @Override
+ public boolean isSatelliteConnectedViaCarrierWithinHysteresisTime() {
+ return mIsSatelliteConnectedViaCarrierWithinHysteresisTime;
+ }
+
+ @Override
+ protected int getEnforcedEmergencyCallToSatelliteHandoverType() {
+ return INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
+ }
+
public void setIsSatelliteCommunicationAllowed(boolean allowed) {
mIsSatelliteCommunicationAllowed = allowed;
}
+ public void setSatelliteConnectedViaCarrierWithinHysteresisTime(
+ boolean connectedViaCarrier) {
+ mIsSatelliteConnectedViaCarrierWithinHysteresisTime = connectedViaCarrier;
+ }
+
public int getRegisterForSatelliteProvisionStateChangedCalls() {
return mRegisterForSatelliteProvisionStateChangedCalls;
}
@@ -489,8 +628,12 @@
return mUnregisterForSatelliteProvisionStateChangedCalls;
}
+ public void setIsSatelliteViaOemProvisioned(boolean provisioned) {
+ mIsSatelliteViaOemProvisioned = provisioned;
+ }
+
public void sendProvisionStateChangedEvent(int subId, boolean provisioned) {
- mIsSatelliteProvisioned = provisioned;
+ mIsSatelliteViaOemProvisioned = provisioned;
Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
mProvisionStateChangedCallbacks.get(subId);
if (perSubscriptionCallbacks != null) {
@@ -507,7 +650,7 @@
private static class TestImsManager extends ImsManager {
- private final Set<RegistrationManager.RegistrationCallback> mCallbacks;
+ private final List<RegistrationManager.RegistrationCallback> mCallbacks;
private int mAddRegistrationCallbackCalls = 0;
private int mRemoveRegistrationListenerCalls = 0;
@@ -518,7 +661,7 @@
SubscriptionManagerProxy subManagerProxy, SettingsProxy settingsProxy,
BinderCacheManager binderCacheManager) {
super(context, phoneId, factory, subManagerProxy, settingsProxy, binderCacheManager);
- mCallbacks = new HashSet<>();
+ mCallbacks = new ArrayList<>();
}
@Override
@@ -535,7 +678,9 @@
}
callback.setExecutor(executor);
- mCallbacks.add(callback);
+ if (!mCallbacks.contains(callback)) {
+ mCallbacks.add(callback);
+ }
}
@Override
@@ -556,20 +701,24 @@
return mRemoveRegistrationListenerCalls;
}
- public void sendImsRegistrationStateChangedEvent(boolean registered) {
+ public void sendImsRegistrationStateChangedEvent(int callbackIndex, boolean registered) {
+ if (callbackIndex < 0 || callbackIndex >= mCallbacks.size()) {
+ throw new IndexOutOfBoundsException("sendImsRegistrationStateChangedEvent: invalid"
+ + "callbackIndex=" + callbackIndex
+ + ", mCallbacks.size=" + mCallbacks.size());
+ }
+ RegistrationManager.RegistrationCallback callback = mCallbacks.get(callbackIndex);
if (registered) {
- for (RegistrationManager.RegistrationCallback callback : mCallbacks) {
- callback.onRegistered(null);
- }
+ callback.onRegistered(null);
} else {
- for (RegistrationManager.RegistrationCallback callback : mCallbacks) {
- callback.onUnregistered(null);
- }
+ callback.onUnregistered(null);
}
}
}
private static class TestSOSMessageRecommender extends SatelliteSOSMessageRecommender {
+ private ComponentName mSmsAppComponent = new ComponentName(
+ DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS);
/**
* Create an instance of SatelliteSOSMessageRecommender.
@@ -581,9 +730,15 @@
* null only in unit tests.
* @param timeoutMillis The timeout duration of the timer.
*/
- TestSOSMessageRecommender(Looper looper, SatelliteController satelliteController,
- ImsManager imsManager, long timeoutMillis) {
- super(looper, satelliteController, imsManager, timeoutMillis);
+ TestSOSMessageRecommender(Context context, Looper looper,
+ SatelliteController satelliteController, ImsManager imsManager,
+ long timeoutMillis) {
+ super(context, looper, satelliteController, imsManager, timeoutMillis);
+ }
+
+ @Override
+ protected ComponentName getDefaultSmsApp() {
+ return mSmsAppComponent;
}
public boolean isTimerStarted() {
@@ -594,28 +749,66 @@
return mCountOfTimerStarted;
}
- public void sendServiceStateChangedEvent(@ServiceState.RegState int state) {
- ServiceState serviceState = new ServiceState();
- serviceState.setState(state);
- sendMessage(obtainMessage(EVENT_CELLULAR_SERVICE_STATE_CHANGED,
- new AsyncResult(null, serviceState, null)));
+ public void sendServiceStateChangedEvent() {
+ sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED));
}
}
private static class TestConnection extends Connection {
- private final Set<String> mSentEvents;
+ private String mSentEvent = null;
+ private Bundle mExtras = null;
TestConnection(String callId) {
setTelecomCallId(callId);
- mSentEvents = new HashSet<>();
}
@Override
public void sendConnectionEvent(String event, Bundle extras) {
- mSentEvents.add(event);
+ mSentEvent = event;
+ mExtras = extras;
+ }
+
+ public boolean isEventSent(String event, int handoverType, String packageName,
+ String className, String action) {
+ if (mSentEvent == null || mExtras == null) {
+ return false;
+ }
+
+ PendingIntent pendingIntent = mExtras.getParcelable(
+ EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT, PendingIntent.class);
+ Intent intent = pendingIntent.getIntent();
+ if (!TextUtils.equals(event, mSentEvent) || handoverType != mExtras.getInt(
+ EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE)
+ || !TextUtils.equals(packageName, intent.getComponent().getPackageName())
+ || !TextUtils.equals(className, intent.getComponent().getClassName())
+ || !TextUtils.equals(action, intent.getAction())) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isEventWithoutLaunchIntentSent(String event, int handoverType) {
+ if (mSentEvent == null || mExtras == null) {
+ return false;
+ }
+
+ PendingIntent pendingIntent = mExtras.getParcelable(
+ EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT, PendingIntent.class);
+ if (!TextUtils.equals(event, mSentEvent) || handoverType != mExtras.getInt(
+ EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE) || pendingIntent != null) {
+ return false;
+ }
+
+ return true;
}
public boolean isEventSent(String event) {
- return mSentEvents.contains(event);
+ if (mSentEvent == null) {
+ return false;
+ }
+ if (!TextUtils.equals(event, mSentEvent)) {
+ return false;
+ }
+ return true;
}
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index 230f147..1d320a3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -42,7 +42,6 @@
import org.junit.Test;
public class UiccSlotTest extends TelephonyTest {
- private UiccSlot mUiccSlot;
private UiccSlotTestHandlerThread mTestHandlerThread;
private Handler mTestHandler;
@@ -263,7 +262,7 @@
// assert on updated values
assertTrue(mUiccSlot.isActive());
- assertEquals(mUiccSlot.getMinimumVoltageClass(), UiccSlot.VOLTAGE_CLASS_A);
+ assertEquals(UiccSlot.VOLTAGE_CLASS_A, mUiccSlot.getMinimumVoltageClass());
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
index 7e51bad..d5b6ccb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
@@ -50,7 +50,6 @@
private static final String PROVISIONING_PACKAGE_NAME = "test.provisioning.package";
// Mocked classes
- private Context mContext;
private Resources mResources;
private IccCardStatus makeCardStatus(CardState state) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
index b6dd7bd..c38be60 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
@@ -52,7 +52,6 @@
private static class ResultCaptor<T> extends AsyncResultCallback<T> {
public T result;
- public Throwable exception;
private CountDownLatch mLatch;
@@ -68,7 +67,6 @@
@Override
public void onException(Throwable e) {
- exception = e;
mLatch.countDown();
}
}