Merge "Add registering_seconds and unregistered_seconds to ImsRegistrationStats" into main
diff --git a/flags/data.aconfig b/flags/data.aconfig
index c769bcc..260d983 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -1,6 +1,13 @@
package: "com.android.internal.telephony.flags"
flag {
+ name: "unthrottle_check_transport"
+ namespace: "telephony"
+ description: "Check transport when unthrottle."
+ bug: "303922311"
+}
+
+flag {
name: "relax_ho_teardown"
namespace: "telephony"
description: "Relax handover tear down if the device is currently in voice call."
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 2b5ab2b..87acccc 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -13,4 +13,11 @@
namespace: "telephony"
description: "Whether to log MMS/SMS database access info and report anomaly when getting exception."
bug: "275225402"
+}
+
+flag {
+ name: "enable_wps_check_api_flag"
+ 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"
}
\ No newline at end of file
diff --git a/flags/network.aconfig b/flags/network.aconfig
index 0c7873e..299a2a0 100644
--- a/flags/network.aconfig
+++ b/flags/network.aconfig
@@ -6,3 +6,10 @@
description: "enabling this flag allows KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY to control N1 mode enablement"
bug:"302033535"
}
+
+flag {
+ name: "hide_roaming_icon"
+ namespace: "telephony"
+ description: "Allow carriers to hide the roaming (R) icon when roaming."
+ bug: "301467052"
+}
diff --git a/src/java/com/android/internal/telephony/DeviceStateMonitor.java b/src/java/com/android/internal/telephony/DeviceStateMonitor.java
index ecc6208..7bdf2ff 100644
--- a/src/java/com/android/internal/telephony/DeviceStateMonitor.java
+++ b/src/java/com/android/internal/telephony/DeviceStateMonitor.java
@@ -22,6 +22,7 @@
import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE;
import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
+import android.annotation.NonNull;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -47,6 +48,7 @@
import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -92,10 +94,14 @@
private static final int NR_NSA_TRACKING_INDICATIONS_ALWAYS_ON = 2;
private final Phone mPhone;
+ @NonNull
+ private final FeatureFlags mFeatureFlags;
private final LocalLog mLocalLog = new LocalLog(64);
private final RegistrantList mPhysicalChannelConfigRegistrants = new RegistrantList();
+ private final RegistrantList mSignalStrengthReportDecisionCallbackRegistrants =
+ new RegistrantList();
private final NetworkRequest mWifiNetworkRequest =
new NetworkRequest.Builder()
@@ -269,8 +275,9 @@
*
* @param phone Phone object
*/
- public DeviceStateMonitor(Phone phone) {
+ public DeviceStateMonitor(Phone phone, @NonNull FeatureFlags featureFlags) {
mPhone = phone;
+ mFeatureFlags = featureFlags;
DisplayManager dm = (DisplayManager) phone.getContext().getSystemService(
Context.DISPLAY_SERVICE);
dm.registerDisplayListener(mDisplayListener, null);
@@ -602,6 +609,15 @@
// use a null message since we don't care of receiving response
mPhone.mCi.getBarringInfo(null);
}
+
+ // Determine whether to notify registrants about the non-terrestrial signal strength change.
+ if (mFeatureFlags.oemEnabledSatelliteFlag()) {
+ if (shouldEnableSignalStrengthReports()) {
+ mSignalStrengthReportDecisionCallbackRegistrants.notifyResult(true);
+ } else {
+ mSignalStrengthReportDecisionCallbackRegistrants.notifyResult(false);
+ }
+ }
}
/**
@@ -778,6 +794,33 @@
}
/**
+ * Register a callback to decide whether signal strength should be notified or not.
+ * @param h Handler to notify
+ * @param what msg.what when the message is delivered
+ * @param obj AsyncResult.userObj when the message is delivered
+ */
+ public void registerForSignalStrengthReportDecision(Handler h, int what, Object obj) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ Rlog.d(TAG, "oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+ Registrant r = new Registrant(h, what, obj);
+ mSignalStrengthReportDecisionCallbackRegistrants.add(r);
+ }
+
+ /**
+ * Register a callback to decide whether signal strength should be notified or not.
+ * @param h Handler to notify
+ */
+ public void unregisterForSignalStrengthReportDecision(Handler h) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ Rlog.d(TAG, "oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+ mSignalStrengthReportDecisionCallbackRegistrants.remove(h);
+ }
+
+ /**
* @param msg Debug message
* @param logIntoLocalLog True if log into the local log
*/
diff --git a/src/java/com/android/internal/telephony/DisplayInfoController.java b/src/java/com/android/internal/telephony/DisplayInfoController.java
index 567331d..945b640 100644
--- a/src/java/com/android/internal/telephony/DisplayInfoController.java
+++ b/src/java/com/android/internal/telephony/DisplayInfoController.java
@@ -19,9 +19,11 @@
import android.annotation.NonNull;
import android.os.Handler;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.telephony.AnomalyReporter;
+import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
@@ -29,6 +31,7 @@
import android.util.LocalLog;
import android.util.Pair;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
@@ -66,34 +69,55 @@
/** Event for service state changed (roaming). */
private static final int EVENT_SERVICE_STATE_CHANGED = 1;
+ /** Event for carrier config changed. */
+ private static final int EVENT_CARRIER_CONFIG_CHANGED = 2;
- private final Phone mPhone;
- private final NetworkTypeController mNetworkTypeController;
- private final RegistrantList mTelephonyDisplayInfoChangedRegistrants = new RegistrantList();
- private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo;
- private @NonNull ServiceState mServiceState;
+ @NonNull private final Phone mPhone;
+ @NonNull private final NetworkTypeController mNetworkTypeController;
+ @NonNull private final RegistrantList mTelephonyDisplayInfoChangedRegistrants =
+ new RegistrantList();
+ @NonNull private final FeatureFlags mFeatureFlags;
+ @NonNull private TelephonyDisplayInfo mTelephonyDisplayInfo;
+ @NonNull private ServiceState mServiceState;
+ @NonNull private PersistableBundle mConfigs;
- public DisplayInfoController(Phone phone) {
+ public DisplayInfoController(@NonNull Phone phone, @NonNull FeatureFlags featureFlags) {
mPhone = phone;
+ mFeatureFlags = featureFlags;
mLogTag = "DIC-" + mPhone.getPhoneId();
+ mServiceState = mPhone.getServiceStateTracker().getServiceState();
+ mConfigs = new PersistableBundle();
+ try {
+ mConfigs = mPhone.getContext().getSystemService(CarrierConfigManager.class)
+ .getConfigForSubId(mPhone.getSubId(),
+ CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL);
+ } catch (Exception ignored) {
+ // CarrierConfigLoader might not be available yet.
+ // Once it's available, configs will be updated through the listener.
+ }
+ mPhone.getServiceStateTracker()
+ .registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
+ mPhone.getContext().getSystemService(CarrierConfigManager.class)
+ .registerCarrierConfigChangeListener(Runnable::run,
+ (slotIndex, subId, carrierId, specificCarrierId) -> {
+ if (slotIndex == mPhone.getPhoneId()) {
+ obtainMessage(EVENT_CARRIER_CONFIG_CHANGED).sendToTarget();
+ }
+ });
mTelephonyDisplayInfo = new TelephonyDisplayInfo(
TelephonyManager.NETWORK_TYPE_UNKNOWN,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
+ false);
mNetworkTypeController = new NetworkTypeController(phone, this);
+ // EVENT_UPDATE will transition from DefaultState to the current state
+ // and update the TelephonyDisplayInfo based on the current state.
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-
- mServiceState = mPhone.getServiceStateTracker().getServiceState();
- post(() -> {
- mPhone.getServiceStateTracker()
- .registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
- updateTelephonyDisplayInfo();
- });
}
/**
* @return the current TelephonyDisplayInfo
*/
- public @NonNull TelephonyDisplayInfo getTelephonyDisplayInfo() {
+ @NonNull public TelephonyDisplayInfo getTelephonyDisplayInfo() {
return mTelephonyDisplayInfo;
}
@@ -105,7 +129,7 @@
TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(
mNetworkTypeController.getDataNetworkType(),
mNetworkTypeController.getOverrideNetworkType(),
- mServiceState.getRoaming());
+ isRoaming());
if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
+ newDisplayInfo);
@@ -117,6 +141,24 @@
}
/**
+ * Determine the roaming status for icon display only.
+ * If this is {@code true}, the roaming indicator will be shown, and if this is {@code false},
+ * the roaming indicator will not be shown.
+ * To get the actual roaming status, use {@link ServiceState#getRoaming()} instead.
+ *
+ * @return Whether the device is considered roaming for display purposes.
+ */
+ private boolean isRoaming() {
+ boolean roaming = mServiceState.getRoaming();
+ if (roaming && mFeatureFlags.hideRoamingIcon()
+ && !mConfigs.getBoolean(CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL)) {
+ logl("Override roaming for display due to carrier configs.");
+ roaming = false;
+ }
+ return roaming;
+ }
+
+ /**
* Validate the display info and trigger anomaly report if needed.
*
* @param displayInfo The display info to validate.
@@ -175,6 +217,13 @@
log("ServiceState updated, isRoaming=" + mServiceState.getRoaming());
updateTelephonyDisplayInfo();
break;
+ case EVENT_CARRIER_CONFIG_CHANGED:
+ mConfigs = mPhone.getContext().getSystemService(CarrierConfigManager.class)
+ .getConfigForSubId(mPhone.getSubId(),
+ CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL);
+ log("Carrier configs updated: " + mConfigs);
+ updateTelephonyDisplayInfo();
+ break;
}
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 05bfe36..6f30fb5 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -359,12 +359,13 @@
.inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker(
this, this.mCi);
mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName())
- .makeDeviceStateMonitor(this);
+ .makeDeviceStateMonitor(this, mFeatureFlags);
// DisplayInfoController creates an OverrideNetworkTypeController, which uses
// DeviceStateMonitor so needs to be crated after it is instantiated.
mDisplayInfoController = mTelephonyComponentFactory.inject(
- DisplayInfoController.class.getName()).makeDisplayInfoController(this);
+ DisplayInfoController.class.getName())
+ .makeDisplayInfoController(this, featureFlags);
mDataNetworkController = mTelephonyComponentFactory.inject(
DataNetworkController.class.getName())
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 6b5b266..50cf844 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -727,6 +727,28 @@
}
/**
+ * Determines if the carrier prefers to use an in service sim for a normal routed emergency
+ * call.
+ * @return true when carrier config
+ * {@link CarrierConfigManager#KEY_PREFER_IN_SERVICE_SIM_FOR_NORMAL_ROUTED_EMERGENCY_CALLS_BOOL}
+ * is true.
+ */
+ public boolean shouldPreferInServiceSimForNormalRoutedEmergencyCall() {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ PersistableBundle b = configManager.getConfigForSubId(getSubId(), CarrierConfigManager
+ .KEY_PREFER_IN_SERVICE_SIM_FOR_NORMAL_ROUTED_EMERGENCY_CALLS_BOOL);
+ if (b != null) {
+ return b.getBoolean(CarrierConfigManager
+ .KEY_PREFER_IN_SERVICE_SIM_FOR_NORMAL_ROUTED_EMERGENCY_CALLS_BOOL,
+ false);
+ } else {
+ // Default value set in CarrierConfigManager
+ return false;
+ }
+ }
+
+ /**
* When overridden the derived class needs to call
* super.handleMessage(msg) so this method has a
* a chance to process the message.
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index 2816e2b..c2c29f8 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -983,8 +983,11 @@
dpi.persistent = dp.isPersistent();
dpi.preferred = dp.isPreferred();
dpi.alwaysOn = false;
+ dpi.infrastructureBitmap = android.hardware.radio.data.DataProfileInfo
+ .INFRASTRUCTURE_CELLULAR;
if (dp.getApnSetting() != null) {
dpi.alwaysOn = dp.getApnSetting().isAlwaysOn();
+ dpi.infrastructureBitmap = dp.getApnSetting().getInfrastructureBitmask();
}
dpi.trafficDescriptor = convertToHalTrafficDescriptorAidl(dp.getTrafficDescriptor());
@@ -1022,6 +1025,7 @@
.setRoamingProtocol(dpi.roamingProtocol)
.setUser(dpi.user)
.setAlwaysOn(dpi.alwaysOn)
+ .setInfrastructureBitmask(dpi.infrastructureBitmap)
.build();
TrafficDescriptor td;
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index b756675..8b832dd 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -406,8 +406,12 @@
return new AppSmsManager(context);
}
- public DeviceStateMonitor makeDeviceStateMonitor(Phone phone) {
- return new DeviceStateMonitor(phone);
+ /**
+ * Create a DeviceStateMonitor.
+ */
+ public DeviceStateMonitor makeDeviceStateMonitor(Phone phone,
+ @NonNull FeatureFlags featureFlags) {
+ return new DeviceStateMonitor(phone, featureFlags);
}
/**
@@ -448,8 +452,8 @@
/**
* Create a new DisplayInfoController.
*/
- public DisplayInfoController makeDisplayInfoController(Phone phone) {
- return new DisplayInfoController(phone);
+ public DisplayInfoController makeDisplayInfoController(Phone phone, FeatureFlags featureFlags) {
+ return new DisplayInfoController(phone, featureFlags);
}
/**
@@ -498,15 +502,17 @@
* @param dataServiceManager Data service manager instance.
* @param looper The looper to be used by the handler. Currently the handler thread is the phone
* process's main thread.
+ * @param featureFlags Feature flags controlling which feature is enabled. *
* @param callback Callback for passing events back to data network controller.
* @return The data profile manager instance.
*/
public @NonNull DataProfileManager makeDataProfileManager(@NonNull Phone phone,
@NonNull DataNetworkController dataNetworkController,
@NonNull DataServiceManager dataServiceManager, @NonNull Looper looper,
+ @NonNull FeatureFlags featureFlags,
@NonNull DataProfileManager.DataProfileManagerCallback callback) {
return new DataProfileManager(phone, dataNetworkController, dataServiceManager, looper,
- callback);
+ featureFlags, callback);
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 6b410ce..f3bb6c1 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -3308,7 +3308,8 @@
&& !mAttachedNetworkRequestList.isEmpty()) {
TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
- .getDataProfileForNetworkRequest(networkRequest, targetNetworkType, false);
+ .getDataProfileForNetworkRequest(networkRequest, targetNetworkType,
+ mPhone.getServiceState().isUsingNonTerrestrialNetwork(), 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 3073f49..5bdef27 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -879,6 +879,7 @@
DataProfileManager.class.getName())
.makeDataProfileManager(mPhone, this, mDataServiceManagers
.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), looper,
+ mFeatureFlags,
new DataProfileManagerCallback(this::post) {
@Override
public void onDataProfilesChanged() {
@@ -899,7 +900,7 @@
}
});
mDataRetryManager = new DataRetryManager(mPhone, this,
- mDataServiceManagers, looper,
+ mDataServiceManagers, looper, mFeatureFlags,
new DataRetryManagerCallback(this::post) {
@Override
public void onDataNetworkSetupRetry(
@@ -1328,6 +1329,7 @@
DataProfile candidate = mDataProfileManager
.getDataProfileForNetworkRequest(requestList.getFirst(),
TelephonyManager.NETWORK_TYPE_IWLAN,
+ mServiceState.isUsingNonTerrestrialNetwork(),
false/*ignorePermanentFailure*/);
if (candidate != null && !dataNetwork.getDataProfile().equals(candidate)) {
logv("But skipped because found better data profile " + candidate
@@ -1491,7 +1493,8 @@
if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
evaluation.setCandidateDataProfile(mDataProfileManager.getDataProfileForNetworkRequest(
- networkRequest, getDataNetworkType(transport), true));
+ networkRequest, getDataNetworkType(transport),
+ mServiceState.isUsingNonTerrestrialNetwork(), true));
networkRequest.setEvaluation(evaluation);
log(evaluation.toString());
return evaluation;
@@ -1647,6 +1650,7 @@
}
DataProfile dataProfile = mDataProfileManager
.getDataProfileForNetworkRequest(networkRequest, networkType,
+ mServiceState.isUsingNonTerrestrialNetwork(),
// If the evaluation is due to environmental changes, then we should ignore
// the permanent failure reached earlier.
reason.isConditionBased());
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index 23029e3..273dc8b 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -48,6 +48,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
@@ -113,6 +114,9 @@
/** SIM state. */
private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
+ /** Feature flags controlling which feature is enabled. */
+ private final @NonNull FeatureFlags mFeatureFlags;
+
/**
* Data profile manager callback. This should be only used by {@link DataNetworkController}.
*/
@@ -140,15 +144,18 @@
* @param dataServiceManager WWAN data service manager.
* @param looper The looper to be used by the handler. Currently the handler thread is the
* phone process's main thread.
+ * @param featureFlags Feature flags controlling which feature is enabled.
* @param callback Data profile manager callback.
*/
public DataProfileManager(@NonNull Phone phone,
@NonNull DataNetworkController dataNetworkController,
@NonNull DataServiceManager dataServiceManager, @NonNull Looper looper,
+ @NonNull FeatureFlags featureFlags,
@NonNull DataProfileManagerCallback callback) {
super(looper);
mPhone = phone;
mLogTag = "DPM-" + mPhone.getPhoneId();
+ mFeatureFlags = featureFlags;
mDataNetworkController = dataNetworkController;
mWwanDataServiceManager = dataServiceManager;
mDataConfigManager = dataNetworkController.getDataConfigManager();
@@ -626,17 +633,18 @@
*
* @param networkRequest The network request.
* @param networkType The current data network type.
+ * @param isNtn {@code true} if the device is currently attached to non-terrestrial network.
* @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}.
* This should be set to true for condition-based retry/setup.
* @return The data profile. {@code null} if can't find any satisfiable data profile.
*/
public @Nullable DataProfile getDataProfileForNetworkRequest(
@NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
- boolean ignorePermanentFailure) {
+ boolean isNtn, boolean ignorePermanentFailure) {
ApnSetting apnSetting = null;
if (networkRequest.hasAttribute(TelephonyNetworkRequest
.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
- apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType,
+ apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType, isNtn,
ignorePermanentFailure);
}
@@ -696,32 +704,56 @@
*
* @param networkRequest The network request.
* @param networkType The current data network type.
+ * @param isNtn {@code true} if the device is currently attached to non-terrestrial network.
* @param ignorePermanentFailure {@code true} to ignore {@link ApnSetting#getPermanentFailed()}.
* This should be set to true for condition-based retry/setup.
* @return The APN setting. {@code null} if can't find any satisfiable data profile.
*/
private @Nullable ApnSetting getApnSettingForNetworkRequest(
@NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType,
- boolean ignorePermanentFailure) {
+ boolean isNtn, boolean ignorePermanentFailure) {
if (!networkRequest.hasAttribute(
TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
loge("Network request does not have APN setting attribute.");
return null;
}
- // 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();
+ 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();
+ }
+ log("The preferred data profile is permanently failed. Only condition based "
+ + "retry can happen.");
+ return null;
+ }
}
// Filter out the data profile that can't satisfy the request.
@@ -743,8 +775,22 @@
// Check if the remaining data profiles can used in current data network type.
dataProfiles = dataProfiles.stream()
- .filter(dp -> dp.getApnSetting() != null
- && dp.getApnSetting().canSupportNetworkType(networkType))
+ .filter((dp) -> {
+ if (dp.getApnSetting() == null) return false;
+ if (!dp.getApnSetting().canSupportNetworkType(networkType)) return false;
+ if (mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ if (isNtn && !dp.getApnSetting().isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_SATELLITE)) {
+ return false;
+ }
+ if (!isNtn && !dp.getApnSetting().isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_CELLULAR)) {
+ return false;
+ }
+ }
+
+ return true;
+ })
.collect(Collectors.toList());
if (dataProfiles.size() == 0) {
log("Can't find any data profile for network type "
@@ -818,7 +864,8 @@
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
.build(), mPhone);
- return getDataProfileForNetworkRequest(networkRequest, networkType, true) != null;
+ return getDataProfileForNetworkRequest(networkRequest, networkType,
+ mPhone.getServiceState().isUsingNonTerrestrialNetwork(), true) != null;
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 4465fbb..754400e 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -51,6 +51,7 @@
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
@@ -141,6 +142,9 @@
/** The phone instance. */
private final @NonNull Phone mPhone;
+ /** Featureflags. */
+ private final @NonNull FeatureFlags mFlags;
+
/** The RIL instance. */
private final @NonNull CommandsInterface mRil;
@@ -952,10 +956,12 @@
public DataRetryManager(@NonNull Phone phone,
@NonNull DataNetworkController dataNetworkController,
@NonNull SparseArray<DataServiceManager> dataServiceManagers,
- @NonNull Looper looper, @NonNull DataRetryManagerCallback dataRetryManagerCallback) {
+ @NonNull Looper looper, @NonNull FeatureFlags flags,
+ @NonNull DataRetryManagerCallback dataRetryManagerCallback) {
super(looper);
mPhone = phone;
mRil = phone.mCi;
+ mFlags = flags;
mLogTag = "DRM-" + mPhone.getPhoneId();
mDataRetryManagerCallbacks.add(dataRetryManagerCallback);
@@ -1480,9 +1486,12 @@
DataThrottlingEntry entry = new DataThrottlingEntry(dataProfile, networkRequestList,
dataNetwork, transport, retryType, expirationTime);
// Remove previous entry that contains the same data profile. Therefore it should always
- // contain at maximum all the distinct data profiles of the current subscription.
+ // contain at maximu all the distinct data profiles of the current subscription times each
+ // transport.
mDataThrottlingEntries.removeIf(
- throttlingEntry -> dataProfile.equals(throttlingEntry.dataProfile));
+ throttlingEntry -> dataProfile.equals(throttlingEntry.dataProfile)
+ && (!mFlags.unthrottleCheckTransport()
+ || throttlingEntry.transport == transport));
if (mDataThrottlingEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
// If we don't see the anomaly report after U release, we should remove this check for
@@ -1544,7 +1553,8 @@
// in DataProfileInfo.aidl), so we need to get the equivalent data profile from data
// profile manager.
Stream<DataThrottlingEntry> stream = mDataThrottlingEntries.stream();
- stream = stream.filter(entry -> entry.expirationTimeMillis > now);
+ stream = stream.filter(entry -> entry.expirationTimeMillis > now
+ && (!mFlags.unthrottleCheckTransport() || entry.transport == transport));
if (dataProfile.getApnSetting() != null) {
stream = stream
.filter(entry -> entry.dataProfile.getApnSetting() != null)
diff --git a/src/java/com/android/internal/telephony/data/DataUtils.java b/src/java/com/android/internal/telephony/data/DataUtils.java
index fc0c4f1..259b482 100644
--- a/src/java/com/android/internal/telephony/data/DataUtils.java
+++ b/src/java/com/android/internal/telephony/data/DataUtils.java
@@ -90,6 +90,8 @@
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
case "PRIORITIZE_LATENCY":
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
+ case "RCS":
+ return NetworkCapabilities.NET_CAPABILITY_RCS;
default:
return -1;
}
@@ -254,6 +256,8 @@
return ApnSetting.TYPE_VSIM;
case NetworkCapabilities.NET_CAPABILITY_BIP:
return ApnSetting.TYPE_BIP;
+ case NetworkCapabilities.NET_CAPABILITY_RCS:
+ return ApnSetting.TYPE_RCS;
default:
return ApnSetting.TYPE_NONE;
}
@@ -295,6 +299,8 @@
return NetworkCapabilities.NET_CAPABILITY_VSIM;
case ApnSetting.TYPE_ENTERPRISE:
return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
+ case ApnSetting.TYPE_RCS:
+ return NetworkCapabilities.NET_CAPABILITY_RCS;
default:
return -1;
}
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index ab759e9..36e6587 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -1546,7 +1546,7 @@
// If validation feature is not supported, set it directly. Otherwise,
// start validation on the subscription first.
if (!mValidator.isValidationFeatureSupported()) {
- setAutoSelectedDataSubIdInternal(subIdToValidate);
+ setAutoSelectedDataSubIdInternal(subId);
sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
return;
}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
index b334b89..2668302 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
@@ -130,7 +130,9 @@
new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY,
CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID),
new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH,
- CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)
+ CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID),
+ new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_RCS,
+ CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN)
);
/** The phone instance. */
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
index 9a75b43..5ef8b8a 100644
--- a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
+++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
@@ -21,7 +21,6 @@
import android.os.AsyncResult;
import android.os.CancellationSignal;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
@@ -44,8 +43,6 @@
import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
import java.util.function.Consumer;
@@ -74,42 +71,63 @@
private final class TransportSelectorCallbackWrapper implements TransportSelectorCallback {
@Override
public void onCreated(@NonNull DomainSelector selector) {
- mDomainSelector = selector;
- DomainSelectionConnection.this.onCreated();
+ synchronized (mLock) {
+ mDomainSelector = selector;
+ if (mDisposed) {
+ mDomainSelector.cancelSelection();
+ return;
+ }
+ DomainSelectionConnection.this.onCreated();
+ }
}
@Override
public void onWlanSelected(boolean useEmergencyPdn) {
- DomainSelectionConnection.this.onWlanSelected(useEmergencyPdn);
+ synchronized (mLock) {
+ if (mDisposed) return;
+ DomainSelectionConnection.this.onWlanSelected(useEmergencyPdn);
+ }
}
@Override
public @NonNull WwanSelectorCallback onWwanSelected() {
- if (mWwanSelectorCallback == null) {
- mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+ synchronized (mLock) {
+ if (mWwanSelectorCallback == null) {
+ mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+ }
+ if (mDisposed) {
+ return mWwanSelectorCallback;
+ }
+ DomainSelectionConnection.this.onWwanSelected();
+ return mWwanSelectorCallback;
}
- DomainSelectionConnection.this.onWwanSelected();
- return mWwanSelectorCallback;
}
@Override
public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
- if (mWwanSelectorCallback == null) {
- mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+ synchronized (mLock) {
+ if (mDisposed) return;
+ if (mWwanSelectorCallback == null) {
+ mWwanSelectorCallback = new WwanSelectorCallbackWrapper();
+ }
+ initHandler();
+ mHandler.post(() -> {
+ synchronized (mLock) {
+ if (mDisposed) return;
+ DomainSelectionConnection.this.onWwanSelected();
+ consumer.accept(mWwanSelectorCallback);
+ }
+ });
}
- if (mWwanSelectedExecutor == null) {
- mWwanSelectedExecutor = Executors.newSingleThreadExecutor();
- }
- mWwanSelectedExecutor.execute(() -> {
- DomainSelectionConnection.this.onWwanSelected();
- consumer.accept(mWwanSelectorCallback);
- });
}
@Override
public void onSelectionTerminated(int cause) {
- DomainSelectionConnection.this.onSelectionTerminated(cause);
- dispose();
+ synchronized (mLock) {
+ if (mDisposed) return;
+ DomainSelectionConnection.this.onSelectionTerminated(cause);
+ dispose();
+ }
}
}
@@ -120,22 +138,38 @@
public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
@EmergencyScanType int scanType, @NonNull CancellationSignal signal,
@NonNull Consumer<EmergencyRegResult> consumer) {
- if (signal != null) signal.setOnCancelListener(this);
- mResultCallback = consumer;
- initHandler();
- DomainSelectionConnection.this.onRequestEmergencyNetworkScan(
- preferredNetworks.stream().mapToInt(Integer::intValue).toArray(), scanType);
+ synchronized (mLock) {
+ if (mDisposed) return;
+ if (signal != null) signal.setOnCancelListener(this);
+ mResultCallback = consumer;
+ initHandler();
+ mHandler.post(() -> {
+ synchronized (mLock) {
+ DomainSelectionConnection.this.onRequestEmergencyNetworkScan(
+ preferredNetworks.stream().mapToInt(Integer::intValue).toArray(),
+ scanType);
+ }
+ });
+ }
}
@Override
public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain,
boolean useEmergencyPdn) {
- DomainSelectionConnection.this.onDomainSelected(domain, useEmergencyPdn);
+ synchronized (mLock) {
+ if (mDisposed) return;
+ DomainSelectionConnection.this.onDomainSelected(domain, useEmergencyPdn);
+ }
}
@Override
public void onCancel() {
- DomainSelectionConnection.this.onCancel();
+ synchronized (mLock) {
+ if (mDisposed || mHandler == null) return;
+ mHandler.post(() -> {
+ DomainSelectionConnection.this.onCancel();
+ });
+ }
}
}
@@ -156,7 +190,7 @@
if (DBG) logd("EVENT_EMERGENCY_NETWORK_SCAN_RESULT result=" + regResult);
CompletableFuture.runAsync(
() -> mResultCallback.accept(regResult),
- mController.getDomainSelectionServiceExecutor()).join();
+ mController.getDomainSelectionServiceExecutor());
break;
case EVENT_QUALIFIED_NETWORKS_CHANGED:
onQualifiedNetworksChanged();
@@ -170,6 +204,8 @@
protected String mTag = "DomainSelectionConnection";
+ private boolean mDisposed = false;
+ private final Object mLock = new Object();
private final LocalLog mLocalLog = new LocalLog(30);
private final @NonNull TransportSelectorCallback mTransportSelectorCallback;
@@ -196,15 +232,13 @@
/** The attributes required to determine the domain. */
private @Nullable DomainSelectionService.SelectionAttributes mSelectionAttributes;
- private @Nullable Looper mLooper;
+ private final @NonNull Looper mLooper;
protected @Nullable DomainSelectionConnectionHandler mHandler;
private boolean mRegisteredRegistrant;
private boolean mIsWaitingForScanResult;
private @NonNull AndroidFuture<Integer> mOnComplete;
- private @Nullable Executor mWwanSelectedExecutor;
-
/**
* Creates an instance.
*
@@ -220,6 +254,7 @@
mPhone = phone;
mSelectorType = selectorType;
mIsEmergency = isEmergency;
+ mLooper = Looper.getMainLooper();
mTransportSelectorCallback = new TransportSelectorCallbackWrapper();
mOnComplete = new AndroidFuture<>();
@@ -323,6 +358,8 @@
public void onRequestEmergencyNetworkScan(
@NonNull @RadioAccessNetworkType int[] preferredNetworks,
@EmergencyScanType int scanType) {
+ if (mHandler == null) return;
+
// Can be overridden if required
if (!mRegisteredRegistrant) {
mPhone.registerForEmergencyNetworkScan(mHandler,
@@ -376,9 +413,12 @@
* to clean up all ongoing operations with the framework.
*/
public void cancelSelection() {
- if (mDomainSelector == null) return;
- mDomainSelector.cancelSelection();
- dispose();
+ synchronized (mLock) {
+ if (mDomainSelector != null) {
+ mDomainSelector.cancelSelection();
+ }
+ dispose();
+ }
}
/**
@@ -400,9 +440,12 @@
* Finishes the selection procedure and cleans everything up.
*/
public void finishSelection() {
- if (mDomainSelector == null) return;
- mDomainSelector.finishSelection();
- dispose();
+ synchronized (mLock) {
+ if (mDomainSelector != null) {
+ mDomainSelector.finishSelection();
+ }
+ dispose();
+ }
}
/** Indicates that the service connection has been removed. */
@@ -412,23 +455,18 @@
}
private void dispose() {
+ mDisposed = true;
if (mRegisteredRegistrant) {
mPhone.unregisterForEmergencyNetworkScan(mHandler);
mRegisteredRegistrant = false;
}
onCancel(true);
mController.removeConnection(this);
- if (mLooper != null) mLooper.quitSafely();
- mLooper = null;
+ if (mHandler != null) mHandler.removeCallbacksAndMessages(null);
mHandler = null;
}
protected void initHandler() {
- if (mLooper == null) {
- HandlerThread handlerThread = new HandlerThread(mTag);
- handlerThread.start();
- mLooper = handlerThread.getLooper();
- }
if (mHandler == null) mHandler = new DomainSelectionConnectionHandler(mLooper);
}
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index 9b44001..e2418c5 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -935,6 +935,23 @@
}
/**
+ * Get a list of the {@link EmergencyNumber}s that have the corresponding emergency number.
+ * Note: {@link #getEmergencyNumber(String)} assumes there is ONLY one record for a phone number
+ * when in reality there CAN be multiple instances if the same number is reported by the radio
+ * for a specific mcc and the emergency number database specifies the number without an mcc
+ * specified.
+ *
+ * @param emergencyNumber the emergency number to find.
+ * @return the list of emergency numbers matching.
+ */
+ public List<EmergencyNumber> getEmergencyNumbers(String emergencyNumber) {
+ final String toFind = PhoneNumberUtils.stripSeparators(emergencyNumber);
+ return getEmergencyNumberList().stream()
+ .filter(num -> num.getNumber().equals(toFind))
+ .toList();
+ }
+
+ /**
* Get the emergency service categories for the corresponding emergency number. The only
* trusted sources for the categories are the
* {@link EmergencyNumber#EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING} and
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 3099eb8..896063f 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -18,6 +18,8 @@
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.KEY_NTN_SIGNAL_STRENGTH;
import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
@@ -55,10 +57,12 @@
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
@@ -70,6 +74,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.DeviceStateMonitor;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.flags.FeatureFlags;
@@ -138,6 +143,11 @@
private static final int EVENT_SET_SATELLITE_PLMN_INFO_DONE = 29;
private static final int CMD_EVALUATE_SATELLITE_ATTACH_RESTRICTION_CHANGE = 30;
private static final int EVENT_EVALUATE_SATELLITE_ATTACH_RESTRICTION_CHANGE_DONE = 31;
+ 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;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -150,6 +160,7 @@
@NonNull private final SubscriptionManagerService mSubscriptionManagerService;
private final CommandsInterface mCi;
private ContentResolver mContentResolver = null;
+ private final DeviceStateMonitor mDSM;
private final Object mRadioStateLock = new Object();
@@ -187,6 +198,7 @@
new AtomicBoolean(false);
private final AtomicBoolean mRegisteredForSatelliteModemStateChangedWithSatelliteService =
new AtomicBoolean(false);
+ private final AtomicBoolean mRegisteredForNtnSignalStrengthChanged = new AtomicBoolean(false);
/**
* Map key: subId, value: callback to get error code of the provision request.
*/
@@ -198,6 +210,12 @@
*/
private final ConcurrentHashMap<IBinder, ISatelliteProvisionStateCallback>
mSatelliteProvisionStateChangedListeners = new ConcurrentHashMap<>();
+ /**
+ * Map key: binder of the callback, value: callback to receive non-terrestrial signal strength
+ * state changed events.
+ */
+ private final ConcurrentHashMap<IBinder, INtnSignalStrengthCallback>
+ mNtnSignalStrengthChangedListeners = new ConcurrentHashMap<>();
private final Object mIsSatelliteSupportedLock = new Object();
@GuardedBy("mIsSatelliteSupportedLock")
private Boolean mIsSatelliteSupported = null;
@@ -215,6 +233,10 @@
private final Object mNeedsSatellitePointingLock = new Object();
@GuardedBy("mNeedsSatellitePointingLock")
private boolean mNeedsSatellitePointing = false;
+ private final Object mNtnSignalsStrengthLock = new Object();
+ @GuardedBy("mNtnSignalsStrengthLock")
+ private NtnSignalStrength mNtnSignalStrength =
+ new NtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE);
/** Key: subId, value: (key: PLMN, value: set of
* {@link android.telephony.NetworkRegistrationInfo.ServiceType})
*/
@@ -279,6 +301,7 @@
mFeatureFlags = featureFlags;
Phone phone = SatelliteServiceUtils.getPhone();
mCi = phone.mCi;
+ mDSM = phone.getDeviceStateMonitor();
// Create the SatelliteModemInterface singleton, which is used to manage connections
// to the satellite service and HAL interface.
mSatelliteModemInterface = SatelliteModemInterface.make(mContext, this);
@@ -333,6 +356,8 @@
handleCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId);
mCarrierConfigManager.registerCarrierConfigChangeListener(
new HandlerExecutor(new Handler(looper)), mCarrierConfigChangeListener);
+ mDSM.registerForSignalStrengthReportDecision(this, CMD_START_SENDING_NTN_SIGNAL_STRENGTH,
+ null);
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -1054,6 +1079,91 @@
break;
}
+ case CMD_REQUEST_NTN_SIGNAL_STRENGTH: {
+ logd("CMD_REQUEST_NTN_SIGNAL_STRENGTH");
+ request = (SatelliteControllerHandlerRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_REQUEST_NTN_SIGNAL_STRENGTH_DONE, request);
+ mSatelliteModemInterface.requestNtnSignalStrength(onCompleted);
+ break;
+ }
+
+ case EVENT_REQUEST_NTN_SIGNAL_STRENGTH_DONE: {
+ ar = (AsyncResult) msg.obj;
+ request = (SatelliteControllerHandlerRequest) ar.userObj;
+ ResultReceiver result = (ResultReceiver) request.argument;
+ int errorCode = SatelliteServiceUtils.getSatelliteError(ar,
+ "requestNtnSignalStrength");
+ if (errorCode == SATELLITE_RESULT_SUCCESS) {
+ NtnSignalStrength ntnSignalStrength = (NtnSignalStrength) ar.result;
+ if (ntnSignalStrength != null) {
+ synchronized (mNtnSignalsStrengthLock) {
+ mNtnSignalStrength = ntnSignalStrength;
+ }
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(KEY_NTN_SIGNAL_STRENGTH, ntnSignalStrength);
+ result.send(SATELLITE_RESULT_SUCCESS, bundle);
+ } else {
+ synchronized (mNtnSignalsStrengthLock) {
+ if (mNtnSignalStrength.getLevel() != NTN_SIGNAL_STRENGTH_NONE) {
+ mNtnSignalStrength = new NtnSignalStrength(
+ NTN_SIGNAL_STRENGTH_NONE);
+ }
+ }
+ loge("EVENT_REQUEST_NTN_SIGNAL_STRENGTH_DONE: ntnSignalStrength is null");
+ result.send(SatelliteManager.SATELLITE_RESULT_REQUEST_FAILED, null);
+ }
+ } else {
+ synchronized (mNtnSignalsStrengthLock) {
+ if (mNtnSignalStrength.getLevel() != NTN_SIGNAL_STRENGTH_NONE) {
+ mNtnSignalStrength = new NtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE);
+ }
+ }
+ result.send(errorCode, null);
+ }
+ break;
+ }
+
+ case EVENT_NTN_SIGNAL_STRENGTH_CHANGED: {
+ ar = (AsyncResult) msg.obj;
+ if (ar.result == null) {
+ loge("EVENT_NTN_SIGNAL_STRENGTH_CHANGED: result is null");
+ } else {
+ handleEventNtnSignalStrengthChanged((NtnSignalStrength) ar.result);
+ }
+ break;
+ }
+
+ case CMD_START_SENDING_NTN_SIGNAL_STRENGTH: {
+ ar = (AsyncResult) msg.obj;
+ boolean shouldReport = (boolean) ar.result;
+ logd("CMD_START_SENDING_NTN_SIGNAL_STRENGTH: shouldReport=" + shouldReport);
+ request = new SatelliteControllerHandlerRequest(shouldReport,
+ SatelliteServiceUtils.getPhone());
+ if (SATELLITE_RESULT_SUCCESS != evaluateOemSatelliteRequestAllowed(true)) {
+ return;
+ }
+ onCompleted = obtainMessage(EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING,
+ request);
+ if (shouldReport) {
+ mSatelliteModemInterface.startSendingNtnSignalStrength(onCompleted);
+ } else {
+ mSatelliteModemInterface.stopSendingNtnSignalStrength(onCompleted);
+ }
+ break;
+ }
+
+ case EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING: {
+ ar = (AsyncResult) msg.obj;
+ request = (SatelliteControllerHandlerRequest) ar.userObj;
+ int errorCode = SatelliteServiceUtils.getSatelliteError(ar,
+ "EVENT_UPDATE_SIGNAL_STRENGTH_REPORTING");
+ if (errorCode != SATELLITE_RESULT_SUCCESS) {
+ loge(((boolean) request.argument ? "startSendingNtnSignalStrength"
+ : "stopSendingNtnSignalStrength") + "returns " + errorCode);
+ }
+ break;
+ }
+
default:
Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
msg.what);
@@ -1686,6 +1796,8 @@
Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
result.accept(SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+ logd("addSatelliteAttachRestrictionForCarrier: carrierEnabledSatelliteFlag is "
+ + "disabled");
return;
}
@@ -1723,6 +1835,8 @@
Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
result.accept(SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+ logd("removeSatelliteAttachRestrictionForCarrier: carrierEnabledSatelliteFlag is "
+ + "disabled");
return;
}
@@ -1765,6 +1879,75 @@
}
/**
+ * Request to get the signal strength of the satellite connection.
+ *
+ * @param subId The subId of the subscription to request for.
+ * @param result Result receiver to get the error code of the request and the current signal
+ * strength of the satellite connection.
+ */
+ public void requestNtnSignalStrength(int subId, @NonNull ResultReceiver result) {
+ if (DBG) logd("requestNtnSignalStrength()");
+
+ int error = evaluateOemSatelliteRequestAllowed(true);
+ if (error != SATELLITE_RESULT_SUCCESS) {
+ result.send(error, null);
+ return;
+ }
+
+ /* In case cache is available, it is not needed to request non-terrestrial signal strength
+ to modem */
+ synchronized (mNtnSignalsStrengthLock) {
+ if (mNtnSignalStrength.getLevel() != NTN_SIGNAL_STRENGTH_NONE) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(KEY_NTN_SIGNAL_STRENGTH, mNtnSignalStrength);
+ result.send(SATELLITE_RESULT_SUCCESS, bundle);
+ return;
+ }
+ }
+
+ Phone phone = SatelliteServiceUtils.getPhone();
+ sendRequestAsync(CMD_REQUEST_NTN_SIGNAL_STRENGTH, result, phone);
+ }
+
+ /**
+ * Registers for NTN signal strength changed from satellite modem.
+ *
+ * @param subId The subId of the subscription to request for.
+ * @param callback The callback to handle the non-terrestrial network signal strength changed
+ * event.
+ *
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ */
+ @SatelliteManager.SatelliteResult public int registerForNtnSignalStrengthChanged(
+ int subId, @NonNull INtnSignalStrengthCallback callback) {
+ if (DBG) logd("registerForNtnSignalStrengthChanged()");
+
+ int error = evaluateOemSatelliteRequestAllowed(true);
+ if (error != SATELLITE_RESULT_SUCCESS) return error;
+
+ mNtnSignalStrengthChangedListeners.put(callback.asBinder(), callback);
+ return SATELLITE_RESULT_SUCCESS;
+ }
+
+ /**
+ * Unregisters for NTN signal strength changed from satellite modem.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for provision state changed.
+ * @param callback The callback that was passed to
+ * {@link #registerForNtnSignalStrengthChanged(int, INtnSignalStrengthCallback)}
+ */
+ public void unregisterForNtnSignalStrengthChanged(
+ int subId, @NonNull INtnSignalStrengthCallback callback) {
+ if (DBG) logd("unregisterForNtnSignalStrengthChanged()");
+
+ int error = evaluateOemSatelliteRequestAllowed(true);
+ if (error == SATELLITE_RESULT_SUCCESS) {
+ mNtnSignalStrengthChangedListeners.remove(callback.asBinder());
+ }
+ }
+
+ /**
* This API can be used by only CTS to update satellite vendor service package name.
*
* @param servicePackageName The package name of the satellite vendor service.
@@ -1907,6 +2090,7 @@
*/
public void onCellularRadioPowerOffRequested() {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("onCellularRadioPowerOffRequested: oemEnabledSatelliteFlag is disabled");
return;
}
@@ -1987,6 +2171,7 @@
*/
public boolean isSatelliteAttachRequired() {
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("isSatelliteAttachRequired: oemEnabledSatelliteFlag is disabled");
return false;
}
@@ -2195,6 +2380,7 @@
registerForSatelliteProvisionStateChanged();
registerForPendingDatagramCount();
registerForSatelliteModemStateChanged();
+ registerForNtnSignalStrengthChanged();
requestIsSatelliteProvisioned(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
new ResultReceiver(this) {
@@ -2263,6 +2449,21 @@
}
}
+ private void registerForNtnSignalStrengthChanged() {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("registerForNtnSignalStrengthChanged: oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+
+ if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
+ if (!mRegisteredForNtnSignalStrengthChanged.get()) {
+ mSatelliteModemInterface.registerForNtnSignalStrengthChanged(
+ this, EVENT_NTN_SIGNAL_STRENGTH_CHANGED, null);
+ mRegisteredForNtnSignalStrengthChanged.set(true);
+ }
+ }
+ }
+
private void handleEventSatelliteProvisionStateChanged(boolean provisioned) {
logd("handleSatelliteProvisionStateChangedEvent: provisioned=" + provisioned);
@@ -2270,16 +2471,16 @@
mIsSatelliteProvisioned = provisioned;
}
- List<ISatelliteProvisionStateCallback> toBeRemoved = new ArrayList<>();
+ List<ISatelliteProvisionStateCallback> deadCallersList = new ArrayList<>();
mSatelliteProvisionStateChangedListeners.values().forEach(listener -> {
try {
listener.onSatelliteProvisionStateChanged(provisioned);
} catch (RemoteException e) {
logd("handleSatelliteProvisionStateChangedEvent RemoteException: " + e);
- toBeRemoved.add(listener);
+ deadCallersList.add(listener);
}
});
- toBeRemoved.forEach(listener -> {
+ deadCallersList.forEach(listener -> {
mSatelliteProvisionStateChangedListeners.remove(listener.asBinder());
});
}
@@ -2320,6 +2521,31 @@
}
}
+ private void handleEventNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
+ logd("handleEventNtnSignalStrengthChanged: ntnSignalStrength=" + ntnSignalStrength);
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("handleEventNtnSignalStrengthChanged: oemEnabledSatelliteFlag is disabled");
+ return;
+ }
+
+ synchronized (mNtnSignalsStrengthLock) {
+ mNtnSignalStrength = ntnSignalStrength;
+ }
+
+ List<INtnSignalStrengthCallback> deadCallersList = new ArrayList<>();
+ mNtnSignalStrengthChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onNtnSignalStrengthChanged(ntnSignalStrength);
+ } catch (RemoteException e) {
+ logd("handleEventNtnSignalStrengthChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mNtnSignalStrengthChangedListeners.remove(listener.asBinder());
+ });
+ }
+
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected void setSettingsKeyForSatelliteMode(int val) {
logd("setSettingsKeyForSatelliteMode val: " + val);
@@ -2396,6 +2622,7 @@
private void configureSatellitePlmnForCarrier(int subId) {
logd("configureSatellitePlmnForCarrier");
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("configureSatellitePlmnForCarrier: carrierEnabledSatelliteFlag is disabled");
return;
}
synchronized (mSupportedSatelliteServicesLock) {
@@ -2421,6 +2648,8 @@
private void updateSupportedSatelliteServicesForActiveSubscriptions() {
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("updateSupportedSatelliteServicesForActiveSubscriptions: "
+ + "carrierEnabledSatelliteFlag is disabled");
return;
}
@@ -2448,6 +2677,7 @@
@NonNull
private List<String> readSatellitePlmnsFromOverlayConfig() {
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
+ logd("readSatellitePlmnsFromOverlayConfig: carrierEnabledSatelliteFlag is disabled");
return new ArrayList<>();
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index 6ecb642..62f7371 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -31,10 +31,12 @@
import android.os.RegistrantList;
import android.os.RemoteException;
import android.telephony.Rlog;
+import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteManager.SatelliteException;
+import android.telephony.satellite.stub.INtnSignalStrengthConsumer;
import android.telephony.satellite.stub.ISatellite;
import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
import android.telephony.satellite.stub.ISatelliteListener;
@@ -87,6 +89,8 @@
@NonNull private final RegistrantList mPendingDatagramsRegistrants = new RegistrantList();
@NonNull private final RegistrantList mSatelliteDatagramsReceivedRegistrants =
new RegistrantList();
+ @NonNull private final RegistrantList mNtnSignalStrengthChangedRegistrants =
+ new RegistrantList();
@NonNull private final ISatelliteListener mListener = new ISatelliteListener.Stub() {
@Override
@@ -136,6 +140,13 @@
}
mDatagramTransferStateChangedRegistrants.notifyResult(datagramTransferState);
}
+
+ @Override
+ public void onNtnSignalStrengthChanged(
+ android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength) {
+ mNtnSignalStrengthChangedRegistrants.notifyResult(
+ SatelliteServiceUtils.fromModemInterface(ntnSignalStrength));
+ }
};
/**
@@ -441,6 +452,27 @@
}
/**
+ * Registers for non-terrestrial signal strength level changed.
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ public void registerForNtnSignalStrengthChanged(
+ @NonNull Handler h, int what, @Nullable Object obj) {
+ mNtnSignalStrengthChangedRegistrants.add(h, what, obj);
+ }
+
+ /**
+ * Unregisters for non-terrestrial signal strength level changed.
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ public void unregisterForNtnSignalStrengthChanged(@NonNull Handler h) {
+ mNtnSignalStrengthChangedRegistrants.remove(h);
+ }
+
+ /**
* Request to enable or disable the satellite service listening mode.
* Listening mode allows the satellite service to listen for incoming pages.
*
@@ -1153,6 +1185,102 @@
}
}
+ /**
+ * Request to get the signal strength of the satellite connection.
+ *
+ * @param message The Message to send to result of the operation to.
+ */
+ public void requestNtnSignalStrength(@NonNull Message message) {
+ if (mSatelliteService != null) {
+ try {
+ mSatelliteService.requestSignalStrength(
+ new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ int error = SatelliteServiceUtils.fromSatelliteError(result);
+ logd("requestNtnSignalStrength: " + error);
+ Binder.withCleanCallingIdentity(() ->
+ sendMessageWithResult(message, null, error));
+ }
+ }, new INtnSignalStrengthConsumer.Stub() {
+ @Override
+ public void accept(NtnSignalStrength result) {
+ logd("requestNtnSignalStrength: " + result);
+ Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
+ message, result,
+ SatelliteManager.SATELLITE_RESULT_SUCCESS));
+ }
+ });
+ } catch (RemoteException e) {
+ loge("requestNtnSignalStrength: RemoteException " + e);
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
+ }
+ } else {
+ loge("requestNtnSignalStrength: Satellite service is unavailable.");
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
+ }
+ }
+
+ /**
+ * The satellite service should report the NTN signal strength via
+ * ISatelliteListener#onNtnSignalStrengthChanged when the NTN signal strength changes.
+ *
+ * @param message The Message to send to result of the operation to.
+ */
+ public void startSendingNtnSignalStrength(@NonNull Message message) {
+ if (mSatelliteService != null) {
+ try {
+ mSatelliteService.startSendingNtnSignalStrength(new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ int error = SatelliteServiceUtils.fromSatelliteError(result);
+ logd("startSendingNtnSignalStrength: " + error);
+ Binder.withCleanCallingIdentity(() ->
+ sendMessageWithResult(message, null, error));
+ }
+ });
+ } catch (RemoteException e) {
+ loge("startSendingNtnSignalStrength: RemoteException " + e);
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
+ }
+ } else {
+ loge("startSendingNtnSignalStrength: Satellite service is unavailable.");
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
+ }
+ }
+
+ /**
+ * The satellite service should stop reporting NTN signal strength to the framework.
+ *
+ * @param message The Message to send to result of the operation to.
+ */
+ public void stopSendingNtnSignalStrength(@NonNull Message message) {
+ if (mSatelliteService != null) {
+ try {
+ mSatelliteService.stopSendingNtnSignalStrength(new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ int error = SatelliteServiceUtils.fromSatelliteError(result);
+ logd("stopSendingNtnSignalStrength: " + error);
+ Binder.withCleanCallingIdentity(() ->
+ sendMessageWithResult(message, null, error));
+ }
+ });
+ } catch (RemoteException e) {
+ loge("stopSendingNtnSignalStrength: RemoteException " + e);
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
+ }
+ } else {
+ loge("stopSendingNtnSignalStrength: Satellite service is unavailable.");
+ sendMessageWithResult(message, null,
+ SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
+ }
+ }
public boolean isSatelliteServiceSupported() {
return mIsSatelliteServiceSupported;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
index fc461fd..b42c7d4 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -31,6 +31,7 @@
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
@@ -212,6 +213,16 @@
}
/**
+ * Convert non-terrestrial signal strength from service definition to framework definition.
+ * @param ntnSignalStrength The non-terrestrial signal strength from the satellite service.
+ * @return The converted non-terrestrial signal strength for the framework.
+ */
+ @Nullable public static NtnSignalStrength fromModemInterface(
+ android.telephony.satellite.stub.NtnSignalStrength ntnSignalStrength) {
+ return new NtnSignalStrength(ntnSignalStrength.signalStrengthLevel);
+ }
+
+ /**
* Convert SatelliteDatagram from framework definition to service definition.
* @param datagram The SatelliteDatagram from the framework.
* @return The converted SatelliteDatagram for the satellite service.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index ea19b62..3c8db99 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -783,7 +783,7 @@
doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
doAnswer(invocation -> mNetworkId++).when(mNetwork).getNetId();
doReturn(mNetwork).when(mConnectivityManager).registerNetworkAgent(
- any(), any(), any(), any(), any(), any(), anyInt());
+ any(), any(), any(), any(), any(), any(), any(), anyInt());
doReturn(true).when(mEuiccManager).isEnabled();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
index 28a37f7..018759a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
@@ -20,7 +20,9 @@
import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
@@ -30,6 +32,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static java.util.Arrays.asList;
@@ -40,22 +43,31 @@
import android.hardware.radio.V1_5.IndicationFilter;
import android.net.ConnectivityManager;
import android.net.TetheringManager;
+import android.os.AsyncResult;
import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.test.suitebuilder.annotation.MediumTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import com.android.internal.telephony.flags.FeatureFlags;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -114,6 +126,7 @@
private static final int STATE_OFF = 0;
private static final int STATE_ON = 1;
+ private static final long TIMEOUT = 500;
// The keys are the single IndicationFilter flags,
// The values are the array of states, when one state turn on, the corresponding
@@ -135,6 +148,9 @@
UiModeManager mUiModeManager;
private DeviceStateMonitor mDSM;
+ private TestSatelliteController mSatelliteControllerUT;
+
+ @Mock private FeatureFlags mFeatureFlags;
// Given a stateType, return the event type that can change the state
private int state2Event(@StateType int stateType) {
@@ -162,11 +178,12 @@
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
+ MockitoAnnotations.initMocks(this);
mUiModeManager = mock(UiModeManager.class);
mContextFixture.setSystemService(Context.UI_MODE_SERVICE, mUiModeManager);
// We don't even need a mock executor, we just need to not throw.
doReturn(null).when(mContextFixture.getTestDouble()).getMainExecutor();
- mDSM = new DeviceStateMonitor(mPhone);
+ mDSM = new DeviceStateMonitor(mPhone, mFeatureFlags);
// Initialize with ALL states off
updateAllStatesToOff();
@@ -177,6 +194,7 @@
@After
public void tearDown() throws Exception {
+ mSatelliteControllerUT = null;
mDSM = null;
super.tearDown();
}
@@ -453,4 +471,160 @@
verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(
eq(INDICATION_FILTERS_MINIMUM), nullable(Message.class));
}
+
+ @Test
+ public void testRegisterForSignalStrengthReportDecisionWithFeatureEnabled() {
+ logd("testRegisterForSignalStrengthReportDecisionWithFeatureEnabled()");
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ mSatelliteControllerUT = new TestSatelliteController(Looper.myLooper(), mDSM);
+
+ updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, 0);
+ updateState(STATE_TYPE_SCREEN, STATE_OFF);
+ mSatelliteControllerUT.resetCount();
+ sEventDeviceStatusChanged.drainPermits();
+
+ updateState(STATE_TYPE_SCREEN, STATE_ON);
+ assertTrue(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(1, mSatelliteControllerUT.getStopEventCount());
+ mSatelliteControllerUT.resetCount();
+
+ mSatelliteControllerUT.resetCount();
+ updateState(STATE_TYPE_SCREEN, STATE_OFF);
+ assertTrue(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(1, mSatelliteControllerUT.getStopEventCount());
+ mSatelliteControllerUT.resetCount();
+
+ updateState(STATE_TYPE_RADIO_ON, 0);
+ assertTrue(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(1, mSatelliteControllerUT.getStopEventCount());
+ mSatelliteControllerUT.resetCount();
+
+ updateState(STATE_TYPE_SCREEN, STATE_ON);
+ assertTrue(waitForEventDeviceStatusChanged());
+ assertEquals(1, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+ mSatelliteControllerUT.resetCount();
+
+ updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, 0);
+ assertTrue(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(1, mSatelliteControllerUT.getStopEventCount());
+ }
+
+ @Test
+ public void testRegisterForSignalStrengthReportDecisionWithFeatureDisabled() {
+ logd("testRegisterForSignalStrengthReportDecisionWithFeatureDisabled()");
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
+ mSatelliteControllerUT = new TestSatelliteController(Looper.myLooper(), mDSM);
+
+ updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, 0);
+ updateState(STATE_TYPE_SCREEN, STATE_OFF);
+ mSatelliteControllerUT.resetCount();
+ sEventDeviceStatusChanged.drainPermits();
+
+
+ /* Sending stop ntn signal strength as radio is off */
+ updateState(STATE_TYPE_SCREEN, STATE_ON);
+ assertFalse(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+
+ updateState(STATE_TYPE_SCREEN, STATE_OFF);
+ assertFalse(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+
+ updateState(STATE_TYPE_RADIO_ON, 0);
+ assertFalse(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+
+ updateState(STATE_TYPE_SCREEN, STATE_ON);
+ assertFalse(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+
+ updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, 0);
+ assertFalse(waitForEventDeviceStatusChanged());
+ assertEquals(0, mSatelliteControllerUT.getStartEventCount());
+ assertEquals(0, mSatelliteControllerUT.getStopEventCount());
+ }
+
+ private static Semaphore sEventDeviceStatusChanged = new Semaphore(0);
+ private boolean waitForEventDeviceStatusChanged() {
+ try {
+ if (!sEventDeviceStatusChanged.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ logd("Time out to receive EVENT_DEVICE_STATUS_CHANGED");
+ return false;
+ }
+ } catch (Exception ex) {
+ logd("waitForEventDeviceStatusChanged: ex=" + ex);
+ return false;
+ }
+ return true;
+ }
+
+ private static class TestSatelliteController extends Handler {
+ public static final int EVENT_DEVICE_STATUS_CHANGED = 35;
+ private final DeviceStateMonitor mDsm;
+ private int mStartEventCount;
+ private int mStopEventCount;
+
+ TestSatelliteController(Looper looper, DeviceStateMonitor dsm) {
+ super(looper);
+ mDsm = dsm;
+ mDsm.registerForSignalStrengthReportDecision(this, EVENT_DEVICE_STATUS_CHANGED, null);
+ }
+
+ /**
+ * Resets the count of occurred events.
+ */
+ public void resetCount() {
+ mStartEventCount = 0;
+ mStopEventCount = 0;
+ }
+
+ public int getStartEventCount() {
+ return mStartEventCount;
+ }
+
+ public int getStopEventCount() {
+ return mStopEventCount;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case EVENT_DEVICE_STATUS_CHANGED: {
+ logd("EVENT_DEVICE_STATUS_CHANGED");
+ AsyncResult ar = (AsyncResult) msg.obj;
+ boolean shouldReport = (boolean) ar.result;
+ if (shouldReport) {
+ startSendingNtnSignalStrength();
+ } else {
+ stopSendingNtnSignalStrength();
+ }
+ try {
+ sEventDeviceStatusChanged.release();
+ } catch (Exception ex) {
+ logd("waitForEventDeviceStatusChanged: ex=" + ex);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ private void startSendingNtnSignalStrength() {
+ mStartEventCount++;
+ }
+
+ private void stopSendingNtnSignalStrength() {
+ mStopEventCount++;
+ }
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
index f729b80..8dd350f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DisplayInfoControllerTest.java
@@ -42,11 +42,14 @@
import android.testing.TestableLooper;
import android.text.TextUtils;
+import com.android.internal.telephony.flags.FeatureFlags;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
import java.util.Collections;
import java.util.concurrent.Executor;
@@ -54,17 +57,18 @@
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DisplayInfoControllerTest extends TelephonyTest {
-
private static final int PHONE_ID = 0;
private static final String MCC = "600";
private static final String MNC = "01";
private static final String NUMERIC = MCC + MNC;
private static final String NETWORK = "TestNet";
+ // Mocked classes
+ private FeatureFlags mFeatureFlags;
+
private DisplayInfoController mDic;
private ServiceStateTracker mSst;
private ServiceStateTrackerTestHandler mSstHandler;
- private SignalStrengthController mSsc;
private PersistableBundle mBundle;
private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
@@ -75,8 +79,8 @@
@Override
public void onLooperPrepared() {
- mSsc = new SignalStrengthController(mPhone);
- doReturn(mSsc).when(mPhone).getSignalStrengthController();
+ SignalStrengthController ssc = new SignalStrengthController(mPhone);
+ doReturn(ssc).when(mPhone).getSignalStrengthController();
doReturn(new ServiceState()).when(mPhone).getServiceState();
doReturn(NUMERIC).when(mTelephonyManager).getSimOperatorNumericForPhone(eq(PHONE_ID));
doReturn(NETWORK).when(mTelephonyManager).getSimOperatorNameForPhone(eq(PHONE_ID));
@@ -101,6 +105,7 @@
logd("DisplayInfoControllerTest setup!");
super.setUp(getClass().getSimpleName());
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
doReturn((Executor) Runnable::run).when(mContext).getMainExecutor();
mBundle = mContextFixture.getCarrierConfigBundle();
mSstHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
@@ -191,7 +196,7 @@
assertFalse(ss.getRoaming()); // home
doReturn(mSst).when(mPhone).getServiceStateTracker();
- mDic = new DisplayInfoController(mPhone);
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
mDic.updateTelephonyDisplayInfo();
TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
@@ -211,7 +216,7 @@
assertFalse(ss.getRoaming()); // home
doReturn(mSst).when(mPhone).getServiceStateTracker();
- mDic = new DisplayInfoController(mPhone);
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
mDic.updateTelephonyDisplayInfo();
TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
@@ -232,7 +237,7 @@
assertTrue(ss1.getRoaming()); // roam
doReturn(mSst).when(mPhone).getServiceStateTracker();
- mDic = new DisplayInfoController(mPhone);
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
mDic.updateTelephonyDisplayInfo();
TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
@@ -254,7 +259,7 @@
assertFalse(ss.getRoaming()); // home
doReturn(mSst).when(mPhone).getServiceStateTracker();
- mDic = new DisplayInfoController(mPhone);
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
mDic.updateTelephonyDisplayInfo();
TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
@@ -275,10 +280,32 @@
assertTrue(ss1.getRoaming()); // roam
doReturn(mSst).when(mPhone).getServiceStateTracker();
- mDic = new DisplayInfoController(mPhone);
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
mDic.updateTelephonyDisplayInfo();
TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
assertTrue(tdi.isRoaming());
}
+
+ @Test
+ public void testIsRoamingOverride_HideRoamingIndicator() {
+ doReturn(true).when(mPhone).isPhoneTypeGsm();
+ mBundle.putStringArray(
+ CarrierConfigManager.KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, new String[] {NUMERIC});
+ mBundle.putBoolean(CarrierConfigManager.KEY_SHOW_ROAMING_INDICATOR_BOOL, false);
+ doReturn(true).when(mFeatureFlags).hideRoamingIcon();
+ sendCarrierConfigUpdate();
+
+ changeRegState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ ServiceState ss1 = mSst.getServiceState();
+
+ assertTrue(ss1.getRoaming()); // roam
+
+ doReturn(mSst).when(mPhone).getServiceStateTracker();
+ mDic = new DisplayInfoController(mPhone, mFeatureFlags);
+ mDic.updateTelephonyDisplayInfo();
+ TelephonyDisplayInfo tdi = mDic.getTelephonyDisplayInfo();
+
+ assertFalse(tdi.isRoaming()); // display override
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index d304f5c..435763b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -108,6 +108,7 @@
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.data.PhoneSwitcher;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsNrSaModeHandler;
import com.android.internal.telephony.imsphone.ImsPhone;
@@ -183,6 +184,7 @@
}
// Mocked classes
+ protected FeatureFlags mFeatureFlags;
protected GsmCdmaPhone mPhone;
protected GsmCdmaPhone mPhone2;
protected ImsPhone mImsPhone;
@@ -421,6 +423,7 @@
protected void setUp(String tag) throws Exception {
TAG = tag;
enableStrictMode();
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
mPhone = Mockito.mock(GsmCdmaPhone.class);
mPhone2 = Mockito.mock(GsmCdmaPhone.class);
mImsPhone = Mockito.mock(ImsPhone.class);
@@ -590,7 +593,7 @@
doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory)
.makeIccPhoneBookInterfaceManager(nullable(Phone.class));
doReturn(mDisplayInfoController).when(mTelephonyComponentFactory)
- .makeDisplayInfoController(nullable(Phone.class));
+ .makeDisplayInfoController(nullable(Phone.class), any(FeatureFlags.class));
doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory)
.makeWspTypeDecoder(nullable(byte[].class));
doReturn(mImsCT).when(mTelephonyComponentFactory)
@@ -610,7 +613,7 @@
doReturn(mCarrierActionAgent).when(mTelephonyComponentFactory)
.makeCarrierActionAgent(nullable(Phone.class));
doReturn(mDeviceStateMonitor).when(mTelephonyComponentFactory)
- .makeDeviceStateMonitor(nullable(Phone.class));
+ .makeDeviceStateMonitor(nullable(Phone.class), any(FeatureFlags.class));
doReturn(mAccessNetworksManager).when(mTelephonyComponentFactory)
.makeAccessNetworksManager(nullable(Phone.class), any(Looper.class));
doReturn(mNitzStateMachine).when(mTelephonyComponentFactory)
@@ -625,6 +628,7 @@
doReturn(mDataProfileManager).when(mTelephonyComponentFactory)
.makeDataProfileManager(any(Phone.class), any(DataNetworkController.class),
any(DataServiceManager.class), any(Looper.class),
+ any(FeatureFlags.class),
any(DataProfileManager.DataProfileManagerCallback.class));
//mPhone
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
index b6d77e9..98d3ce5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
@@ -154,6 +154,9 @@
assertTrue(createApnSetting(
ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_EMERGENCY)
.canHandleType(ApnSetting.TYPE_EMERGENCY));
+ assertTrue(createApnSetting(
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_RCS | ApnSetting.TYPE_EMERGENCY)
+ .canHandleType(ApnSetting.TYPE_RCS));
assertFalse(createApnSetting(ApnSetting.TYPE_ALL)
.canHandleType(ApnSetting.TYPE_MCX));
assertTrue(createApnSetting(
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 5e7213b..f1ab894 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -209,6 +209,8 @@
.setMaxConns(321)
.setWaitTime(456)
.setMaxConnsTime(789)
+ .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_SATELLITE
+ | ApnSetting.INFRASTRUCTURE_CELLULAR)
.build())
.setPreferred(false)
.build();
@@ -401,6 +403,17 @@
.setPreferred(false)
.build();
+ private final DataProfile mNtnDataProfile = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName("ntn")
+ .setApnName("ntn")
+ .setApnTypeBitmask(ApnSetting.TYPE_RCS)
+ .setCarrierEnabled(true)
+ .setInfrastructureBitmask(ApnSetting.INFRASTRUCTURE_SATELLITE)
+ .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<>();
@@ -904,7 +917,8 @@
List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile,
mGeneralPurposeDataProfileAlternative, mImsCellularDataProfile,
mImsIwlanDataProfile, mEmergencyDataProfile, mFotaDataProfile,
- mTetheringDataProfile);
+ mTetheringDataProfile, mMmsOnWlanDataProfile, mLowLatencyDataProfile,
+ mNtnDataProfile);
doAnswer(invocation -> {
DataProfile dp = (DataProfile) invocation.getArguments()[0];
@@ -935,23 +949,30 @@
TelephonyNetworkRequest networkRequest =
(TelephonyNetworkRequest) invocation.getArguments()[0];
int networkType = (int) invocation.getArguments()[1];
- boolean ignorePermanentFailure = (boolean) invocation.getArguments()[2];
+ boolean isNtn = (boolean) invocation.getArguments()[2];
+ boolean ignorePermanentFailure = (boolean) invocation.getArguments()[3];
for (DataProfile dataProfile : profiles) {
- if (dataProfile.canSatisfy(networkRequest.getCapabilities())
- && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0
- || (dataProfile.getApnSetting().getNetworkTypeBitmask()
+ ApnSetting apnSetting = dataProfile.getApnSetting();
+ if (apnSetting != null
+ && dataProfile.canSatisfy(networkRequest.getCapabilities())
+ && (apnSetting.getNetworkTypeBitmask() == 0
+ || (apnSetting.getNetworkTypeBitmask()
& ServiceState.getBitmaskForTech(networkType)) != 0)
- && (ignorePermanentFailure || (dataProfile.getApnSetting() != null
- && !dataProfile.getApnSetting().getPermanentFailed()))) {
+ && ((isNtn && apnSetting.isForInfrastructure(
+ 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));
+ + TelephonyManager.getNetworkTypeName(networkType) + ", ignorePermanentFailure="
+ + ignorePermanentFailure + ", isNtn=" + isNtn);
return null;
}).when(mDataProfileManager).getDataProfileForNetworkRequest(
- any(TelephonyNetworkRequest.class), anyInt(), anyBoolean());
+ any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean());
doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
.getPreferredTransportByNetworkCapability(anyInt());
@@ -1233,7 +1254,7 @@
+ TelephonyManager.getNetworkTypeName(networkType));
return null;
}).when(mDataProfileManager).getDataProfileForNetworkRequest(
- any(TelephonyNetworkRequest.class), anyInt(), anyBoolean());
+ any(TelephonyNetworkRequest.class), anyInt(), anyBoolean(), anyBoolean());
// verify the network still connects
verify(mMockedDataNetworkControllerCallback).onConnectedInternetDataNetworksChanged(any());
@@ -1278,7 +1299,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean());
+ anyBoolean(), anyBoolean());
NetworkCapabilities netCaps = new NetworkCapabilities();
netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
@@ -1493,7 +1514,7 @@
// Now RAT changes from UMTS to GSM
doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_GSM),
- anyBoolean());
+ anyBoolean(), anyBoolean());
serviceStateChanged(TelephonyManager.NETWORK_TYPE_GSM,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
verifyAllDataDisconnected();
@@ -1507,14 +1528,14 @@
// Now RAT changes from GSM to UMTS
doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_UMTS),
- 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());
// Now RAT changes from UMTS to LTE
serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
@@ -3509,7 +3530,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean());
+ anyBoolean(), anyBoolean());
NetworkCapabilities netCaps = new NetworkCapabilities();
netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
@@ -4664,7 +4685,7 @@
createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean());
+ anyBoolean(), anyBoolean());
mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
@@ -4702,7 +4723,7 @@
createDataCallResponse(2, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
doReturn(mLowLatencyDataProfile).when(mDataProfileManager)
.getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt(),
- anyBoolean());
+ anyBoolean(), anyBoolean());
processAllFutureMessages();
dataNetworkList = getDataNetworks();
@@ -4731,12 +4752,11 @@
createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
processAllMessages();
verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
- verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
// 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());
setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager,
createDataCallResponse(2, DataCallResponse.LINK_STATUS_ACTIVE));
@@ -4746,4 +4766,16 @@
processAllMessages();
verifyConnectedNetworkHasDataProfile(mMmsOnWlanDataProfile);
}
+
+ @Test
+ public void testNonTerrestrialNetwork() throws Exception {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+ mIsNonTerrestrialNetwork = true;
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_RCS));
+ processAllMessages();
+ verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index 9235e46..e34d1ba 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -443,7 +443,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
- anyInt());
+ any(), anyInt());
// The very first link properties from telephony is an empty link properties. It will be
// updated later.
assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
@@ -550,7 +550,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(),
- anyInt());
+ any(), anyInt());
// Make sure the initial network capability has NOT_SUSPENDED
assertThat(networkCapabilitiesCaptor.getValue().hasCapability(
@@ -614,7 +614,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), networkCapabilitiesCaptor.capture(), any(), any(),
- anyInt());
+ any(), anyInt());
// Make sure the 2nd network agent was created with NOT_SUSPENDED.
assertThat(networkCapabilitiesCaptor.getValue().hasCapability(
@@ -674,7 +674,7 @@
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
- anyInt());
+ any(), anyInt());
// The very first link properties from telephony is an empty link properties. It will be
// updated later.
assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
@@ -1434,8 +1434,8 @@
.forClass(NetworkAgentConfig.class);
verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
- any(LinkProperties.class), any(NetworkCapabilities.class), any(), captor.capture(),
- anyInt());
+ any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
+ captor.capture(), anyInt());
NetworkAgentConfig networkAgentConfig = captor.getValue();
@@ -1518,7 +1518,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
@@ -1540,7 +1540,7 @@
// Agent not re-created, so register should be called once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)).isTrue();
@@ -1709,7 +1709,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
// The new agent should have the new IP address.
assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
InetAddresses.parseNumericAddress(IPV4_ADDRESS1),
@@ -1758,7 +1758,7 @@
// Agent re-created, so register should be called twice.
verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
// The new agent should have the new IP address.
assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
InetAddresses.parseNumericAddress(IPV6_ADDRESS1));
@@ -1849,7 +1849,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
@@ -1893,7 +1893,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
@@ -1938,7 +1938,7 @@
// Agent should not be re-created, so register should be called ony once.
verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
- anyInt());
+ any(), anyInt());
// The network should have IPv6 address now
assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
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 5c7e3ec..f9a11be 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.ContentValues;
@@ -53,6 +54,7 @@
import com.android.internal.telephony.data.DataConfigManager.DataConfigManagerCallback;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
import org.junit.After;
import org.junit.Before;
@@ -81,6 +83,7 @@
private static final String IMS_APN = "IMS_APN";
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 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 PLMN = "330123";
@@ -93,6 +96,8 @@
private DataProfileManager mDataProfileManagerUT;
+ private FeatureFlags mFeatureFlags;
+
private final ApnSettingContentProvider mApnSettingContentProvider =
new ApnSettingContentProvider();
@@ -132,6 +137,7 @@
Telephony.Carriers.CARRIER_ID,
Telephony.Carriers.SKIP_464XLAT,
Telephony.Carriers.ALWAYS_ON,
+ Telephony.Carriers.INFRASTRUCTURE_BITMASK
};
private int mPreferredApnSet = 0;
@@ -170,7 +176,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
// default internet data profile for RAT CDMA, to test update preferred data profile
new Object[]{
@@ -205,7 +212,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
2, // id
@@ -239,7 +247,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
3, // id
@@ -273,7 +282,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // alwys_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
4, // id
@@ -308,7 +318,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
// This APN entry is created to test de-duping.
new Object[]{
@@ -344,7 +355,8 @@
DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
6, // id
@@ -379,7 +391,8 @@
APN_SET_ID_1, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
7, // id
@@ -414,7 +427,8 @@
APN_SET_ID_1, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
},
new Object[]{
8, // id
@@ -449,7 +463,44 @@
MATCH_ALL_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
- 0 // always_on
+ 0, // always_on
+ 1 // INFRASTRUCTURE_CELLULAR
+ },
+ new Object[]{
+ 9, // id
+ PLMN, // numeric
+ RCS_APN, // name
+ RCS_APN, // 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
}
);
@@ -621,6 +672,7 @@
logd("DataProfileManagerTest +Setup!");
super.setUp(getClass().getSimpleName());
mDataProfileManagerCallback = Mockito.mock(DataProfileManagerCallback.class);
+ mFeatureFlags = Mockito.mock(FeatureFlags.class);
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
@@ -632,7 +684,8 @@
return null;
}).when(mDataProfileManagerCallback).invokeFromExecutor(any(Runnable.class));
mDataProfileManagerUT = new DataProfileManager(mPhone, mDataNetworkController,
- mMockedWwanDataServiceManager, Looper.myLooper(), mDataProfileManagerCallback);
+ mMockedWwanDataServiceManager, Looper.myLooper(), mFeatureFlags,
+ mDataProfileManagerCallback);
ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
verify(mDataNetworkController).registerDataNetworkControllerCallback(
@@ -663,7 +716,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -674,7 +727,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
@@ -684,7 +737,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(IMS_APN);
@@ -693,7 +746,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dp).isNull();
doReturn(new NetworkRegistrationInfo.Builder()
@@ -706,7 +759,7 @@
.build();
tnr = new TelephonyNetworkRequest(request, mPhone);
dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_NR, false);
+ TelephonyManager.NETWORK_TYPE_NR, false, false);
assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
assertThat(dp.getApnSetting().getApnName()).isEqualTo(TETHERING_APN);
}
@@ -718,7 +771,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_GSM, false);
+ TelephonyManager.NETWORK_TYPE_GSM, false, false);
// Should not find data profile due to RAT incompatible.
assertThat(dp).isNull();
}
@@ -730,14 +783,14 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, 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);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
}
@@ -748,7 +801,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -761,7 +814,7 @@
.addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
0, NetworkRequest.Type.REQUEST), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -777,7 +830,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -793,7 +846,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting()).isNull();
OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
@@ -803,13 +856,28 @@
}
@Test
+ public void testGetDataProfileForSatellite() {
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .build();
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+ DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
+ TelephonyManager.NETWORK_TYPE_LTE, true, false);
+
+ assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
+ assertThat(dp.getApnSetting().getApnName()).isEqualTo(RCS_APN);
+ }
+
+ @Test
public void testSetPreferredDataProfile() {
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
dataProfile.setPreferred(true);
@@ -823,14 +891,14 @@
// Test See if the same one can be returned.
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, 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);
+ tnr, TelephonyManager.NETWORK_TYPE_CDMA, false, false);
DataNetwork legacyRatInternetNetwork = Mockito.mock(DataNetwork.class);
doReturn(legacyRatDataProfile).when(legacyRatInternetNetwork).getDataProfile();
doReturn(new DataNetworkController.NetworkRequestList(List.of(tnr)))
@@ -849,7 +917,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
.build(), mPhone);
DataProfile dunDataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- dunTnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ dunTnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
DataNetwork dunInternetNetwork = Mockito.mock(DataNetwork.class);
doReturn(dunDataProfile).when(dunInternetNetwork).getDataProfile();
doReturn(new DataNetworkController.NetworkRequestList(List.of(dunTnr)))
@@ -948,7 +1016,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile).isNull();
// expect default EIMS when SIM absent
@@ -957,7 +1025,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
// expect no default IMS when SIM absent
@@ -966,7 +1034,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile).isEqualTo(null);
// Verify null as initial attached data profile is sent to modem
@@ -996,7 +1064,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile).isNull();
// expect default EIMS when SIM absent
@@ -1005,7 +1073,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
// expect no default IMS when SIM absent
@@ -1014,7 +1082,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile).isEqualTo(null);
// Verify in legacy mode, null IA should NOT be sent to modem
@@ -1049,7 +1117,7 @@
new TelephonyNetworkRequest(new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone),
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(IMS_APN);
}
@@ -1061,7 +1129,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);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
}
@@ -1198,7 +1266,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApn()).isEqualTo("sos");
assertThat(dataProfile.getTrafficDescriptor().getDataNetworkName()).isEqualTo("sos");
@@ -1215,7 +1283,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(), mPhone);
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
DataNetwork internetNetwork = Mockito.mock(DataNetwork.class);
@@ -1286,7 +1354,7 @@
// The carrier configured data profile should be the preferred APN after APN reset
DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
@@ -1299,7 +1367,7 @@
// The carrier configured data profile should be the preferred APN after APN reset
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
- tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
+ tnr, TelephonyManager.NETWORK_TYPE_LTE, false, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
}
@@ -1580,7 +1648,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
// Mark the APN as permanent failed.
dp.getApnSetting().setPermanentFailed(true);
@@ -1588,7 +1656,7 @@
// 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)).isNotEqualTo(dp);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNotEqualTo(dp);
}
@Test
@@ -1603,7 +1671,7 @@
.build();
TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
- TelephonyManager.NETWORK_TYPE_LTE, false);
+ TelephonyManager.NETWORK_TYPE_LTE, false, false);
// Mark the APN as permanent failed.
dp.getApnSetting().setPermanentFailed(true);
@@ -1611,7 +1679,7 @@
// 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)).isNull();
+ TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNull();
}
private void changeSimStateTo(@TelephonyManager.SimState int simState) {
@@ -1632,6 +1700,6 @@
// Verify the we can get the previously permanent failed data profile again.
assertThat(mDataProfileManagerUT.getDataProfileForNetworkRequest(
new TelephonyNetworkRequest(request, mPhone),
- TelephonyManager.NETWORK_TYPE_LTE, false)).isNotNull();
+ TelephonyManager.NETWORK_TYPE_LTE, false, false)).isNotNull();
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java
index 4a2eb38..f5981f7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java
@@ -179,6 +179,7 @@
assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_MMS)).isFalse();
assertThat(dp.canSatisfy(new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
NetworkCapabilities.NET_CAPABILITY_MMS})).isFalse();
+ assertThat(dp.canSatisfy(new int[]{NetworkCapabilities.NET_CAPABILITY_RCS})).isFalse();
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index 8372d8f..dd95ff0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -158,7 +158,8 @@
mockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
mMockedWlanDataServiceManager);
mDataRetryManagerUT = new DataRetryManager(mPhone, mDataNetworkController,
- mockedDataServiceManagers, Looper.myLooper(), mDataRetryManagerCallbackMock);
+ mockedDataServiceManagers, Looper.myLooper(), mFeatureFlags,
+ mDataRetryManagerCallbackMock);
ArgumentCaptor<DataConfigManagerCallback> dataConfigManagerCallbackCaptor =
ArgumentCaptor.forClass(DataConfigManagerCallback.class);
@@ -340,29 +341,30 @@
@Test
public void testDataSetupUnthrottling() throws Exception {
- testDataSetupRetryNetworkSuggestedNeverRetry();
+ doReturn(true).when(mFeatureFlags).unthrottleCheckTransport();
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+ .build();
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
+ DataNetworkController.NetworkRequestList
+ networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
+ mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
+ 456);
+ mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN, networkRequestList, 123,
+ 456);
+ processAllFutureMessages();
Mockito.clearInvocations(mDataRetryManagerCallbackMock);
+
DataNetworkController.NetworkRequestList mockNrl = Mockito.mock(
DataNetworkController.NetworkRequestList.class);
Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
field.setAccessible(true);
List<DataRetryEntry> mDataRetryEntries =
(List<DataRetryEntry>) field.get(mDataRetryManagerUT);
+ assertThat(mDataRetryEntries.size()).isEqualTo(2);
- // schedule 2 setup retries
- DataSetupRetryEntry scheduledRetry1 = new DataSetupRetryEntry.Builder<>()
- .setDataProfile(mDataProfile3)
- .setNetworkRequestList(mockNrl)
- .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setSetupRetryType(1)
- .build();
- DataSetupRetryEntry scheduledRetry2 = new DataSetupRetryEntry.Builder<>()
- .setNetworkRequestList(mockNrl)
- .setDataProfile(mDataProfile3)
- .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
- .setSetupRetryType(1)
- .build();
- mDataRetryEntries.addAll(List.of(scheduledRetry1, scheduledRetry2));
// Suppose we set the data profile as permanently failed.
mDataProfile3.getApnSetting().setPermanentFailed(true);
@@ -408,8 +410,21 @@
assertThat(entry.transport).isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
// check mDataProfile3-WWAN retry is cancelled, but not the WLAN
- assertThat(scheduledRetry1.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
- assertThat(scheduledRetry2.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+ assertThat(mDataRetryEntries.size()).isEqualTo(3);
+ for (DataRetryEntry retry : mDataRetryEntries) {
+ DataSetupRetryEntry setupRetry = (DataSetupRetryEntry) retry;
+ if (setupRetry.transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
+ if (setupRetry.retryDelayMillis == 0) {
+ assertThat(setupRetry.getState())
+ .isEqualTo(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+ } else {
+ assertThat(setupRetry.getState())
+ .isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
+ }
+ } else {
+ assertThat(setupRetry.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+ }
+ }
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index 9e78afd..94fd934 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -679,6 +679,37 @@
}
@Test
+ public void testSetAutoSelectedValidationFeatureNotSupported() throws Exception {
+ doReturn(false).when(mCellularNetworkValidator).isValidationFeatureSupported();
+ initialize();
+
+ // Phone 0 has sub 1, phone 1 has sub 2.
+ // Sub 1 is default data sub.
+ // Both are active subscriptions are active sub, as they are in both active slots.
+ setSlotIndexToSubId(0, 1);
+ setSlotIndexToSubId(1, 2);
+ setDefaultDataSubId(1);
+
+ doReturn(new SubscriptionInfoInternal.Builder(mSubscriptionManagerService
+ .getSubscriptionInfoInternal(2)).setOpportunistic(1).build())
+ .when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
+
+ mPhoneSwitcherUT.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1);
+ processAllMessages();
+ mPhoneSwitcherUT.mValidationCallback.onNetworkAvailable(null, 2);
+ processAllMessages();
+ assertEquals(2, mPhoneSwitcherUT.getAutoSelectedDataSubId());
+
+ // Switch to the default sub, verify AutoSelectedDataSubId is the default value.
+ clearInvocations(mSetOpptDataCallback1);
+ mPhoneSwitcherUT.trySetOpportunisticDataSubscription(SubscriptionManager
+ .DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback1);
+ processAllMessages();
+ assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mPhoneSwitcherUT.getAutoSelectedDataSubId());
+ }
+
+ @Test
@SmallTest
public void testSetPreferredDataModemCommand() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1357,7 +1388,7 @@
.when(mSubscriptionManagerService).getSubscriptionInfoInternal(2);
// Switch to primary before a primary is selected/inactive.
- setDefaultDataSubId(-1);
+ setDefaultDataSubId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
mPhoneSwitcherUT.trySetOpportunisticDataSubscription(
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
processAllMessages();
@@ -1992,7 +2023,7 @@
doReturn(true).when(mDataConfigManager).isPingTestBeforeAutoDataSwitchRequired();
}
- private void setDefaultDataSubId(int defaultDataSub) throws Exception {
+ private void setDefaultDataSubId(int defaultDataSub) {
mDefaultDataSub = defaultDataSub;
doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId();
for (Phone phone : mPhones) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
index 9752885..26a9fde 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
@@ -87,6 +87,24 @@
.setMaxConnsTime(789)
.build();
+ private static final ApnSetting RCS_APN_SETTING = new ApnSetting.Builder()
+ .setId(2165)
+ .setOperatorNumeric("12345")
+ .setEntryName("rcs")
+ .setApnName("rcs")
+ .setUser("user")
+ .setPassword("passwd")
+ .setApnTypeBitmask(ApnSetting.TYPE_RCS)
+ .setProtocol(ApnSetting.PROTOCOL_IPV6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
+ .setCarrierEnabled(true)
+ .setNetworkTypeBitmask(0)
+ .setProfileId(1234)
+ .setMaxConns(321)
+ .setWaitTime(456)
+ .setMaxConnsTime(789)
+ .build();
+
@Before
public void setUp() throws Exception {
logd("TelephonyNetworkRequestTest +Setup!");
@@ -211,6 +229,20 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
.build();
assertThat(internetRequest.canBeSatisfiedBy(caps)).isTrue();
+
+ TelephonyNetworkRequest rcsRequest = new TelephonyNetworkRequest(
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .build(), mPhone);
+ caps = new NetworkCapabilities.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+ .build();
+ assertThat(rcsRequest.canBeSatisfiedBy(caps)).isTrue();
}
@Test
@@ -223,17 +255,25 @@
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
.build(), mPhone);
+ TelephonyNetworkRequest rcsRequest = new TelephonyNetworkRequest(
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
+ .build(), mPhone);
DataProfile internetDataProfile = new DataProfile.Builder()
.setApnSetting(INTERNET_APN_SETTING)
.build();
DataProfile mmsDataProfile = new DataProfile.Builder()
.setApnSetting(MMS_APN_SETTING)
.build();
+ DataProfile rcsDataProfile = new DataProfile.Builder()
+ .setApnSetting(RCS_APN_SETTING)
+ .build();
assertThat(internetRequest.canBeSatisfiedBy(internetDataProfile)).isTrue();
assertThat(internetRequest.canBeSatisfiedBy(mmsDataProfile)).isFalse();
assertThat(mmsRequest.canBeSatisfiedBy(internetDataProfile)).isFalse();
assertThat(mmsRequest.canBeSatisfiedBy(mmsDataProfile)).isTrue();
+ assertThat(rcsRequest.canBeSatisfiedBy(rcsDataProfile)).isTrue();
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
index ce59cc6..a2a55ee 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
@@ -131,19 +131,16 @@
public void testWwanSelectorCallbackAsync() throws Exception {
mDsc = new DomainSelectionConnection(mPhone, SELECTOR_TYPE_CALLING, true,
mDomainSelectionController);
- replaceInstance(DomainSelectionConnection.class, "mWwanSelectedExecutor",
- mDsc, new Executor() {
- public void execute(Runnable command) {
- command.run();
- }
- });
TransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
assertNotNull(transportCallback);
+ replaceInstance(DomainSelectionConnection.class, "mLooper",
+ mDsc, mTestableLooper.getLooper());
Consumer<WwanSelectorCallback> consumer = Mockito.mock(Consumer.class);
transportCallback.onWwanSelected(consumer);
+ processAllMessages();
verify(consumer).accept(any());
}
@@ -171,6 +168,7 @@
Consumer<EmergencyRegResult> consumer = Mockito.mock(Consumer.class);
wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, null, consumer);
+ processAllMessages();
ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -220,11 +218,13 @@
CancellationSignal signal = new CancellationSignal();
wwanCallback.onRequestEmergencyNetworkScan(new ArrayList<>(),
SCAN_TYPE_NO_PREFERENCE, signal, Mockito.mock(Consumer.class));
+ processAllMessages();
verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());
signal.cancel();
+ processAllMessages();
verify(mPhone).cancelEmergencyNetworkScan(eq(false), any());
}
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 a84ca32..2feb34d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -16,7 +16,12 @@
package com.android.internal.telephony.satellite;
+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;
+import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_POOR;
import static android.telephony.satellite.SatelliteManager.KEY_DEMO_MODE_ENABLED;
+import static android.telephony.satellite.SatelliteManager.KEY_NTN_SIGNAL_STRENGTH;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_CAPABILITIES;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ENABLED;
@@ -87,10 +92,12 @@
import android.os.ResultReceiver;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
+import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
@@ -335,7 +342,7 @@
mQueriedSatelliteAllowed = false;
}
} else {
- logd("mSatelliteSupportReceiver: resultCode=" + resultCode);
+ logd("mSatelliteAllowedReceiver: resultCode=" + resultCode);
mQueriedSatelliteAllowed = false;
}
try {
@@ -374,6 +381,36 @@
}
};
+ private @NtnSignalStrength.NtnSignalStrengthLevel int mQueriedNtnSignalStrengthLevel =
+ NTN_SIGNAL_STRENGTH_NONE;
+ private int mQueriedNtnSignalStrengthResultCode = SATELLITE_RESULT_SUCCESS;
+ private Semaphore mRequestNtnSignalStrengthSemaphore = new Semaphore(0);
+ private ResultReceiver mRequestNtnSignalStrengthReceiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mQueriedNtnSignalStrengthResultCode = resultCode;
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_NTN_SIGNAL_STRENGTH)) {
+ NtnSignalStrength result = resultData.getParcelable(KEY_NTN_SIGNAL_STRENGTH);
+ logd("result.getLevel()=" + result.getLevel());
+ mQueriedNtnSignalStrengthLevel = result.getLevel();
+ } else {
+ loge("KEY_NTN_SIGNAL_STRENGTH does not exist.");
+ mQueriedNtnSignalStrengthLevel = NTN_SIGNAL_STRENGTH_NONE;
+ }
+ } else {
+ logd("KEY_NTN_SIGNAL_STRENGTH: resultCode=" + resultCode);
+ mQueriedNtnSignalStrengthLevel = NTN_SIGNAL_STRENGTH_NONE;
+ }
+ try {
+ mRequestNtnSignalStrengthSemaphore.release();
+ } catch (Exception ex) {
+ loge("mRequestNtnSignalStrengthReceiver: Got exception in releasing semaphore, ex="
+ + ex);
+ }
+ }
+ };
+
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
@@ -2002,6 +2039,276 @@
SATELLITE_MODEM_STATE_CONNECTED);
}
+ @Test
+ public void testRequestNtnSignalStrengthWithFeatureFlagEnabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ resetSatelliteControllerUT();
+
+ mRequestNtnSignalStrengthSemaphore.drainPermits();
+ setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+
+ @NtnSignalStrength.NtnSignalStrengthLevel int expectedLevel = NTN_SIGNAL_STRENGTH_GREAT;
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ /* In case request is not successful, result should be NTN_SIGNAL_STRENGTH_NONE */
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE, SATELLITE_RESULT_NOT_SUPPORTED);
+
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+
+ doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ // reset cache to NTN_SIGNAL_STRENGTH_NONE
+ sendNtnSignalStrengthChangedEvent(NTN_SIGNAL_STRENGTH_NONE, null);
+ processAllMessages();
+ expectedLevel = NTN_SIGNAL_STRENGTH_POOR;
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ }
+
+ @Test
+ public void testRequestNtnSignalStrengthWithFeatureFlagDisabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
+
+ resetSatelliteControllerUT();
+ mRequestNtnSignalStrengthSemaphore.drainPermits();
+ doReturn(false).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+
+ @NtnSignalStrength.NtnSignalStrengthLevel int expectedLevel = NTN_SIGNAL_STRENGTH_GREAT;
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ expectedLevel = NTN_SIGNAL_STRENGTH_POOR;
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_MODEM_ERROR);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+ }
+
+ @Test
+ public void testRegisterForNtnSignalStrengthChangedWithFeatureFlagEnabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ Semaphore semaphore = new Semaphore(0);
+ final NtnSignalStrength[] signalStrength = new NtnSignalStrength[1];
+ INtnSignalStrengthCallback callback =
+ new INtnSignalStrengthCallback.Stub() {
+ @Override
+ public void onNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
+ logd("onNtnSignalStrengthChanged: ntnSignalStrength="
+ + ntnSignalStrength);
+ try {
+ signalStrength[0] = ntnSignalStrength;
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onNtnSignalStrengthChanged: Got exception in releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ int errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID,
+ callback);
+ assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, errorCode);
+ @NtnSignalStrength.NtnSignalStrengthLevel int expectedLevel = NTN_SIGNAL_STRENGTH_NONE;
+
+ setUpResponseForRequestIsSatelliteSupported(false,
+ SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+ errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, errorCode);
+ verifyRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_NOT_SUPPORTED);
+
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);
+ verifyRequestNtnSignalStrength(expectedLevel, SATELLITE_RESULT_SUCCESS);
+
+ expectedLevel = NTN_SIGNAL_STRENGTH_GOOD;
+ sendNtnSignalStrengthChangedEvent(expectedLevel, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForNtnSignalStrengthChanged"));
+ assertEquals(expectedLevel, signalStrength[0].getLevel());
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_GOOD, SATELLITE_RESULT_SUCCESS);
+
+ expectedLevel = NTN_SIGNAL_STRENGTH_POOR;
+ sendNtnSignalStrengthChangedEvent(expectedLevel, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForNtnSignalStrengthChanged"));
+ assertEquals(expectedLevel, signalStrength[0].getLevel());
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_POOR, SATELLITE_RESULT_SUCCESS);
+
+ mSatelliteControllerUT.unregisterForNtnSignalStrengthChanged(SUB_ID, callback);
+ sendNtnSignalStrengthChangedEvent(NTN_SIGNAL_STRENGTH_GREAT, null);
+ processAllMessages();
+ assertFalse(waitForForEvents(
+ semaphore, 1, "testRegisterForNtnSignalStrengthChanged"));
+ /* Even if all listeners are unregistered, the cache is updated with the latest value when a
+ new value event occurs. */
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_GREAT, SATELLITE_RESULT_SUCCESS);
+ }
+
+ @Test
+ public void testRegisterForNtnSignalStrengthChangedWithFeatureFlagDisabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
+
+ Semaphore semaphore = new Semaphore(0);
+ final NtnSignalStrength[] signalStrength = new NtnSignalStrength[1];
+ INtnSignalStrengthCallback callback =
+ new INtnSignalStrengthCallback.Stub() {
+ @Override
+ public void onNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
+ logd("onNtnSignalStrengthChanged: ntnSignalStrength="
+ + ntnSignalStrength);
+ try {
+ signalStrength[0] = ntnSignalStrength;
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onNtnSignalStrengthChanged: Got exception in releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ int errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID,
+ callback);
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode);
+
+ setUpResponseForRequestIsSatelliteSupported(false,
+ SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(false, SATELLITE_RESULT_NOT_SUPPORTED);
+ errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode);
+ setUpResponseForRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_SUCCESS);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(false, SATELLITE_RESULT_NOT_SUPPORTED);
+ errorCode = mSatelliteControllerUT.registerForNtnSignalStrengthChanged(SUB_ID, callback);
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode);
+ verifyRequestNtnSignalStrength(NTN_SIGNAL_STRENGTH_NONE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+
+ @NtnSignalStrength.NtnSignalStrengthLevel int expectedNtnSignalStrengthLevel =
+ NTN_SIGNAL_STRENGTH_GOOD;
+ sendNtnSignalStrengthChangedEvent(expectedNtnSignalStrengthLevel, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 0, "testRegisterForNtnSignalStrengthChanged"));
+ }
+
+ @Test
+ public void testSendingNtnSignalStrengthWithFeatureEnabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ int expectedResult = SATELLITE_RESULT_SUCCESS;
+ // startSendingNtnSignalStrength() is requested when screen on event comes.
+ reset(mMockSatelliteModemInterface);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestIsSatelliteSupported(true, expectedResult);
+ setUpResponseForRequestIsSatelliteProvisioned(true, expectedResult);
+ verifySatelliteSupported(true, expectedResult);
+ verifySatelliteProvisioned(true, expectedResult);
+ setUpResponseForStartSendingNtnSignalStrength(expectedResult);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(true);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, times(1))
+ .startSendingNtnSignalStrength(any(Message.class));
+
+ // stopSendingNtnSignalStrength() is requested when screen off event comes.
+ reset(mMockSatelliteModemInterface);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForStopSendingNtnSignalStrength(expectedResult);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(false);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, times(1))
+ .stopSendingNtnSignalStrength(any(Message.class));
+
+ // startSendingNtnSignalStrength() is requested but received fail from the service.
+ reset(mMockSatelliteModemInterface);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForStartSendingNtnSignalStrength(SATELLITE_RESULT_INVALID_MODEM_STATE);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(true);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, times(1))
+ .startSendingNtnSignalStrength(any(Message.class));
+
+ // stopSendingNtnSignalStrength() is requested but received fail from the service.
+ reset(mMockSatelliteModemInterface);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForStopSendingNtnSignalStrength(SATELLITE_RESULT_NO_RESOURCES);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(false);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, times(1))
+ .stopSendingNtnSignalStrength(any(Message.class));
+ }
+
+ @Test
+ public void testSendingNtnSignalStrengthWithFeatureDisabled() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
+
+ int expectedResult = SATELLITE_RESULT_SUCCESS;
+ // startSendingNtnSignalStrength() is requested when screen on event comes.
+ reset(mMockSatelliteModemInterface);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForRequestIsSatelliteSupported(true, expectedResult);
+ setUpResponseForRequestIsSatelliteProvisioned(true, expectedResult);
+ verifySatelliteSupported(false, SATELLITE_RESULT_NOT_SUPPORTED);
+ verifySatelliteProvisioned(false, SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
+ setUpResponseForStartSendingNtnSignalStrength(expectedResult);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(true);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, never())
+ .startSendingNtnSignalStrength(any(Message.class));
+
+ // stopSendingNtnSignalStrength() is requested when screen off event comes.
+ reset(mMockSatelliteModemInterface);
+ setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
+ setUpResponseForStopSendingNtnSignalStrength(expectedResult);
+ sendCmdStartSendingNtnSignalStrengthChangedEvent(false);
+ processAllMessages();
+ verify(mMockSatelliteModemInterface, never())
+ .stopSendingNtnSignalStrength(any(Message.class));
+ }
+
private void resetSatelliteControllerUTEnabledState() {
logd("resetSatelliteControllerUTEnabledState");
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
@@ -2229,6 +2536,20 @@
}).when(mMockSatelliteModemInterface).requestSatelliteCapabilities(any(Message.class));
}
+ private void setUpResponseForRequestNtnSignalStrength(
+ @NtnSignalStrength.NtnSignalStrengthLevel int ntnSignalStrengthLevel,
+ @SatelliteManager.SatelliteResult int error) {
+ SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
+ ? null : new SatelliteException(error);
+ doAnswer(invocation -> {
+ Message message = (Message) invocation.getArguments()[0];
+ AsyncResult.forMessage(message, new NtnSignalStrength(ntnSignalStrengthLevel),
+ exception);
+ message.sendToTarget();
+ return null;
+ }).when(mMockSatelliteModemInterface).requestNtnSignalStrength(any(Message.class));
+ }
+
private boolean waitForForEvents(
Semaphore semaphore, int expectedNumberOfEvents, String caller) {
for (int i = 0; i < expectedNumberOfEvents; i++) {
@@ -2281,6 +2602,30 @@
}).when(mMockPointingAppController).stopSatelliteTransmissionUpdates(any(Message.class));
}
+ private void setUpResponseForStartSendingNtnSignalStrength(
+ @SatelliteManager.SatelliteResult int error) {
+ SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
+ ? null : new SatelliteException(error);
+ doAnswer(invocation -> {
+ Message message = (Message) invocation.getArguments()[0];
+ AsyncResult.forMessage(message, null, exception);
+ message.sendToTarget();
+ return null;
+ }).when(mMockSatelliteModemInterface).startSendingNtnSignalStrength(any(Message.class));
+ }
+
+ private void setUpResponseForStopSendingNtnSignalStrength(
+ @SatelliteManager.SatelliteResult int error) {
+ SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
+ ? null : new SatelliteException(error);
+ doAnswer(invocation -> {
+ Message message = (Message) invocation.getArguments()[0];
+ AsyncResult.forMessage(message, null, exception);
+ message.sendToTarget();
+ return null;
+ }).when(mMockSatelliteModemInterface).stopSendingNtnSignalStrength(any(Message.class));
+ }
+
private boolean waitForRequestIsSatelliteSupportedResult(int expectedNumberOfEvents) {
for (int i = 0; i < expectedNumberOfEvents; i++) {
try {
@@ -2391,6 +2736,22 @@
return true;
}
+ private boolean waitForRequestNtnSignalStrengthResult(int expectedNumberOfEvents) {
+ for (int i = 0; i < expectedNumberOfEvents; i++) {
+ try {
+ if (!mRequestNtnSignalStrengthSemaphore.tryAcquire(TIMEOUT,
+ TimeUnit.MILLISECONDS)) {
+ loge("Timeout to receive requestNtnSignalStrength() callback");
+ return false;
+ }
+ } catch (Exception ex) {
+ loge("requestNtnSignalStrength: Got exception=" + ex);
+ return false;
+ }
+ }
+ return true;
+ }
+
private boolean waitForIIntegerConsumerResult(int expectedNumberOfEvents) {
for (int i = 0; i < expectedNumberOfEvents; i++) {
try {
@@ -2434,6 +2795,17 @@
assertEquals(provisioned, mQueriedIsSatelliteProvisioned);
}
+ private void verifyRequestNtnSignalStrength(
+ @NtnSignalStrength.NtnSignalStrengthLevel int signalStrengthLevel,
+ int expectedErrorCode) {
+ mRequestNtnSignalStrengthSemaphore.drainPermits();
+ mSatelliteControllerUT.requestNtnSignalStrength(SUB_ID, mRequestNtnSignalStrengthReceiver);
+ processAllMessages();
+ assertTrue(waitForRequestNtnSignalStrengthResult(1));
+ assertEquals(expectedErrorCode, mQueriedNtnSignalStrengthResultCode);
+ assertEquals(signalStrengthLevel, mQueriedNtnSignalStrengthLevel);
+ }
+
private void sendProvisionedStateChangedEvent(boolean provisioned, Throwable exception) {
Message msg = mSatelliteControllerUT.obtainMessage(
26 /* EVENT_SATELLITE_PROVISION_STATE_CHANGED */);
@@ -2448,6 +2820,33 @@
msg.sendToTarget();
}
+ private void sendNtnSignalStrengthChangedEvent(
+ @NtnSignalStrength.NtnSignalStrengthLevel int ntnSignalStrengthLevel,
+ Throwable exception) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 34 /* EVENT_NTN_SIGNAL_STRENGTH_CHANGED */);
+ msg.obj = new AsyncResult(null, new NtnSignalStrength(ntnSignalStrengthLevel),
+ exception);
+ msg.sendToTarget();
+ }
+
+ private void sendCmdStartSendingNtnSignalStrengthChangedEvent(boolean shouldReport) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 35 /* CMD_START_SENDING_NTN_SIGNAL_STRENGTH */);
+ msg.obj = new AsyncResult(null, shouldReport, null);
+ msg.sendToTarget();
+ }
+
+ private void sendStartSendingNtnSignalStrengthChangedEvent(
+ @NtnSignalStrength.NtnSignalStrengthLevel int ntnSignalStrengthLevel,
+ Throwable exception) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 36 /* EVENT_START_SENDING_NTN_SIGNAL_STRENGTH_DONE */);
+ msg.obj = new AsyncResult(null, new NtnSignalStrength(ntnSignalStrengthLevel),
+ exception);
+ msg.sendToTarget();
+ }
+
private void setRadioPower(boolean on) {
mSimulatedCommands.setRadioPower(on, false, false, null);
}