Merge "Add new satellite APIs for cellular modem." into main
diff --git a/flags/calling.aconfig b/flags/calling.aconfig
index 906abfc..65cfbaf 100644
--- a/flags/calling.aconfig
+++ b/flags/calling.aconfig
@@ -69,4 +69,5 @@
namespace: "telephony"
description: "Used to notify the emergency callback mode for call/SMS to other applications."
bug:"359064059"
+ is_exported: true
}
diff --git a/flags/data.aconfig b/flags/data.aconfig
index ccd5db4..17d1adb 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -121,21 +121,11 @@
}
}
-# OWNER=jackyu TARGET=25Q1
-flag {
- name: "sim_disabled_graceful_tear_down"
- namespace: "telephony"
- description: "Gracefully tear down the networks when SIM is disabled."
- bug: "362372940"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
# OWNER=TBD TARGET=TBD
flag {
name: "oem_paid_private"
namespace: "telephony"
description: "Support OEM_PAID and OEM_PRIVATE networks"
bug: "366194627"
+ is_exported: true
}
diff --git a/flags/ims.aconfig b/flags/ims.aconfig
index 4ce7508..703440f 100644
--- a/flags/ims.aconfig
+++ b/flags/ims.aconfig
@@ -155,6 +155,7 @@
namespace: "telephony"
description: "Used to expose SMS related hidden APIs for SMS over IMS to public API."
bug:"359721349"
+ is_exported: true
}
# OWNER=jhyoon TARGET=25Q2
@@ -163,4 +164,5 @@
namespace: "telephony"
description: "This flag controls the type of API regarding MmTelFeature, either hidden or system type."
bug:"359721349"
+ is_exported: true
}
diff --git a/flags/satellite.aconfig b/flags/satellite.aconfig
index 8662572..ee4570e 100644
--- a/flags/satellite.aconfig
+++ b/flags/satellite.aconfig
@@ -41,6 +41,7 @@
namespace: "telephony"
description: "This flag enables satellite carrier roaming to nb iot ntn."
bug:"348253735"
+ is_exported: true
}
# OWNER=tnd TARGET=24Q4
@@ -78,4 +79,5 @@
namespace: "telephony"
description: "Introduce SatelliteManager APIs for carrier apps to monitor satellite state change"
bug: "357638490"
+ is_exported: true
}
diff --git a/flags/subscription.aconfig b/flags/subscription.aconfig
index aea9bd0..0522a3c 100644
--- a/flags/subscription.aconfig
+++ b/flags/subscription.aconfig
@@ -88,4 +88,5 @@
namespace: "telephony"
description: "Provide APIs to retrieve the status and recurrence rule info on a subscription plan"
bug: "357272015"
+ is_exported: true
}
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index abe4296..edb4ce2 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -49,6 +49,7 @@
namespace: "telephony"
description: "This flag controls the visibility of the setCarrierRestrictionStatus API in carrierRestrictionRules class."
bug:"342411308"
+ is_exported: true
}
# OWNER=arunvoddu TARGET=24Q4
@@ -87,4 +88,33 @@
namespace: "telephony"
description: "This flag controls the type of API that retrieves ISIM records, either hidden or system type."
bug:"359721349"
+ is_exported: true
+}
+
+# OWNER=jinjeong TARGET=25Q2
+flag {
+ name: "carrier_id_from_carrier_identifier"
+ namespace: "telephony"
+ description: "This flag controls to get a carrier id using a carrier identifier."
+ bug:"378778278"
+ is_exported: true
+}
+
+# OWNER=arunvoddu TARGET=25Q2
+flag {
+ name: "force_imsi_certificate_delete"
+ namespace: "telephony"
+ description: "This flag controls the IMSI certificate delete with out any condition."
+ bug:"235296888"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+# OWNER=jinjeong TARGET=25Q2
+flag {
+ name: "get_group_id_level2"
+ namespace: "telephony"
+ description: "This flag controls to get a group id level2."
+ bug:"381171540"
}
diff --git a/src/java/com/android/internal/telephony/CarrierInfoManager.java b/src/java/com/android/internal/telephony/CarrierInfoManager.java
index 8364c0a..206770d 100644
--- a/src/java/com/android/internal/telephony/CarrierInfoManager.java
+++ b/src/java/com/android/internal/telephony/CarrierInfoManager.java
@@ -273,21 +273,25 @@
/**
* Resets the Carrier Keys in the database. This involves 2 steps:
- * 1. Delete the keys from the database.
- * 2. Send an intent to download new Certificates.
- * @param context Context
- * @param mPhoneId phoneId
+ * 1. Delete the keys from the database.
+ * 2. Send an intent to download new Certificates.
*
+ * @param context Context
+ * @param mPhoneId phoneId
+ * @param forceResetAll to skip the check of the RESET_CARRIER_KEY_RATE_LIMIT.
*/
- public void resetCarrierKeysForImsiEncryption(Context context, int mPhoneId) {
- Log.i(LOG_TAG, "resetting carrier key");
+ public void resetCarrierKeysForImsiEncryption(Context context, int mPhoneId,
+ boolean forceResetAll) {
+ Log.i(LOG_TAG, "resetting carrier key, forceResetAll = " +forceResetAll);
// Check rate limit.
long now = System.currentTimeMillis();
- if (now - mLastAccessResetCarrierKey < RESET_CARRIER_KEY_RATE_LIMIT) {
- Log.i(LOG_TAG, "resetCarrierKeysForImsiEncryption: Access rate exceeded");
- return;
+ if (!forceResetAll) {
+ if (now - mLastAccessResetCarrierKey < RESET_CARRIER_KEY_RATE_LIMIT) {
+ Log.i(LOG_TAG, "resetCarrierKeysForImsiEncryption: Access rate exceeded");
+ return;
+ }
+ mLastAccessResetCarrierKey = now;
}
- mLastAccessResetCarrierKey = now;
int subId = SubscriptionManager.getSubscriptionId(mPhoneId);
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
diff --git a/src/java/com/android/internal/telephony/EventLogTags.logtags b/src/java/com/android/internal/telephony/EventLogTags.logtags
index b5e458b..2f30c33 100644
--- a/src/java/com/android/internal/telephony/EventLogTags.logtags
+++ b/src/java/com/android/internal/telephony/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.telephony;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 6a6e4d0..5a73cae 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -2189,7 +2189,12 @@
@Override
public void resetCarrierKeysForImsiEncryption() {
- mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId);
+ mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId, false);
+ }
+
+ @Override
+ public void resetCarrierKeysForImsiEncryption(boolean forceResetAll) {
+ mCIM.resetCarrierKeysForImsiEncryption(mContext, mPhoneId, forceResetAll);
}
@Override
@@ -3770,6 +3775,13 @@
&& disclosure != null) {
mIdentifierDisclosureNotifier.addDisclosure(mContext, getSubId(), disclosure);
}
+ if (mFeatureFlags.cellularIdentifierDisclosureIndications()
+ && mIdentifierDisclosureNotifier != null
+ && disclosure != null) {
+ logd("EVENT_CELL_IDENTIFIER_DISCLOSURE for non-Safety Center listeners "
+ + "phoneId = " + getPhoneId());
+ mNotifier.notifyCellularIdentifierDisclosedChanged(this, disclosure);
+ }
break;
case EVENT_SET_IDENTIFIER_DISCLOSURE_ENABLED_DONE:
@@ -3780,13 +3792,21 @@
case EVENT_SECURITY_ALGORITHM_UPDATE:
logd("EVENT_SECURITY_ALGORITHM_UPDATE phoneId = " + getPhoneId());
+
+ ar = (AsyncResult) msg.obj;
+ SecurityAlgorithmUpdate update = (SecurityAlgorithmUpdate) ar.result;
+
if (mFeatureFlags.enableModemCipherTransparencyUnsolEvents()
&& mNullCipherNotifier != null) {
- ar = (AsyncResult) msg.obj;
- SecurityAlgorithmUpdate update = (SecurityAlgorithmUpdate) ar.result;
mNullCipherNotifier.onSecurityAlgorithmUpdate(mContext, getPhoneId(),
getSubId(), update);
}
+ if (mFeatureFlags.securityAlgorithmsUpdateIndications()
+ && mNullCipherNotifier != null) {
+ logd("EVENT_SECURITY_ALGORITHM_UPDATE for non-Safety Center listeners "
+ + "phoneId = " + getPhoneId());
+ mNotifier.notifySecurityAlgorithmsChanged(this, update);
+ }
break;
case EVENT_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED_DONE:
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index ab9be76..5998d46 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -4076,6 +4076,16 @@
}
/**
+ * Resets the Carrier Keys in the database. This involves 2 steps:
+ * 1. Delete the keys from the database.
+ * 2. Send an intent to download new Certificates.
+ *
+ * @param forceResetAll : Force delete the downloaded key if any.
+ */
+ public void resetCarrierKeysForImsiEncryption(boolean forceResetAll) {
+ }
+
+ /**
* Return if UT capability of ImsPhone is enabled or not
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index c40193e..9801542 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -659,6 +659,20 @@
});
}
+ /**
+ * Return GroupIdLevel2 for the subscriber
+ */
+ public String getGroupIdLevel2ForSubscriber(int subId, String callingPackage,
+ String callingFeatureId) {
+ return callPhoneMethodForSubIdWithPrivilegedCheck(subId,
+ "getGroupIdLevel2", (phone)-> {
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "getGroupIdLevel2ForSubscriber");
+ return phone.getGroupIdLevel2();
+ });
+ }
+
/** Below are utility methods that abstracts the flow that many public methods use:
* 1. Check permission: pass, throw exception, or fails (returns false).
* 2. clearCallingIdentity.
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index b209d1d..88b9958 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -2738,6 +2738,14 @@
}
/**
+ * Returns the flag specifying whether any part of this {@link SmsTracker} failed to send
+ * or not.
+ */
+ protected boolean isAnyPartFailed() {
+ return mAnyPartFailed != null && mAnyPartFailed.get();
+ }
+
+ /**
* Persist a sent SMS if required:
* 1. It is a text message
* 2. SmsApplication tells us to persist: sent from apps that are not default-SMS app or
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 58f3490..91aac26 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -1234,7 +1234,8 @@
boolean isOverIms, boolean isLastSmsPart, boolean success) {
notifySmsSentToEmergencyStateTracker(tracker.mDestAddress,
tracker.mMessageId, isOverIms, isLastSmsPart, success);
- notifySmsSentToDatagramDispatcher(tracker.mUniqueMessageId, isLastSmsPart, success);
+ notifySmsSentToDatagramDispatcher(tracker.mUniqueMessageId,
+ tracker.isSinglePartOrLastPart(), success && !tracker.isAnyPartFailed());
}
/**
@@ -1256,9 +1257,10 @@
private void notifySmsSentToDatagramDispatcher(
long messageId, boolean isLastSmsPart, boolean success) {
- if (SatelliteController.getInstance().shouldSendSmsToDatagramDispatcher(mPhone)) {
+ if (SatelliteController.getInstance().shouldSendSmsToDatagramDispatcher(mPhone)
+ && isLastSmsPart) {
DatagramDispatcher.getInstance().onSendSmsDone(
- mPhone.getSubId(), messageId, isLastSmsPart, success);
+ mPhone.getSubId(), messageId, success);
}
}
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index 40c0081..f5eae91 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -225,8 +225,6 @@
SIM_LOADED(true),
/** SIM is removed. */
SIM_REMOVAL(true),
- /** SIM is disabled. */
- SIM_DISABLED(true),
/** Data profiles changed. */
DATA_PROFILES_CHANGED(true),
/** When service state changes.(For now only considering data RAT and data registration). */
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 9e432e1..d5bc741 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -3543,6 +3543,15 @@
}
/**
+ * Called when SIM is absent.
+ */
+ private void onSimAbsent() {
+ log("onSimAbsent");
+ sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
+ DataEvaluationReason.SIM_REMOVAL));
+ }
+
+ /**
* Called when SIM state changes.
*
* @param simState SIM state. (Note this is mixed with card state and application state.)
@@ -3550,22 +3559,13 @@
private void onSimStateChanged(@SimState int simState) {
log("onSimStateChanged: state=" + TelephonyManager.simStateToString(simState));
if (mSimState != simState) {
+ mSimState = simState;
if (simState == TelephonyManager.SIM_STATE_ABSENT) {
- log("onSimStateChanged: SIM absent.");
- sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
- DataEvaluationReason.SIM_REMOVAL));
- } else if (simState == TelephonyManager.SIM_STATE_NOT_READY
- && mSimState == TelephonyManager.SIM_STATE_LOADED) {
- if (mFeatureFlags.simDisabledGracefulTearDown()) {
- log("onSimStateChanged: SIM disabled.");
- sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
- DataEvaluationReason.SIM_DISABLED));
- }
+ onSimAbsent();
} else if (simState == TelephonyManager.SIM_STATE_LOADED) {
sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
DataEvaluationReason.SIM_LOADED));
}
- mSimState = simState;
mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
() -> callback.onSimStateChanged(mSimState)));
}
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramController.java b/src/java/com/android/internal/telephony/satellite/DatagramController.java
index 9f6edf2..acd3fd1 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramController.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramController.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
@@ -419,6 +420,15 @@
&& mSatelltieModemState == SATELLITE_MODEM_STATE_NOT_CONNECTED) {
return false;
}
+ boolean allowCheckMessageInNotConnected =
+ mContext.getResources().getBoolean(
+ R.bool.config_satellite_allow_check_message_in_not_connected);
+ if (datagramType == DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS
+ && mSatelltieModemState == SATELLITE_MODEM_STATE_NOT_CONNECTED
+ && allowCheckMessageInNotConnected
+ && mFeatureFlags.carrierRoamingNbIotNtn()) {
+ return false;
+ }
if (mSatelltieModemState != SATELLITE_MODEM_STATE_CONNECTED
&& mSatelltieModemState != SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING) {
return true;
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index d6b1a70..113c3ee 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -406,10 +406,9 @@
SomeArgs args = (SomeArgs) msg.obj;
int subId = (int) args.arg1;
long messageId = (long) args.arg2;
- boolean isLastPartSms = (boolean) args.arg3;
- boolean success = (boolean) args.arg4;
+ boolean success = (boolean) args.arg3;
try {
- handleEventSendSmsDone(subId, messageId, isLastPartSms, success);
+ handleEventSendSmsDone(subId, messageId, success);
} finally {
args.recycle();
}
@@ -754,6 +753,8 @@
private void reportSendDatagramCompleted(@NonNull SendSatelliteDatagramArgument argument,
@NonNull @SatelliteManager.SatelliteResult int resultCode) {
+ long datagramTransmissionTime = argument.datagramStartTime > 0
+ ? (System.currentTimeMillis() - argument.datagramStartTime) : 0;
SatelliteStats.getInstance().onSatelliteOutgoingDatagramMetrics(
new SatelliteStats.SatelliteOutgoingDatagramParams.Builder()
.setDatagramType(argument.datagramType)
@@ -761,15 +762,15 @@
.setDatagramSizeBytes(argument.getDatagramRoundedSizeBytes())
/* In case pending datagram has not been attempted to send to modem
interface. transfer time will be 0. */
- .setDatagramTransferTimeMillis(argument.datagramStartTime > 0
- ? (System.currentTimeMillis() - argument.datagramStartTime) : 0)
+ .setDatagramTransferTimeMillis(datagramTransmissionTime)
.setIsDemoMode(mIsDemoMode)
.setCarrierId(SatelliteController.getInstance().getSatelliteCarrierId())
.build());
if (resultCode == SatelliteManager.SATELLITE_RESULT_SUCCESS) {
mControllerMetricsStats.reportOutgoingDatagramSuccessCount(argument.datagramType,
mIsDemoMode);
- mSessionMetricsStats.addCountOfSuccessfulOutgoingDatagram(argument.datagramType);
+ mSessionMetricsStats.addCountOfSuccessfulOutgoingDatagram(argument.datagramType,
+ datagramTransmissionTime);
} else {
mControllerMetricsStats.reportOutgoingDatagramFailCount(argument.datagramType,
mIsDemoMode);
@@ -1182,15 +1183,13 @@
* Sending MO SMS is completed.
* @param subId subscription ID
* @param messageId message ID of MO SMS
- * @param isLastSmsPart whether this is the last sms part of MO SMS
* @param success boolean specifying whether MO SMS is successfully sent or not.
*/
- public void onSendSmsDone(int subId, long messageId, boolean isLastSmsPart, boolean success) {
+ public void onSendSmsDone(int subId, long messageId, boolean success) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = subId;
args.arg2 = messageId;
- args.arg3 = isLastSmsPart;
- args.arg4 = success;
+ args.arg3 = success;
sendMessage(obtainMessage(EVENT_SEND_SMS_DONE, args));
}
@@ -1231,29 +1230,32 @@
pendingSmsMap.clear();
}
- private void handleEventSendSmsDone(
- int subId, long messageId, boolean isLastPartSms, boolean success) {
+ private void handleEventSendSmsDone(int subId, long messageId, boolean success) {
synchronized (mLock) {
- mSendingInProgress = false;
PendingRequest pendingSms = mPendingSmsMap.remove(messageId);
- int datagramType = pendingSms != null && pendingSms.isMtSmsPolling
+ if (pendingSms == null) {
+ // Just return, the SMS is not sent by DatagramDispatcher such as Data SMS
+ plogd("handleEventSendSmsDone there is no pendingSms for messageId=" + messageId);
+ return;
+ }
+
+ mSendingInProgress = false;
+ int datagramType = pendingSms.isMtSmsPolling
? DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS : DATAGRAM_TYPE_SMS;
plogd("handleEventSendSmsDone subId=" + subId + " messageId=" + messageId
- + " isLastPartSms=" + isLastPartSms + " success=" + success
- + " datagramType=" + datagramType);
+ + " success=" + success + " datagramType=" + datagramType);
if (success) {
- if (isLastPartSms) {
- // Update send status only after all parts of the SMS are sent
- mDatagramController.updateSendStatus(subId, datagramType,
- SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS,
- getPendingMessagesCount(), SATELLITE_RESULT_SUCCESS);
- }
+ // Update send status
+ mDatagramController.updateSendStatus(subId, datagramType,
+ SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS,
+ getPendingMessagesCount(), SATELLITE_RESULT_SUCCESS);
if (datagramType == DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS) {
startMtSmsPollingThrottle();
}
} else {
+ // Update send status
mDatagramController.updateSendStatus(subId, datagramType,
SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
getPendingMessagesCount(), SATELLITE_RESULT_NETWORK_ERROR);
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 762649a..c6383a6 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -35,7 +35,6 @@
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_NIDD_APN_NAME_STRING;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
@@ -43,6 +42,7 @@
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY;
import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS;
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
@@ -134,6 +134,7 @@
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
@@ -193,7 +194,6 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.stream.Collectors;
-import com.android.internal.R;
/**
* Satellite controller is the backend service of
@@ -304,6 +304,7 @@
private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 57;
private static final int CMD_UPDATE_SYSTEM_SELECTION_CHANNELS = 58;
private static final int EVENT_UPDATE_SYSTEM_SELECTION_CHANNELS_DONE = 59;
+ private static final int EVENT_SELECTED_NB_IOT_SATELLITE_SUBSCRIPTION_CHANGED = 60;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -428,9 +429,16 @@
*/
private final ConcurrentHashMap<IBinder, ISatelliteModemStateCallback>
mTerrestrialNetworkAvailableChangedListeners = new ConcurrentHashMap<>();
- private final Object mIsSatelliteSupportedLock = new Object();
+ /**
+ * Map key: binder of the callback, value: callback to receive selected NB IOT satellite
+ * subscription changed
+ */
+ private final ConcurrentHashMap<IBinder, ISelectedNbIotSatelliteSubscriptionCallback>
+ mSelectedNbIotSatelliteSubscriptionChangedListeners = new ConcurrentHashMap<>();
+
+ protected final Object mIsSatelliteSupportedLock = new Object();
@GuardedBy("mIsSatelliteSupportedLock")
- private Boolean mIsSatelliteSupported = null;
+ protected Boolean mIsSatelliteSupported = null;
private boolean mIsDemoModeEnabled = false;
private boolean mIsEmergency = false;
private final Object mIsSatelliteEnabledLock = new Object();
@@ -569,6 +577,9 @@
* carrierPlmnList. */
@GuardedBy("mSupportedSatelliteServicesLock")
private final SparseArray<List<String>> mMergedPlmnListPerCarrier = new SparseArray<>();
+ /** Key Subscription ID, value : map to plmn info with related data plan. */
+ @GuardedBy("mSupportedSatelliteServicesLock")
+ SparseArray<Map<String, Integer>> mEntitlementDataPlanMapPerCarrier = new SparseArray<>();
private static AtomicLong sNextSatelliteEnableRequestId = new AtomicLong(0);
// key : subscriberId, value : provisioned or not.
@GuardedBy("mSatelliteTokenProvisionedLock")
@@ -649,6 +660,15 @@
private final Object mNtnSmsSupportedByMessagesAppLock = new Object();
@GuardedBy("mNtnSmsSupportedByMessagesAppLock")
private Boolean mNtnSmsSupportedByMessagesApp = null;
+
+ private final Object mSatelliteModemStateLock = new Object();
+ @GuardedBy("mSatelliteModemStateLock")
+ @SatelliteManager.SatelliteModemState
+ private int mSatelliteModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
+
+ // Data Plan types at entitlement for the plmn allowed
+ public static final int SATELLITE_DATA_PLAN_METERED = 0;
+ public static final int SATELLITE_DATA_PLAN_UNMETERED = 1;
private BroadcastReceiver
mDefaultSmsSubscriptionChangedBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -718,12 +738,13 @@
* (e.g., class name and method name)
*/
public void incrementResultReceiverCount(String caller) {
- if (mFeatureFlags.geofenceEnhancementForBetterUx()) {
+ if (mFeatureFlags.carrierRoamingNbIotNtn()) {
synchronized (mResultReceiverTotalCountLock) {
mResultReceiverTotalCount++;
logd("[incrementResultReceiverCount] : " + caller
+ " | ResultReceiver total count= " + mResultReceiverTotalCount);
- mResultReceiverCountPerMethodMap.compute(caller, (k, v) -> v == null ? 1 : v + 1);
+ mResultReceiverCountPerMethodMap.compute(caller,
+ (k, v) -> v == null ? 1 : v + 1);
if (mResultReceiverTotalCount > RESULT_RECEIVER_COUNT_ANOMALY_THRESHOLD) {
loge("[mResultReceiverTotalCount] is exceeds limits : "
@@ -737,7 +758,7 @@
}
}
} else {
- logd("[incrementResultReceiverCount]: geofenceEnhancementForBetterUx is not enabled");
+ logd("[incrementResultReceiverCount]: carrierRoamingNbIotNtn is not enabled");
}
}
@@ -749,7 +770,7 @@
* (e.g., class name and method name)
*/
public void decrementResultReceiverCount(String caller) {
- if (mFeatureFlags.geofenceEnhancementForBetterUx()) {
+ if (mFeatureFlags.carrierRoamingNbIotNtn()) {
synchronized (mResultReceiverTotalCountLock) {
if (mResultReceiverTotalCount > 0) {
mResultReceiverTotalCount--;
@@ -760,7 +781,7 @@
(k, v) -> v > 0 ? v - 1 : v);
}
} else {
- logd("[decrementResultReceiverCount]: geofenceEnhancementForBetterUx is not enabled");
+ logd("[decrementResultReceiverCount]: carrierRoamingNbIotNtn is not enabled");
}
}
@@ -1231,12 +1252,13 @@
}
private static final class UpdateSystemSelectionChannelsArgument {
- @NonNull SystemSelectionSpecifier mSelectionSpecifier;
+ @NonNull List<SystemSelectionSpecifier> mSystemSelectionSpecifiers;
@NonNull ResultReceiver mResult;
- UpdateSystemSelectionChannelsArgument(@NonNull SystemSelectionSpecifier selectionSpecifier,
+ UpdateSystemSelectionChannelsArgument(
+ @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifiers,
@NonNull ResultReceiver result) {
- this.mSelectionSpecifier = selectionSpecifier;
+ this.mSystemSelectionSpecifiers = systemSelectionSpecifiers;
this.mResult = result;
}
}
@@ -2068,7 +2090,7 @@
onCompleted = obtainMessage(EVENT_UPDATE_SYSTEM_SELECTION_CHANNELS_DONE, request);
mSatelliteModemInterface.updateSystemSelectionChannels(
((UpdateSystemSelectionChannelsArgument) (request.argument))
- .mSelectionSpecifier,
+ .mSystemSelectionSpecifiers,
onCompleted);
break;
}
@@ -2084,6 +2106,16 @@
break;
}
+ case EVENT_SELECTED_NB_IOT_SATELLITE_SUBSCRIPTION_CHANGED: {
+ ar = (AsyncResult) msg.obj;
+ if (ar.result == null) {
+ loge("EVENT_SELECTED_NB_IOT_SATELLITE_SUBSCRIPTION_CHANGED: result is null");
+ } else {
+ handleEventSelectedNbIotSatelliteSubscriptionChanged((int) ar.result);
+ }
+ break;
+ }
+
default:
Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
msg.what);
@@ -3299,6 +3331,59 @@
}
/**
+ * Registers for selected satellite subscription changed event.
+ *
+ * @param callback The callback to handle the selected satellite subscription changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ */
+ @SatelliteManager.SatelliteResult
+ public int registerForSelectedNbIotSatelliteSubscriptionChanged(
+ @NonNull ISelectedNbIotSatelliteSubscriptionCallback callback) {
+ if (DBG) plogd("registerForSelectedNbIotSatelliteSubscriptionChanged()");
+
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("carrierRoamingNbIotNtn flag is disabled");
+ return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+ }
+
+ int error = evaluateOemSatelliteRequestAllowed(false);
+ if (error != SATELLITE_RESULT_SUCCESS) return error;
+
+ mSelectedNbIotSatelliteSubscriptionChangedListeners.put(callback.asBinder(), callback);
+ try {
+ callback.onSelectedNbIotSatelliteSubscriptionChanged(getSelectedSatelliteSubId());
+ } catch (RemoteException ex) {
+ ploge("registerForSelectedNbIotSatelliteSubscriptionChanged: RemoteException ex="
+ + ex);
+ }
+ return SATELLITE_RESULT_SUCCESS;
+ }
+
+ /**
+ * Unregisters for the selected satellite subscription changed event.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param callback The callback that was passed to {@link
+ * #registerForSelectedNbIotSatelliteSubscriptionChanged(
+ * ISelectedNbIotSatelliteSubscriptionCallback)}.
+ */
+ public void unregisterForSelectedNbIotSatelliteSubscriptionChanged(
+ @NonNull ISelectedNbIotSatelliteSubscriptionCallback callback) {
+ if (DBG) plogd("unregisterForSelectedNbIotSatelliteSubscriptionChanged()");
+
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("carrierRoamingNbIotNtn flag is disabled");
+ return;
+ }
+
+ int error = evaluateOemSatelliteRequestAllowed(true);
+ if (error == SATELLITE_RESULT_SUCCESS) {
+ mSelectedNbIotSatelliteSubscriptionChangedListeners.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.
@@ -4124,6 +4209,7 @@
*/
public void onSatelliteEntitlementStatusUpdated(int subId, boolean entitlementEnabled,
@Nullable List<String> allowedPlmnList, @Nullable List<String> barredPlmnList,
+ @Nullable Map<String,Integer> plmnDataPlanMap,
@Nullable IIntegerConsumer callback) {
if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
logd("onSatelliteEntitlementStatusUpdated: carrierEnabledSatelliteFlag is not enabled");
@@ -4144,6 +4230,9 @@
if (barredPlmnList == null) {
barredPlmnList = new ArrayList<>();
}
+ if (plmnDataPlanMap == null) {
+ plmnDataPlanMap = new HashMap<>();
+ }
logd("onSatelliteEntitlementStatusUpdated subId=" + subId + ", entitlementEnabled="
+ entitlementEnabled + ", allowedPlmnList=["
+ String.join(",", allowedPlmnList) + "]" + ", barredPlmnList=["
@@ -4172,6 +4261,7 @@
mMergedPlmnListPerCarrier.remove(subId);
mEntitlementPlmnListPerCarrier.put(subId, allowedPlmnList);
mEntitlementBarredPlmnListPerCarrier.put(subId, barredPlmnList);
+ mEntitlementDataPlanMapPerCarrier.put(subId, plmnDataPlanMap);
updatePlmnListPerCarrier(subId);
configureSatellitePlmnForCarrier(subId);
mSubscriptionManagerService.setSatelliteEntitlementPlmnList(subId, allowedPlmnList);
@@ -4699,6 +4789,11 @@
private void handleEventSatelliteModemStateChanged(
@SatelliteManager.SatelliteModemState int state) {
plogd("handleEventSatelliteModemStateChanged: state=" + state);
+
+ synchronized (mSatelliteModemStateLock) {
+ mSatelliteModemState = state;
+ }
+
if (state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
|| state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
if (!isWaitingForDisableSatelliteModemResponse()) {
@@ -4830,6 +4925,29 @@
}
}
+ private void handleEventSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("handleEventSelectedNbIotSatelliteSubscriptionChanged: "
+ + "carrierRoamingNbIotNtn flag is disabled");
+ return;
+ }
+
+ plogd("handleEventSelectedNbIotSatelliteSubscriptionChanged: " + selectedSubId);
+
+ List<ISelectedNbIotSatelliteSubscriptionCallback> deadCallersList = new ArrayList<>();
+ mSelectedNbIotSatelliteSubscriptionChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSelectedNbIotSatelliteSubscriptionChanged(selectedSubId);
+ } catch (RemoteException e) {
+ logd("handleEventSelectedNbIotSatelliteSubscriptionChanged RemoteException: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSelectedNbIotSatelliteSubscriptionChangedListeners.remove(listener.asBinder());
+ });
+ }
+
private void notifySatelliteSupportedStateChanged(boolean supported) {
List<ISatelliteSupportedStateCallback> deadCallersList = new ArrayList<>();
mSatelliteSupportedStateChangedListeners.values().forEach(listener -> {
@@ -5382,7 +5500,7 @@
/** If the provision state per subscriberId for the cached is not exist, check the database for
* the corresponding value and use it. */
- private void updateSatelliteProvisionedStatePerSubscriberId() {
+ protected void updateSatelliteProvisionedStatePerSubscriberId() {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
return;
}
@@ -5460,7 +5578,7 @@
KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL);
}
- private int getCarrierRoamingNtnConnectType(int subId) {
+ public int getCarrierRoamingNtnConnectType(int subId) {
return getConfigForSubId(subId).getInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT);
}
@@ -6373,6 +6491,23 @@
updateSatelliteSystemNotification(-1, -1,/*visible*/ false);
}
+ public boolean isSatelliteSystemNotificationsEnabled(int carrierRoamingNtnConnectType) {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ return false;
+ }
+ if (carrierRoamingNtnConnectType
+ != CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL) {
+ return true;
+ }
+ boolean notifySatelliteAvailabilityEnabled =
+ mContext.getResources().getBoolean(R.bool.config_satellite_should_notify_availability);
+ Boolean isSatelliteSupported = getIsSatelliteSupported();
+ if(isSatelliteSupported == null) {
+ return false;
+ }
+ return notifySatelliteAvailabilityEnabled && isSatelliteSupported;
+ }
+
/**
* Update the system notification to reflect the current satellite status, that's either already
* connected OR needs to be manually enabled. The device should only display one notification
@@ -6386,9 +6521,7 @@
*/
private void updateSatelliteSystemNotification(int subId,
@CARRIER_ROAMING_NTN_CONNECT_TYPE int carrierRoamingNtnConnectType, boolean visible) {
- boolean notifySatelliteAvailabilityEnabled =
- mContext.getResources().getBoolean(R.bool.config_satellite_should_notify_availability);
- if (!mFeatureFlags.carrierRoamingNbIotNtn() || !notifySatelliteAvailabilityEnabled) {
+ if (!isSatelliteSystemNotificationsEnabled(carrierRoamingNtnConnectType)) {
plogd("updateSatelliteSystemNotification: satellite notifications are not enabled.");
return;
}
@@ -7107,7 +7240,7 @@
+ ", provisioned=" + provisioned);
list.add(new SatelliteSubscriberProvisionStatus.Builder()
.setSatelliteSubscriberInfo(satelliteSubscriberInfo)
- .setProvisionStatus(provisioned).build());
+ .setProvisioned(provisioned).build());
mSubscriberIdPerSub.put(subscriberId, info.getSubscriptionId());
}
}
@@ -7163,7 +7296,7 @@
// TODO: need to check if satellite is allowed at current location for the subscription
int subId = getSubIdFromSubscriberId(
status.getSatelliteSubscriberInfo().getSubscriberId());
- if (status.getProvisionStatus() && isActiveSubId(subId)) {
+ if (status.isProvisioned() && isActiveSubId(subId)) {
selectedSubId = subId;
break;
}
@@ -7179,6 +7312,7 @@
}
setSatellitePhone(selectedSubId);
plogd("selectBindingSatelliteSubscription: SelectedSatelliteSubId=" + selectedSubId);
+ handleEventSelectedNbIotSatelliteSubscriptionChanged(selectedSubId);
}
private int getSubIdFromSubscriberId(String subscriberId) {
@@ -7249,7 +7383,8 @@
* @param result The result receiver that returns if the request is successful or
* an error code if the request failed.
*/
- public void updateSystemSelectionChannels(@NonNull SystemSelectionSpecifier selectionSpecifier,
+ public void updateSystemSelectionChannels(
+ @NonNull List<SystemSelectionSpecifier> selectionSpecifiers,
@NonNull ResultReceiver result) {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
plogd("updateSystemSelectionChannels: "
@@ -7259,7 +7394,7 @@
}
sendRequestAsync(CMD_UPDATE_SYSTEM_SELECTION_CHANNELS,
- new UpdateSystemSelectionChannelsArgument(selectionSpecifier, result), null);
+ new UpdateSystemSelectionChannelsArgument(selectionSpecifiers, result), null);
}
/**
@@ -7996,7 +8131,7 @@
NTN_SIGNAL_STRENGTH_NONE);
if (isInCarrierRoamingNbIotNtn(phone)) {
- if (mSatelliteSessionController.isInConnectedState()) {
+ if (isInConnectedState()) {
synchronized (mNtnSignalsStrengthLock) {
carrierRoamingNtnSignalStrength = mNtnSignalStrength;
}
@@ -8016,6 +8151,20 @@
return carrierRoamingNtnSignalStrength;
}
+ private boolean isInConnectedState() {
+ synchronized (mSatelliteModemStateLock) {
+ switch (mSatelliteModemState) {
+ case SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED:
+ case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
+ plogd("isInConnectedState: return true");
+ return true;
+ default:
+ plogd("isInConnectedState: return false");
+ return false;
+ }
+ }
+ }
+
protected void updateLastNotifiedCarrierRoamingNtnSignalStrengthAndNotify(
@Nullable Phone phone) {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) return;
@@ -8038,16 +8187,21 @@
/** Returns whether to send SMS to DatagramDispatcher or not. */
public boolean shouldSendSmsToDatagramDispatcher(@Nullable Phone phone) {
- if (!isInCarrierRoamingNbIotNtn(phone)) {
- return false;
- }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (!isInCarrierRoamingNbIotNtn(phone)) {
+ return false;
+ }
- if (isDemoModeEnabled()) {
- return false;
- }
+ if (isDemoModeEnabled()) {
+ return false;
+ }
- int[] services = getSupportedServicesOnCarrierRoamingNtn(phone.getSubId());
- return ArrayUtils.contains(services, NetworkRegistrationInfo.SERVICE_TYPE_SMS);
+ int[] services = getSupportedServicesOnCarrierRoamingNtn(phone.getSubId());
+ return ArrayUtils.contains(services, NetworkRegistrationInfo.SERVICE_TYPE_SMS);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private boolean isWaitingForSatelliteModemOff() {
@@ -8136,4 +8290,28 @@
return mWifiStateEnabled;
}
}
+
+ /**
+ * Method to return the current data plan for the registered plmn based on entitlement
+ * provisioning information. Note: If no information at
+ * provisioning is supported this is overridden with operator carrier config information.
+ *
+ * @param subId current subscription id
+ * @param plmn current registered plmn information
+ *
+ * @return Data supported modes {@link SatelliteController#SATELLITE_DATA_PLAN_METERED}
+ */
+ public int getSatelliteDataPlanForPlmn(int subId, String plmn) {
+ if (plmn != null) {
+ synchronized (mSupportedSatelliteServicesLock) {
+ Map<String, Integer> dataplanMap = mEntitlementDataPlanMapPerCarrier.get(subId);
+ logd("data plan available for sub id:" + dataplanMap);
+ if (dataplanMap != null && dataplanMap.containsKey(plmn)) {
+ return dataplanMap.get(plmn);
+ }
+ }
+ }
+ // TODO (Override with carrier config value when configuration defined)
+ return SATELLITE_DATA_PLAN_METERED;
+ }
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index 6f88f59..5b032e6 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -1387,18 +1387,18 @@
/**
* Request to update system selection channels
*
- * @param systemSelectionSpecifier system selection specifiers
+ * @param systemSelectionSpecifiers system selection specifiers
* @param message The Message to send to result of the operation to.
*/
public void updateSystemSelectionChannels(
- @NonNull SystemSelectionSpecifier systemSelectionSpecifier,
+ @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifiers,
@Nullable Message message) {
plogd("updateSystemSelectionChannels: SystemSelectionSpecifier: "
- + systemSelectionSpecifier.toString());
+ + systemSelectionSpecifiers.toString());
if (mSatelliteService != null) {
try {
mSatelliteService.updateSystemSelectionChannels(SatelliteServiceUtils
- .toSystemSelectionSpecifier(systemSelectionSpecifier),
+ .toSystemSelectionSpecifier(systemSelectionSpecifiers),
new IIntegerConsumer.Stub() {
@Override
public void accept(int result) {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 182f667..64bd2b7 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -24,6 +24,9 @@
import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT;
import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP;
import static com.android.internal.telephony.flags.Flags.satellitePersistentLogging;
import static com.android.internal.telephony.satellite.SatelliteController.INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
@@ -262,6 +265,26 @@
return SmsApplication.getDefaultSendToApplication(mContext, false);
}
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected boolean updateAndGetProvisionState() {
+ mSatelliteController.updateSatelliteProvisionedStatePerSubscriberId();
+ return isDeviceProvisioned();
+ }
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected boolean isSatelliteAllowedByReasons() {
+ SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
+ List<Integer> disallowedReasons = satelliteManager.getSatelliteDisallowedReasons();
+ if (disallowedReasons.stream().anyMatch(r ->
+ (r == SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP
+ || r == SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED
+ || r == SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED))) {
+ plogd("isAllowedForDefaultMessageApp:false, disallowedReasons=" + disallowedReasons);
+ return false;
+ }
+ return true;
+ }
+
private void handleEmergencyCallStartedEvent(@NonNull Connection connection) {
plogd("handleEmergencyCallStartedEvent: connection=" + connection);
mSatelliteController.setLastEmergencyCallTime();
@@ -284,7 +307,8 @@
}
private void handleSatelliteProvisionStateChangedEvent(boolean provisioned) {
- if (!provisioned) {
+ if (!provisioned
+ && !isSatelliteConnectedViaCarrierWithinHysteresisTime()) {
cleanUpResources(false);
}
}
@@ -310,6 +334,8 @@
return;
}
+ updateAndGetProvisionState();
+
/*
* The device might be connected to satellite after the emergency call started. Thus, we
* need to do this check again so that we will have higher chance of sending the event
@@ -321,7 +347,7 @@
boolean isCellularAvailable = SatelliteServiceUtils.isCellularAvailable();
if (!isCellularAvailable
&& isSatelliteAllowed()
- && (isDeviceProvisioned()
+ && ((isDeviceProvisioned() && isSatelliteAllowedByReasons())
|| isSatelliteConnectedViaCarrierWithinHysteresisTime())
&& shouldTrackCall(mEmergencyConnection.getState())) {
plogd("handleTimeoutEvent: Sent EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer");
@@ -737,7 +763,9 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public int getEmergencyCallToSatelliteHandoverType() {
- if (Flags.carrierRoamingNbIotNtn() && isDeviceProvisioned()
+ if (Flags.carrierRoamingNbIotNtn()
+ && isDeviceProvisioned()
+ && isSatelliteAllowedByReasons()
&& isSatelliteConnectedViaCarrierWithinHysteresisTime()) {
int satelliteSubId = mSatelliteController.getSelectedSatelliteSubId();
return mSatelliteController.getCarrierRoamingNtnEmergencyCallToSatelliteHandoverType(
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
index 9217ba1..b55c622 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -36,10 +36,12 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.EarfcnRange;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.PointingInfo;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteModemEnableRequestAttributes;
import android.telephony.satellite.SatelliteSubscriptionInfo;
@@ -54,7 +56,6 @@
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.TelephonyUtils;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -544,24 +545,68 @@
return mcc + mnc;
}
+ @NonNull
+ private static android.telephony.satellite.stub
+ .SystemSelectionSpecifier convertSystemSelectionSpecifierToHALFormat(
+ @NonNull SystemSelectionSpecifier systemSelectionSpecifier) {
+ android.telephony.satellite.stub.SystemSelectionSpecifier convertedSpecifier =
+ new android.telephony.satellite.stub.SystemSelectionSpecifier();
+
+ convertedSpecifier.mMccMnc = systemSelectionSpecifier.getMccMnc();
+ convertedSpecifier.mBands = systemSelectionSpecifier.getBands();
+ convertedSpecifier.mEarfcs = systemSelectionSpecifier.getEarfcns();
+ SatelliteInfo[] satelliteInfos = systemSelectionSpecifier.getSatelliteInfos()
+ .toArray(new SatelliteInfo[0]);
+ android.telephony.satellite.stub.SatelliteInfo[] halSatelliteInfos =
+ new android.telephony.satellite.stub.SatelliteInfo[satelliteInfos.length];
+ for (int i = 0; i < satelliteInfos.length; i++) {
+ halSatelliteInfos[i] = new android.telephony.satellite.stub.SatelliteInfo();
+
+ halSatelliteInfos[i].id = new android.telephony.satellite.stub.UUID();
+ halSatelliteInfos[i].id.mostSigBits =
+ satelliteInfos[i].getSatelliteId().getMostSignificantBits();
+ halSatelliteInfos[i].id.leastSigBits =
+ satelliteInfos[i].getSatelliteId().getLeastSignificantBits();
+
+ halSatelliteInfos[i].position =
+ new android.telephony.satellite.stub.SatellitePosition();
+ halSatelliteInfos[i].position.longitudeDegree =
+ satelliteInfos[i].getSatellitePosition().getLongitudeDegrees();
+ halSatelliteInfos[i].position.altitudeKm =
+ satelliteInfos[i].getSatellitePosition().getAltitudeKm();
+
+ halSatelliteInfos[i].bands = satelliteInfos[i].getBands().stream().mapToInt(
+ Integer::intValue).toArray();
+
+ List<EarfcnRange> earfcnRangeList = satelliteInfos[i].getEarfcnRanges();
+ halSatelliteInfos[i].earfcnRanges =
+ new android.telephony.satellite.stub.EarfcnRange[earfcnRangeList.size()];
+ for (int j = 0; j < earfcnRangeList.size(); j++) {
+ halSatelliteInfos[i].earfcnRanges[j] =
+ new android.telephony.satellite.stub.EarfcnRange();
+ halSatelliteInfos[i].earfcnRanges[j].startEarfcn = earfcnRangeList.get(
+ j).getStartEarfcn();
+ halSatelliteInfos[i].earfcnRanges[j].endEarfcn = earfcnRangeList.get(
+ j).getEndEarfcn();
+ }
+ }
+ convertedSpecifier.satelliteInfos = halSatelliteInfos;
+ convertedSpecifier.tagIds = systemSelectionSpecifier.getTagIds();
+ return convertedSpecifier;
+ }
+
/**
* Convert SystemSelectionSpecifier from framework definition to service definition
* @param systemSelectionSpecifier The SystemSelectionSpecifier from the framework.
* @return The converted SystemSelectionSpecifier for the satellite service.
*/
- @NonNull public static List<android.telephony.satellite.stub
+ @NonNull
+ public static List<android.telephony.satellite.stub
.SystemSelectionSpecifier> toSystemSelectionSpecifier(
- @NonNull SystemSelectionSpecifier systemSelectionSpecifier) {
- List<android.telephony.satellite.stub.SystemSelectionSpecifier> converted =
- new ArrayList<>();
- android.telephony.satellite.stub.SystemSelectionSpecifier convertedSpecifier =
- new android.telephony.satellite.stub.SystemSelectionSpecifier();
-
- convertedSpecifier.mMccMnc = systemSelectionSpecifier.getMccMnc();
- convertedSpecifier.mBands = systemSelectionSpecifier.getBands().toArray();
- convertedSpecifier.mEarfcs = systemSelectionSpecifier.getEarfcs().toArray();
- converted.add(convertedSpecifier);
- return converted;
+ @NonNull List<SystemSelectionSpecifier> systemSelectionSpecifier) {
+ return systemSelectionSpecifier.stream().map(
+ SatelliteServiceUtils::convertSystemSelectionSpecifierToHALFormat).collect(
+ Collectors.toList());
}
/**
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index d1d03a0..b2861d3 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -68,7 +68,6 @@
import android.util.Log;
import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.DeviceStateMonitor;
import com.android.internal.telephony.ExponentialBackoff;
@@ -586,17 +585,6 @@
}
/**
- * Get whether state machine is in connected state.
- *
- * @return {@code true} if state machine is in connected state and {@code false} otherwise.
- */
- public boolean isInConnectedState() {
- if (DBG) plogd("isInConnectedState: getCurrentState=" + getCurrentState());
- return getCurrentState() == mConnectedState;
- }
-
-
- /**
* Release all resource.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
index 2ae8f9d..0a82b99 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
@@ -18,6 +18,7 @@
import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
+import static android.telephony.satellite.SatelliteManager.KEY_SESSION_STATS_V2;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
import android.annotation.NonNull;
@@ -61,9 +62,11 @@
private int mCountOfSatelliteNotificationDisplayed;
private int mCountOfAutoExitDueToScreenOff;
private int mCountOfAutoExitDueToTnNetwork;
+ private SatelliteSessionStats datagramStats;
private SessionMetricsStats() {
initializeSessionMetricsParam();
+ datagramStats = new SatelliteSessionStats();
}
/**
@@ -128,7 +131,9 @@
/** Increase the count of successful outgoing datagram transmission. */
public SessionMetricsStats addCountOfSuccessfulOutgoingDatagram(
- @NonNull @SatelliteManager.DatagramType int datagramType) {
+ @NonNull @SatelliteManager.DatagramType int datagramType,
+ long datagramTransmissionTime) {
+ datagramStats.recordSuccessfulOutgoingDatagramStats(datagramType, datagramTransmissionTime);
if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
// Ignore KEEP_ALIVE messages
return this;
@@ -145,6 +150,7 @@
public SessionMetricsStats addCountOfFailedOutgoingDatagram(
@NonNull @SatelliteManager.DatagramType int datagramType,
@NonNull @SatelliteManager.SatelliteResult int resultCode) {
+ datagramStats.addCountOfUnsuccessfulUserMessages(datagramType, resultCode);
if (datagramType == SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE) {
// Ignore KEEP_ALIVE messages
return this;
@@ -284,6 +290,7 @@
/** Returns {@link SatelliteSessionStats} of the satellite service. */
public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) {
+ Log.i(TAG, "requestSatelliteSessionStats called");
Bundle bundle = new Bundle();
SatelliteSessionStats sessionStats = new SatelliteSessionStats.Builder()
.setCountOfSuccessfulUserMessages(mShadowCountOfSuccessfulOutgoingDatagram)
@@ -296,6 +303,10 @@
DatagramDispatcher.getInstance().getPendingUserMessagesCount())
.build();
bundle.putParcelable(SatelliteManager.KEY_SESSION_STATS, sessionStats);
+
+ // TODO b/381007377 should retrieve MessagesInQueueToBeSent count per messageType and add
+ // to datagramStats
+ bundle.putParcelable(KEY_SESSION_STATS_V2, datagramStats);
result.send(SATELLITE_RESULT_SUCCESS, bundle);
}
@@ -310,9 +321,9 @@
}
private void initializeSessionMetricsParam() {
- mInitializationResult = SatelliteManager.SATELLITE_RESULT_SUCCESS;
+ mInitializationResult = SATELLITE_RESULT_SUCCESS;
mRadioTechnology = SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN;
- mTerminationResult = SatelliteManager.SATELLITE_RESULT_SUCCESS;
+ mTerminationResult = SATELLITE_RESULT_SUCCESS;
mInitializationProcessingTimeMillis = 0;
mTerminationProcessingTimeMillis = 0;
mSessionDurationSec = 0;
@@ -336,6 +347,7 @@
mShadowCountOfFailedOutgoingDatagram = 0;
mShadowCountOfTimedOutUserMessagesWaitingForConnection = 0;
mShadowCountOfTimedOutUserMessagesWaitingForAck = 0;
+ datagramStats.clear();
}
private static void logd(@NonNull String log) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 5dc4719..f934371 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -138,7 +138,7 @@
private long mCallbackModeDurationMillis;
private boolean mCarrierRoamingNtnMode;
private boolean mCarrierRoamingNtnEligible;
- private List<Integer> mCarrierRoamingNtnAvailableServices;
+ private int[] mCarrierRoamingNtnAvailableServices;
private NtnSignalStrength mCarrierRoamingNtnSignalStrength;
private boolean mIsSatelliteEnabled;
@@ -354,7 +354,7 @@
}
@Override
- public void onCarrierRoamingNtnAvailableServicesChanged(List<Integer> services) {
+ public void onCarrierRoamingNtnAvailableServicesChanged(int[] services) {
invocationCount.incrementAndGet();
mCarrierRoamingNtnAvailableServices = services;
}
@@ -1768,9 +1768,7 @@
int[] services = {3, 6};
mTelephonyRegistry.notifyCarrierRoamingNtnAvailableServicesChanged(subId, services);
processAllMessages();
- int[] carrierServices = mCarrierRoamingNtnAvailableServices.stream()
- .mapToInt(Integer::intValue).toArray();
- assertTrue(Arrays.equals(carrierServices, services));
+ assertTrue(Arrays.equals(mCarrierRoamingNtnAvailableServices, services));
}
@Test
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 ee713c6..4cc10d9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -888,11 +888,8 @@
doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
doReturn(new SubscriptionInfoInternal.Builder().setId(1).build())
.when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
-
doReturn(true).when(mFeatureFlags).carrierEnabledSatelliteFlag();
doReturn(true).when(mFeatureFlags).satelliteInternet();
- doReturn(true).when(mFeatureFlags).simDisabledGracefulTearDown();
-
when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
doReturn(true).when(mMockPackageManager).hasSystemFeature(anyString());
@@ -4311,7 +4308,7 @@
}
@Test
- public void testImsGracefulTearDownSimRemoval() throws Exception {
+ public void testImsGracefulTearDown() throws Exception {
setImsRegistered(true);
setRcsRegistered(true);
@@ -4357,52 +4354,6 @@
}
@Test
- public void testImsGracefulTearDownSimDisabled() throws Exception {
- setImsRegistered(true);
- setRcsRegistered(true);
-
- NetworkCapabilities netCaps = new NetworkCapabilities();
- netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
- netCaps.maybeMarkCapabilitiesRestricted();
- netCaps.setRequestorPackageName(FAKE_MMTEL_PACKAGE);
-
- NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
- ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
- TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
- nativeNetworkRequest, mPhone, mFeatureFlags);
-
- mDataNetworkControllerUT.addNetworkRequest(networkRequest);
-
- processAllMessages();
- Mockito.clearInvocations(mPhone);
-
- // SIM disabled
- mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
- TelephonyManager.SIM_STATE_NOT_READY, 0).sendToTarget();
- processAllMessages();
-
- // Make sure data network enters disconnecting state
- ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
- ArgumentCaptor.forClass(PreciseDataConnectionState.class);
- verify(mPhone).notifyDataConnection(pdcsCaptor.capture());
- PreciseDataConnectionState pdcs = pdcsCaptor.getValue();
- assertThat(pdcs.getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTING);
-
- // IMS de-registered. Now data network is safe to be torn down.
- Mockito.clearInvocations(mPhone);
- setImsRegistered(false);
- setRcsRegistered(false);
- processAllMessages();
-
- // All data should be disconnected.
- verifyAllDataDisconnected();
- verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
- verify(mPhone).notifyDataConnection(pdcsCaptor.capture());
- pdcs = pdcsCaptor.getValue();
- assertThat(pdcs.getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTED);
- }
-
- @Test
public void testNoGracefulTearDownForEmergencyDataNetwork() throws Exception {
setImsRegistered(true);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramControllerTest.java
index 21731f0..271e0ad 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramControllerTest.java
@@ -16,10 +16,12 @@
package com.android.internal.telephony.satellite;
+import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_KEEP_ALIVE;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING;
+import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SMS;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE;
import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN;
import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
@@ -44,6 +46,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import com.android.internal.R;
import com.android.internal.telephony.TelephonyTest;
import org.junit.After;
@@ -187,6 +190,76 @@
}
}
+ @Test
+ public void testNeedsWaitingForSatelliteConnected_checkMessageInNotConnected_returnsFalse()
+ throws Exception {
+ when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ mContextFixture.putBooleanResource(
+ R.bool.config_satellite_allow_check_message_in_not_connected, true);
+ mDatagramControllerUT.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+ boolean result =
+ mDatagramControllerUT.needsWaitingForSatelliteConnected(
+ DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS);
+
+ assertFalse(result);
+ }
+
+ @Test
+ public void testNeedsWaitingForSatelliteConnected_regularSmsInNotConnected_returnsTrue()
+ throws Exception {
+ when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ mContextFixture.putBooleanResource(
+ R.bool.config_satellite_allow_check_message_in_not_connected, true);
+ mDatagramControllerUT.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+ boolean result =
+ mDatagramControllerUT.needsWaitingForSatelliteConnected(
+ DATAGRAM_TYPE_SMS);
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void
+ testNeedsWaitingForSatelliteConnected_checkMessageInNotConnected_allowCheckMessageFalse_returnsTrue()
+ throws Exception {
+ when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ mContextFixture.putBooleanResource(
+ R.bool.config_satellite_allow_check_message_in_not_connected, false);
+ mDatagramControllerUT.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+ boolean result =
+ mDatagramControllerUT.needsWaitingForSatelliteConnected(
+ DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS);
+
+ assertTrue(result);
+ }
+
+ @Test
+ public void
+ testNeedsWaitingForSatelliteConnected_checkMessageInNotConnected_carrierRoamingNbIotNtnFalse_returnsTrue()
+ throws Exception {
+ when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(false);
+ mContextFixture.putBooleanResource(
+ R.bool.config_satellite_allow_check_message_in_not_connected, true);
+ mDatagramControllerUT.onSatelliteModemStateChanged(
+ SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+ boolean result =
+ mDatagramControllerUT.needsWaitingForSatelliteConnected(
+ DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS);
+
+ assertTrue(result);
+ }
+
private void testUpdateSendStatus(boolean isDemoMode, int datagramType, int sendState) {
mDatagramControllerUT.setDemoMode(isDemoMode);
clearAllInvocations();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
index 1941518..dc973af 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -31,6 +31,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
@@ -257,7 +258,7 @@
eq(SATELLITE_RESULT_SUCCESS));
verifyNoMoreInteractions(mMockDatagramController);
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(eq(datagramType));
+ .addCountOfSuccessfulOutgoingDatagram(eq(datagramType), anyLong());
verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
assertFalse(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
@@ -398,7 +399,7 @@
any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_SUCCESS);
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(anyInt());
+ .addCountOfSuccessfulOutgoingDatagram(anyInt(), anyLong());
clearInvocations(mMockSatelliteModemInterface);
clearInvocations(mMockDatagramController);
clearInvocations(mMockSessionMetricsStats);
@@ -523,7 +524,7 @@
eq(SATELLITE_RESULT_SUCCESS));
assertThat(mResultListener.peek()).isEqualTo(SATELLITE_RESULT_SUCCESS);
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(eq(datagramType));
+ .addCountOfSuccessfulOutgoingDatagram(eq(datagramType), anyLong());
mDatagramDispatcherUT.setDemoMode(false);
mDatagramDispatcherUT.setDeviceAlignedWithSatellite(false);
}
@@ -618,7 +619,7 @@
eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(eq(DATAGRAM_TYPE2));
+ .addCountOfSuccessfulOutgoingDatagram(eq(DATAGRAM_TYPE2), anyLong());
mDatagramDispatcherUT.setDemoMode(false);
mDatagramDispatcherUT.setDeviceAlignedWithSatellite(false);
@@ -731,7 +732,7 @@
anyInt(), any(SatelliteDatagram.class));
verify(mMockDatagramController).pollPendingSatelliteDatagrams(anyInt(), any());
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(anyInt());
+ .addCountOfSuccessfulOutgoingDatagram(anyInt(), anyLong());
// Test when overlay config config_send_satellite_datagram_to_modem_in_demo_mode is
// false
@@ -824,8 +825,7 @@
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSmsDispatchersController).sendCarrierRoamingNbIotNtnText(eq(mPendingSms));
- mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId,
- true, true);
+ mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId, true);
processAllMessages();
mInOrder.verify(mMockDatagramController)
@@ -859,8 +859,7 @@
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSmsDispatchersController).sendCarrierRoamingNbIotNtnText(eq(mPendingSms));
- mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId,
- true, false);
+ mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId, false);
processAllMessages();
mInOrder.verify(mMockDatagramController)
@@ -1043,7 +1042,7 @@
eq(1),
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(eq(datagramTypeSos));
+ .addCountOfSuccessfulOutgoingDatagram(eq(datagramTypeSos), anyLong());
verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
assertFalse(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
@@ -1058,8 +1057,7 @@
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSmsDispatchersController).sendCarrierRoamingNbIotNtnText(eq(mPendingSms));
- mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId,
- true, true);
+ mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId, true);
processAllMessages();
mInOrder.verify(mMockDatagramController)
@@ -1110,8 +1108,7 @@
processAllMessages();
verifyZeroInteractions(mMockSatelliteModemInterface);
- mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId,
- true, true);
+ mDatagramDispatcherUT.onSendSmsDone(mPhone.getSubId(), mPendingSms.uniqueMessageId, true);
processAllMessages();
mInOrder.verify(mMockDatagramController)
.updateSendStatus(eq(SUB_ID), eq(datagramTypeSms),
@@ -1137,7 +1134,7 @@
eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE), eq(0),
eq(SATELLITE_RESULT_SUCCESS));
verify(mMockSessionMetricsStats, times(1))
- .addCountOfSuccessfulOutgoingDatagram(eq(datagramTypeSos));
+ .addCountOfSuccessfulOutgoingDatagram(eq(datagramTypeSos), anyLong());
verify(mMockSatelliteModemInterface, times(1)).sendSatelliteDatagram(
any(SatelliteDatagram.class), anyBoolean(), anyBoolean(), any(Message.class));
assertFalse(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
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 cf6f6a9..3ccd17e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -22,6 +22,7 @@
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
import static android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_MIGRATION;
import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC;
+import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT;
@@ -81,9 +82,12 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
import static com.android.internal.telephony.satellite.SatelliteController.DEFAULT_CARRIER_EMERGENCY_CALL_WAIT_FOR_CONNECTION_TIMEOUT_MILLIS;
+import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_DATA_PLAN_METERED;
+import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_DATA_PLAN_UNMETERED;
import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_FALSE;
import static com.android.internal.telephony.satellite.SatelliteController.SATELLITE_MODE_ENABLED_TRUE;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -150,6 +154,7 @@
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.satellite.EarfcnRange;
import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteCapabilitiesCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
@@ -157,17 +162,22 @@
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
+import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.SatelliteInfo;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteManager.SatelliteException;
import android.telephony.satellite.SatelliteModemEnableRequestAttributes;
+import android.telephony.satellite.SatellitePosition;
import android.telephony.satellite.SatelliteSubscriberInfo;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.telephony.satellite.SatelliteSubscriptionInfo;
+import android.telephony.satellite.SystemSelectionSpecifier;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.IntArray;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -205,10 +215,12 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -540,6 +552,22 @@
}
};
+ private int mQueriedSystemSelectionChannelUpdatedResultCode = SATELLITE_RESULT_SUCCESS;
+ private Semaphore mSystemSelectionChannelUpdatedSemaphore = new Semaphore(0);
+ private ResultReceiver mSystemSelectionChannelUpdatedReceiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mQueriedSystemSelectionChannelUpdatedResultCode = resultCode;
+ try {
+ mSystemSelectionChannelUpdatedSemaphore.release();
+ } catch (Exception ex) {
+ fail("mSystemSelectionChannelUpdatedReceiver: Got exception in releasing "
+ + "semaphore, ex="
+ + ex);
+ }
+ }
+ };
+
@Rule
public final CheckFlagsRule mCheckFlagsRule =
DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -3140,7 +3168,7 @@
// Verify call the requestSetSatelliteEnabledForCarrier to enable the satellite when
// satellite service is enabled by entitlement server.
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, true, new ArrayList<>(),
- new ArrayList<>(), mIIntegerConsumer);
+ new ArrayList<>(), new HashMap<>(), mIIntegerConsumer);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
@@ -3160,7 +3188,7 @@
.when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
setUpResponseForRequestSetSatelliteEnabledForCarrier(false, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false, new ArrayList<>(),
- new ArrayList<>(), mIIntegerConsumer);
+ new ArrayList<>(), new HashMap<>(), mIIntegerConsumer);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
@@ -3191,7 +3219,7 @@
List<String> entitlementPlmnList = new ArrayList<>();
List<String> barredPlmnList = new ArrayList<>();
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
verify(mMockSatelliteModemInterface, never()).requestSatelliteEnabled(
any(SatelliteModemEnableRequestAttributes.class), any(Message.class));
@@ -3249,7 +3277,7 @@
reset(mMockSatelliteModemInterface);
entitlementPlmnList = Arrays.stream(new String[]{"00101", "00102", ""}).toList();
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
verify(mMockSatelliteModemInterface, never()).requestSatelliteEnabled(
any(SatelliteModemEnableRequestAttributes.class), any(Message.class));
@@ -3257,7 +3285,7 @@
reset(mMockSatelliteModemInterface);
entitlementPlmnList = Arrays.stream(new String[]{"00101", "00102", "123456789"}).toList();
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
verify(mMockSatelliteModemInterface, never()).requestSatelliteEnabled(
any(SatelliteModemEnableRequestAttributes.class), any(Message.class));
@@ -3265,7 +3293,7 @@
reset(mMockSatelliteModemInterface);
entitlementPlmnList = Arrays.stream(new String[]{"00101", "00102", "12"}).toList();
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
verify(mMockSatelliteModemInterface, never()).requestSatelliteEnabled(
any(SatelliteModemEnableRequestAttributes.class), any(Message.class));
@@ -3273,7 +3301,7 @@
reset(mMockSatelliteModemInterface);
entitlementPlmnList = Arrays.stream(new String[]{"00101", "00102", "1234"}).toList();
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
verify(mMockSatelliteModemInterface, never()).requestSatelliteEnabled(
any(SatelliteModemEnableRequestAttributes.class), any(Message.class));
}
@@ -3282,7 +3310,7 @@
List<String> mergedPlmnList, List<String> overlayConfigPlmnList,
List<String> barredPlmnList) {
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
- entitlementPlmnList, barredPlmnList, mIIntegerConsumer);
+ entitlementPlmnList, barredPlmnList, new HashMap<>(), mIIntegerConsumer);
List<String> plmnListPerCarrier = mSatelliteControllerUT.getSatellitePlmnsForCarrier(
SUB_ID);
@@ -3504,21 +3532,21 @@
// Change SUB_ID's EntitlementStatus to true
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, true, new ArrayList<>(),
- new ArrayList<>(), mIIntegerConsumer);
+ new ArrayList<>(), new HashMap<>(), mIIntegerConsumer);
assertEquals(true, satelliteEnabledPerCarrier.get(SUB_ID));
assertEquals(false, satelliteEnabledPerCarrier.get(SUB_ID1));
// Change SUB_ID1's EntitlementStatus to true
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID1, true, new ArrayList<>(),
- new ArrayList<>(), mIIntegerConsumer);
+ new ArrayList<>(), new HashMap<>(), mIIntegerConsumer);
assertEquals(true, satelliteEnabledPerCarrier.get(SUB_ID));
assertEquals(true, satelliteEnabledPerCarrier.get(SUB_ID1));
// Change SUB_ID's EntitlementStatus to false
mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false, new ArrayList<>(),
- new ArrayList<>(), mIIntegerConsumer);
+ new ArrayList<>(), new HashMap<>(), mIIntegerConsumer);
assertEquals(false, satelliteEnabledPerCarrier.get(SUB_ID));
assertEquals(true, satelliteEnabledPerCarrier.get(SUB_ID1));
@@ -3661,6 +3689,7 @@
// Do nothing when the satellite is not connected
doReturn(false).when(mServiceState).isUsingNonTerrestrialNetwork();
sendServiceStateChangedEvent();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
processAllMessages();
assertFalse(mSharedPreferences.getBoolean(SATELLITE_SYSTEM_NOTIFICATION_DONE_KEY, false));
verify(mMockNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any());
@@ -3986,6 +4015,96 @@
}
@Test
+ public void testRegisterForSelectedNbIotSatelliteSubscriptionChanged_WithFeatureFlagEnabled() {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+ Semaphore semaphore = new Semaphore(0);
+ final int[] selectedSubIds = new int[1];
+ ISelectedNbIotSatelliteSubscriptionCallback callback =
+ new ISelectedNbIotSatelliteSubscriptionCallback.Stub() {
+ @Override
+ public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
+ logd("onSelectedNbIotSatelliteSubscriptionChanged: selectedSubId="
+ + selectedSubId);
+ try {
+ selectedSubIds[0] = selectedSubId;
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onSelectedNbIotSatelliteSubscriptionChanged: Got exception in "
+ + "releasing semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ int errorCode = mSatelliteControllerUT.registerForSelectedNbIotSatelliteSubscriptionChanged(
+ callback);
+ assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, errorCode);
+
+ setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
+ errorCode = mSatelliteControllerUT.registerForSelectedNbIotSatelliteSubscriptionChanged(
+ callback);
+ assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, errorCode);
+
+ // Register the callback and verify that the event is reported.
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteProvisioned(true,SATELLITE_RESULT_SUCCESS);
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ errorCode = mSatelliteControllerUT.registerForSelectedNbIotSatelliteSubscriptionChanged(
+ callback);
+ assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);
+ int expectedSubId = 1;
+ sendSelectedNbIotSatelliteSubscriptionChangedEvent(expectedSubId, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSelectedNbIotSatelliteSubscriptionChanged"));
+ assertEquals(expectedSubId, selectedSubIds[0]);
+
+ // Unregister the callback and verify that the event is not reported.
+ mSatelliteControllerUT.unregisterForSelectedNbIotSatelliteSubscriptionChanged(callback);
+ sendSelectedNbIotSatelliteSubscriptionChangedEvent(2, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 0, "testRegisterForSelectedNbIotSatelliteSubscriptionChanged"));
+ }
+
+ @Test
+ public void testRegisterForSelectedNbIotSatelliteSubscriptionChanged_WithFeatureFlagDisabled() {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(false);
+
+ Semaphore semaphore = new Semaphore(0);
+ final int[] selectedSubIds = new int[1];
+ ISelectedNbIotSatelliteSubscriptionCallback callback =
+ new ISelectedNbIotSatelliteSubscriptionCallback.Stub() {
+ @Override
+ public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
+ logd("onSelectedNbIotSatelliteSubscriptionChanged: selectedSubId="
+ + selectedSubId);
+ try {
+ selectedSubIds[0] = selectedSubId;
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onSelectedNbIotSatelliteSubscriptionChanged: Got exception in "
+ + "releasing semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ int errorCode = mSatelliteControllerUT.registerForSelectedNbIotSatelliteSubscriptionChanged(
+ callback);
+ assertEquals(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, errorCode);
+
+ // Verify that the event is not reported.
+ sendSelectedNbIotSatelliteSubscriptionChangedEvent(1, null);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 0, "testRegisterForSelectedNbIotSatelliteSubscriptionChanged"));
+
+
+ }
+
+ @Test
public void testIsSatelliteEmergencyMessagingSupportedViaCarrier() {
// Carrier-enabled flag is off
when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(false);
@@ -4155,8 +4274,10 @@
when(mServiceState2.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
mSatelliteControllerUT.mIsApplicationSupportsP2P = true;
+ mSatelliteControllerUT.setIsSatelliteSupported(true);
mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, true);
- mCarrierConfigBundle.putInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT, 1);
+ mCarrierConfigBundle.putInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
+ CARRIER_ROAMING_NTN_CONNECT_MANUAL);
mCarrierConfigBundle.putInt(
KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT, 1 * 60);
mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL, true);
@@ -4178,6 +4299,7 @@
}
mSatelliteControllerUT.setSatellitePhone(1);
mSatelliteControllerUT.isSatelliteAllowedCallback = null;
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
processAllMessages();
mSatelliteControllerUT.elapsedRealtime = 0;
assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone));
@@ -4605,7 +4727,7 @@
any());
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
- assertTrue(resultArray[0].getProvisionStatus());
+ assertTrue(resultArray[0].isProvisioned());
assertEquals(mSubscriberId, resultArray[0].getSatelliteSubscriberInfo().getSubscriberId());
// Request provisioning with SatelliteSubscriberInfo that has not been provisioned
@@ -4616,7 +4738,7 @@
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
- assertTrue(resultArray[1].getProvisionStatus());
+ assertTrue(resultArray[1].isProvisioned());
assertEquals(mSubscriberId2, resultArray[1].getSatelliteSubscriberInfo().getSubscriberId());
// Request provisioning with the same SatelliteSubscriberInfo that was previously
@@ -4631,9 +4753,9 @@
verifyDeprovisionSatellite(inputList);
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
- assertFalse(resultArray[1].getProvisionStatus());
+ assertFalse(resultArray[1].isProvisioned());
assertEquals(mSubscriberId2, resultArray[1].getSatelliteSubscriberInfo().getSubscriberId());
- assertTrue(resultArray[0].getProvisionStatus());
+ assertTrue(resultArray[0].isProvisioned());
assertEquals(mSubscriberId, resultArray[0].getSatelliteSubscriberInfo().getSubscriberId());
// Request deprovision for subscriberID 1, verify that subscriberID 1 is set to deprovision.
@@ -4642,9 +4764,9 @@
verifyDeprovisionSatellite(inputList);
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
- assertFalse(resultArray[1].getProvisionStatus());
+ assertFalse(resultArray[1].isProvisioned());
assertEquals(mSubscriberId2, resultArray[1].getSatelliteSubscriberInfo().getSubscriberId());
- assertFalse(resultArray[0].getProvisionStatus());
+ assertFalse(resultArray[0].isProvisioned());
assertEquals(mSubscriberId, resultArray[0].getSatelliteSubscriberInfo().getSubscriberId());
// Request provision for subscriberID 2, verify that subscriberID 2 is set to provision.
@@ -4654,9 +4776,9 @@
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
- assertTrue(resultArray[1].getProvisionStatus());
+ assertTrue(resultArray[1].isProvisioned());
assertEquals(mSubscriberId2, resultArray[1].getSatelliteSubscriberInfo().getSubscriberId());
- assertFalse(resultArray[0].getProvisionStatus());
+ assertFalse(resultArray[0].isProvisioned());
assertEquals(mSubscriberId, resultArray[0].getSatelliteSubscriberInfo().getSubscriberId());
}
@@ -5027,6 +5149,132 @@
assertFalse(mSatelliteControllerUT.isApplicationUpdated);
}
+ @Test
+ public void testUpdateSystemSelectionChannels() {
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+ String mccmnc = "123455";
+ int[] bands1 = {200, 201, 202};
+ IntArray intArraybands1 = new IntArray(3);
+ intArraybands1.addAll(bands1);
+ int[] earfcns1 = {300, 301, 310, 311};
+ IntArray intArrayEarfcns1 = new IntArray(4);
+ intArrayEarfcns1.addAll(earfcns1);
+ String seed1 = "test-seed-satellite1";
+ UUID uuid1 = UUID.nameUUIDFromBytes(seed1.getBytes());
+ SatellitePosition satellitePosition1 = new SatellitePosition(0, 35876);
+ EarfcnRange earfcnRange1 = new EarfcnRange(301, 300);
+ EarfcnRange earfcnRange2 = new EarfcnRange(311, 310);
+ List<EarfcnRange> earfcnRangeList1 = new ArrayList<>(
+ Arrays.asList(earfcnRange1, earfcnRange2));
+ SatelliteInfo satelliteInfo1 = new SatelliteInfo(uuid1, satellitePosition1, Arrays.stream(
+ bands1).boxed().collect(Collectors.toList()), earfcnRangeList1);
+ int[] tagIds = {1, 2, 3};
+ IntArray intArrayTagIds = new IntArray(3);
+ intArrayTagIds.addAll(tagIds);
+ SystemSelectionSpecifier systemSelectionSpecifier1 = new SystemSelectionSpecifier(mccmnc,
+ intArraybands1, intArrayEarfcns1, new SatelliteInfo[]{satelliteInfo1},
+ intArrayTagIds);
+
+ setUpResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_ERROR);
+ mSatelliteControllerUT.updateSystemSelectionChannels(
+ new ArrayList<>(List.of(systemSelectionSpecifier1)),
+ mSystemSelectionChannelUpdatedReceiver);
+ processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(1));
+ assertEquals(SATELLITE_RESULT_ERROR, mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ // Verify whether callback receives expected result
+ setUpResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.updateSystemSelectionChannels(
+ new ArrayList<>(List.of(systemSelectionSpecifier1)),
+ mSystemSelectionChannelUpdatedReceiver);
+ processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(1));
+ assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ // Verify whether SatelliteModemInterface API was invoked and data is valid, when single
+ // data was provided.
+ ArgumentCaptor<List<SystemSelectionSpecifier>> systemSelectionSpecifierListCaptor =
+ ArgumentCaptor.forClass(List.class);
+ verify(mMockSatelliteModemInterface, times(2)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(Message.class));
+ List<SystemSelectionSpecifier> capturedList = systemSelectionSpecifierListCaptor.getValue();
+ SystemSelectionSpecifier systemSelectionSpecifier = capturedList.getFirst();
+
+ assertEquals(mccmnc, systemSelectionSpecifier.getMccMnc());
+ int[] actualBandsArray = systemSelectionSpecifier.getBands();
+ assertArrayEquals(bands1, actualBandsArray);
+ int[] actualEarfcnsArray = systemSelectionSpecifier.getEarfcns();
+ assertArrayEquals(earfcns1, actualEarfcnsArray);
+ assertArrayEquals(new SatelliteInfo[]{satelliteInfo1},
+ systemSelectionSpecifier.getSatelliteInfos().toArray(new SatelliteInfo[0]));
+ int[] actualTagIdArray = systemSelectionSpecifier.getTagIds();
+ assertArrayEquals(tagIds, actualTagIdArray);
+
+ // Verify whether SatelliteModemInterface API was invoked and data is valid, when list
+ // of data was provided.
+ int[] bands2 = {210, 211, 212};
+ IntArray intArraybands2 = new IntArray(3);
+ intArraybands2.addAll(bands2);
+ int[] earfcns2 = {320, 321, 330, 331};
+ IntArray intArrayEarfcns2 = new IntArray(4);
+ intArrayEarfcns2.addAll(earfcns2);
+ String seed2 = "test-seed-satellite2";
+ UUID uuid2 = UUID.nameUUIDFromBytes(seed2.getBytes());
+ SatellitePosition satellitePosition2 = new SatellitePosition(120, 35876);
+ EarfcnRange earfcnRange3 = new EarfcnRange(321, 320);
+ EarfcnRange earfcnRange4 = new EarfcnRange(331, 330);
+ List<EarfcnRange> earfcnRangeList2 = new ArrayList<>(
+ Arrays.asList(earfcnRange3, earfcnRange4));
+ SatelliteInfo satelliteInfo2 = new SatelliteInfo(uuid2, satellitePosition2, Arrays.stream(
+ bands1).boxed().collect(Collectors.toList()), earfcnRangeList2);
+ SystemSelectionSpecifier systemSelectionSpecifier2 = new SystemSelectionSpecifier(mccmnc,
+ intArraybands2, intArrayEarfcns2, new SatelliteInfo[]{satelliteInfo2},
+ intArrayTagIds);
+
+ // Verify whether callback receives expected result
+ setUpResponseForUpdateSystemSelectionChannels(SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.updateSystemSelectionChannels(
+ new ArrayList<>(List.of(systemSelectionSpecifier1, systemSelectionSpecifier2)),
+ mSystemSelectionChannelUpdatedReceiver);
+ processAllMessages();
+ assertTrue(waitForRequestUpdateSystemSelectionChannelResult(1));
+ assertEquals(SATELLITE_RESULT_SUCCESS, mQueriedSystemSelectionChannelUpdatedResultCode);
+
+ // Verify whether SatelliteModemInterface API was invoked and data is valid,
+ verify(mMockSatelliteModemInterface, times(3)).updateSystemSelectionChannels(
+ systemSelectionSpecifierListCaptor.capture(), any(Message.class));
+ capturedList = systemSelectionSpecifierListCaptor.getValue();
+ SystemSelectionSpecifier capturedSystemSelectionSpecifier1 = capturedList.getFirst();
+ SystemSelectionSpecifier capturedSystemSelectionSpecifier2 = capturedList.get(1);
+
+ // Verify first SystemSelectionSpecifier
+ assertEquals(mccmnc, systemSelectionSpecifier.getMccMnc());
+ actualBandsArray = capturedSystemSelectionSpecifier1.getBands();
+ assertArrayEquals(bands1, actualBandsArray);
+ actualEarfcnsArray = capturedSystemSelectionSpecifier1.getEarfcns();
+ assertArrayEquals(earfcns1, actualEarfcnsArray);
+ assertArrayEquals(new SatelliteInfo[]{satelliteInfo1},
+ capturedSystemSelectionSpecifier1.getSatelliteInfos().toArray(
+ new SatelliteInfo[0]));
+ actualTagIdArray = capturedSystemSelectionSpecifier1.getTagIds();
+ assertArrayEquals(tagIds, actualTagIdArray);
+
+ // Verify second SystemSelectionSpecifier
+ assertEquals(mccmnc, systemSelectionSpecifier.getMccMnc());
+ actualBandsArray = capturedSystemSelectionSpecifier2.getBands();
+ assertArrayEquals(bands2, actualBandsArray);
+ actualEarfcnsArray = capturedSystemSelectionSpecifier2.getEarfcns();
+ assertArrayEquals(earfcns2, actualEarfcnsArray);
+ assertArrayEquals(new SatelliteInfo[]{satelliteInfo2},
+ capturedSystemSelectionSpecifier2.getSatelliteInfos().toArray(
+ new SatelliteInfo[0]));
+ actualTagIdArray = capturedSystemSelectionSpecifier2.getTagIds();
+ assertArrayEquals(tagIds, actualTagIdArray);
+ }
+
private void verifyProvisionStatusPerSubscriberIdGetFromDb(boolean provision) {
doReturn(provision).when(
mMockSubscriptionManagerService).isSatelliteProvisionedForNonIpDatagram(anyInt());
@@ -5047,7 +5295,7 @@
assertEquals(SATELLITE_RESULT_SUCCESS,
mRequestSatelliteSubscriberProvisionStatusResultCode);
assertEquals(provision,
- mRequestSatelliteSubscriberProvisionStatusResultList.get(0).getProvisionStatus());
+ mRequestSatelliteSubscriberProvisionStatusResultList.get(0).isProvisioned());
}
private void setComponentName() {
@@ -5341,6 +5589,19 @@
}).when(mMockSatelliteModemInterface).stopSendingNtnSignalStrength(any(Message.class));
}
+ private void setUpResponseForUpdateSystemSelectionChannels(
+ @SatelliteManager.SatelliteResult int error) {
+ SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
+ ? null : new SatelliteException(error);
+ doAnswer(invocation -> {
+ Message message = (Message) invocation.getArguments()[1];
+ AsyncResult.forMessage(message, null, exception);
+ message.sendToTarget();
+ return null;
+ }).when(mMockSatelliteModemInterface).updateSystemSelectionChannels(anyList(),
+ any(Message.class));
+ }
+
private boolean waitForRequestIsSatelliteSupportedResult(int expectedNumberOfEvents) {
for (int i = 0; i < expectedNumberOfEvents; i++) {
try {
@@ -5464,6 +5725,24 @@
return true;
}
+ private boolean waitForRequestUpdateSystemSelectionChannelResult(int expectedNumberOfEvents) {
+ for (int i = 0; i < expectedNumberOfEvents; i++) {
+ try {
+ if (!mSystemSelectionChannelUpdatedSemaphore.tryAcquire(TIMEOUT,
+ TimeUnit.MILLISECONDS)) {
+ logd("Timeout to receive "
+ + "updateSystemSelectionChannel()"
+ + " callback");
+ return false;
+ }
+ } catch (Exception ex) {
+ logd("updateSystemSelectionChannel: Got exception=" + ex);
+ return false;
+ }
+ }
+ return true;
+ }
+
private void verifySatelliteSupported(boolean supported, int expectedErrorCode) {
mSatelliteSupportSemaphore.drainPermits();
mSatelliteControllerUT.requestIsSatelliteSupported(mSatelliteSupportReceiver);
@@ -5591,6 +5870,14 @@
msg.sendToTarget();
}
+ private void sendSelectedNbIotSatelliteSubscriptionChangedEvent(int selectedSubId,
+ Throwable exception) {
+ Message msg = mSatelliteControllerUT.obtainMessage(
+ 60 /* EVENT_SELECTED_NB_IOT_SATELLITE_SUBSCRIPTION_CHANGED */);
+ msg.obj = new AsyncResult(null, selectedSubId, exception);
+ msg.sendToTarget();
+ }
+
private void setRadioPower(boolean on) {
mSimulatedCommands.setRadioPower(on, false, false, null);
}
@@ -5916,6 +6203,12 @@
}
}
+ void setIsSatelliteSupported(@Nullable Boolean isSatelliteSupported) {
+ synchronized (mIsSatelliteSupportedLock) {
+ mIsSatelliteSupported = isSatelliteSupported;
+ }
+ }
+
public boolean isRadioOn() {
synchronized (mIsRadioOnLock) {
return mIsRadioOn;
@@ -5974,14 +6267,14 @@
final String callerSC = "SC:ResultReceiver";
final String callerSAC = "SAC:ResultReceiver";
- doReturn(false).when(mFeatureFlags).geofenceEnhancementForBetterUx();
+ doReturn(false).when(mFeatureFlags).carrierRoamingNbIotNtn();
mSatelliteControllerUT.incrementResultReceiverCount(callerSC);
assertEquals(0, mSatelliteControllerUT.getResultReceiverTotalCount());
mSatelliteControllerUT.decrementResultReceiverCount(callerSC);
assertEquals(0, mSatelliteControllerUT.getResultReceiverTotalCount());
- doReturn(true).when(mFeatureFlags).geofenceEnhancementForBetterUx();
+ doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn();
mSatelliteControllerUT.incrementResultReceiverCount(callerSC);
assertEquals(1, mSatelliteControllerUT.getResultReceiverTotalCount());
@@ -6056,4 +6349,64 @@
return isProvisioned != null ? isProvisioned : false;
}
}
+
+ @Test
+ public void testGetSatelliteDataPlanForPlmn_WithEntitlement() throws Exception {
+ logd("testGetSatelliteDataPlanForPlmn_WithEntitlement");
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ replaceInstance(SatelliteController.class, "mMergedPlmnListPerCarrier",
+ mSatelliteControllerUT, new SparseArray<>());
+ List<String> overlayConfigPlmnList = new ArrayList<>();
+ replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
+ mSatelliteControllerUT, overlayConfigPlmnList);
+ mCarrierConfigBundle.putBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+ mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+ true);
+
+ List<String> entitlementPlmnList =
+ Arrays.stream(new String[]{"00101", "00102", "00103", "00104"})
+ .toList();
+ List<String> barredPlmnList = new ArrayList<>();
+ Map<String, Integer> dataPlanListMap = Map.of(
+ "00101", SATELLITE_DATA_PLAN_METERED,
+ "00103", SATELLITE_DATA_PLAN_UNMETERED);
+ mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
+ entitlementPlmnList, barredPlmnList, dataPlanListMap, mIIntegerConsumer);
+
+ int dataPlanForPlmn;
+ dataPlanForPlmn = mSatelliteControllerUT.getSatelliteDataPlanForPlmn(SUB_ID, "00101");
+ assertEquals(SATELLITE_DATA_PLAN_METERED, dataPlanForPlmn);
+
+ dataPlanForPlmn = mSatelliteControllerUT.getSatelliteDataPlanForPlmn(SUB_ID, "00103");
+ assertEquals(SATELLITE_DATA_PLAN_UNMETERED, dataPlanForPlmn);
+ }
+
+ @Test
+ public void testGetSatelliteDataPlanForPlmn_WithoutEntitlement() throws Exception {
+ logd("testGetSatelliteDataPlanForPlmn_WithoutEntitlement");
+ when(mFeatureFlags.carrierEnabledSatelliteFlag()).thenReturn(true);
+
+ replaceInstance(SatelliteController.class, "mMergedPlmnListPerCarrier",
+ mSatelliteControllerUT, new SparseArray<>());
+ List<String> overlayConfigPlmnList = new ArrayList<>();
+ replaceInstance(SatelliteController.class, "mSatellitePlmnListFromOverlayConfig",
+ mSatelliteControllerUT, overlayConfigPlmnList);
+ mCarrierConfigBundle.putBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+ mCarrierConfigBundle.putBoolean(CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+ true);
+
+ List<String> entitlementPlmnList =
+ Arrays.stream(new String[]{"00101", "00102", "00103", "00104"})
+ .toList();
+ List<String> barredPlmnList = new ArrayList<>();
+ Map<String, Integer> dataPlanListMap = new HashMap<>();
+ mSatelliteControllerUT.onSatelliteEntitlementStatusUpdated(SUB_ID, false,
+ entitlementPlmnList, barredPlmnList, dataPlanListMap, mIIntegerConsumer);
+
+ int dataPlanForPlmn = mSatelliteControllerUT.getSatelliteDataPlanForPlmn(SUB_ID, "00101");
+ assertEquals(SATELLITE_DATA_PLAN_METERED, dataPlanForPlmn);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
index 56d5731..529088b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -373,6 +373,7 @@
@Test
public void testSatelliteProvisionStateChangedBeforeTimeout() {
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, false);
processAllMessages();
@@ -393,6 +394,7 @@
assertFalse(mTestSOSMessageRecommender.isDialerNotified());
reset(mMockSatelliteStats);
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection, false);
processAllMessages();
assertTrue(mTestSOSMessageRecommender.isTimerStarted());
@@ -983,6 +985,8 @@
private ComponentName mSmsAppComponent = new ComponentName(
DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS);
private boolean mIsDialerNotified;
+ private boolean mProvisionState = true;
+ private boolean mSatelliteAllowedByReasons = true;
/**
* Create an instance of SatelliteSOSMessageRecommender.
@@ -1017,6 +1021,16 @@
mIsDialerNotified = isDialerNotified;
}
+ @Override
+ protected boolean updateAndGetProvisionState() {
+ return mProvisionState;
+ }
+
+ @Override
+ protected boolean isSatelliteAllowedByReasons() {
+ return mSatelliteAllowedByReasons;
+ }
+
public boolean isTimerStarted() {
return hasMessages(EVENT_TIME_OUT);
}