Merge "Prevent advance <-> idle pingpong" into main
diff --git a/flags/data.aconfig b/flags/data.aconfig
index a993d51..0fd094d 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -121,3 +121,14 @@
}
}
+# 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
+ }
+}
+
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 6044746..6fe1232 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -5497,7 +5497,7 @@
public void refreshSafetySources(String refreshBroadcastId) {
if (mFeatureFlags.enableIdentifierDisclosureTransparencyUnsolEvents()
|| mFeatureFlags.enableModemCipherTransparencyUnsolEvents()) {
- mSafetySource.refresh(mContext, refreshBroadcastId);
+ post(() -> mSafetySource.refresh(mContext, refreshBroadcastId));
}
}
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index 0afe119..42ec8d3 100644
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -566,7 +566,7 @@
}
if (mFeatureFlags.oemEnabledSatelliteFlag()) {
- TelephonyCountryDetector.getInstance(mPhone.getContext())
+ TelephonyCountryDetector.getInstance(mPhone.getContext(), mFeatureFlags)
.onNetworkCountryCodeChanged(mPhone, countryIso);
}
Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 0436ae5..e98b996 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -642,7 +642,7 @@
if (DBG) log("updateDefaultValues: change: " + change);
if (change == PRIMARY_SUB_NO_CHANGE) return;
- // If there's only one primary subscription active, we trigger PREFERRED_PICK_DIALOG
+ // If there's only one primary subscription active, we trigger mobile data
// dialog if and only if there were multiple primary SIM cards and one is removed.
// Otherwise, if user just inserted their first SIM, or there's one primary and one
// opportunistic subscription active (activeSubInfos.size() > 1), we automatically
@@ -658,7 +658,19 @@
if (hasCalling()) mSubscriptionManagerService.setDefaultVoiceSubId(subId);
if (hasMessaging()) mSubscriptionManagerService.setDefaultSmsSubId(subId);
if (!mSubscriptionManagerService.isEsimBootStrapProvisioningActivated()) {
- sendDefaultSubConfirmedNotification(subId);
+ // Determines the appropriate notification type
+ // Preconditions:
+ // - There is only one active primary subscription.
+ // - The eSIM bootstrap is NOT activated.
+ // Behavior:
+ // - If the primary subscription is not deactivated OR the device is in single SIM
+ // mode, send a notification to dismiss the SIM dialog.
+ // - Otherwise, send a notification to trigger the preferred SIM/data pick dialog.
+ @TelephonyManager.DefaultSubscriptionSelectType
+ int type = (change != PRIMARY_SUB_REMOVED || mActiveModemCount == 1)
+ ? EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS
+ : EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
+ sendDefaultSubConfirmedNotification(type, subId);
}
return;
}
@@ -770,14 +782,14 @@
}
}
- private void sendDefaultSubConfirmedNotification(int defaultSubId) {
+ private void sendDefaultSubConfirmedNotification(
+ @TelephonyManager.DefaultSubscriptionSelectType int type, int defaultSubId) {
Intent intent = new Intent();
intent.setAction(ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED);
intent.setClassName("com.android.settings",
"com.android.settings.sim.SimSelectNotification");
- intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
- EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DISMISS);
+ intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, type);
intent.putExtra(EXTRA_SUBSCRIPTION_ID, defaultSubId);
mContext.sendBroadcast(intent);
diff --git a/src/java/com/android/internal/telephony/TelephonyCountryDetector.java b/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
index fed4931..b604431 100644
--- a/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
+++ b/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
@@ -43,6 +43,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.FeatureFlags;
import java.util.ArrayList;
import java.util.HashMap;
@@ -109,6 +110,10 @@
private Map<String, Long> mOverriddenCachedNetworkCountryCodes = new HashMap<>();
@GuardedBy("mLock")
private boolean mIsCountryCodesOverridden = false;
+ private final RegistrantList mCountryCodeChangedRegistrants = new RegistrantList();
+
+ private FeatureFlags mFeatureFlags = null;
+
@NonNull private final LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
@@ -186,22 +191,26 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected TelephonyCountryDetector(@NonNull Looper looper, @NonNull Context context,
@NonNull LocationManager locationManager,
- @NonNull ConnectivityManager connectivityManager) {
+ @NonNull ConnectivityManager connectivityManager,
+ FeatureFlags featureFlags) {
super(looper);
mLocationManager = locationManager;
mGeocoder = new Geocoder(context);
mConnectivityManager = connectivityManager;
+ mFeatureFlags = featureFlags;
initialize();
}
/** @return the singleton instance of the {@link TelephonyCountryDetector} */
- public static synchronized TelephonyCountryDetector getInstance(@NonNull Context context) {
+ public static synchronized TelephonyCountryDetector getInstance(@NonNull Context context,
+ FeatureFlags featureFlags) {
if (sInstance == null) {
HandlerThread handlerThread = new HandlerThread("TelephonyCountryDetector");
handlerThread.start();
sInstance = new TelephonyCountryDetector(handlerThread.getLooper(), context,
context.getSystemService(LocationManager.class),
- context.getSystemService(ConnectivityManager.class));
+ context.getSystemService(ConnectivityManager.class),
+ featureFlags);
}
return sInstance;
}
@@ -473,6 +482,12 @@
}
}
evaluateRequestingLocationUpdates();
+ if (mFeatureFlags.oemEnabledSatelliteFlag()) {
+ logd("mCountryCodeChangedRegistrants.notifyRegistrants()");
+ mCountryCodeChangedRegistrants.notifyRegistrants();
+ } else {
+ logd("mCountryCodeChangedRegistrants.notifyRegistrants() is not called");
+ }
}
private void handleEventWifiConnectivityStateChanged() {
@@ -587,6 +602,26 @@
|| SystemProperties.getBoolean(BOOT_ALLOW_MOCK_MODEM_PROPERTY, false));
}
+ /**
+ * Register a callback for country code changed events
+ *
+ * @param h Handler to notify
+ * @param what msg.what when the message is delivered
+ * @param obj AsyncResult.userObj when the message is delivered
+ */
+ public void registerForCountryCodeChanged(Handler h, int what, Object obj) {
+ mCountryCodeChangedRegistrants.add(h, what, obj);
+ }
+
+ /**
+ * Unregister a callback for country code changed events
+ *
+ * @param h Handler to notifyf
+ */
+ public void unregisterForCountryCodeChanged(Handler h) {
+ mCountryCodeChangedRegistrants.remove(h);
+ }
+
private static void logd(@NonNull String log) {
Rlog.d(TAG, log);
}
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
index f5eae91..40c0081 100644
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ b/src/java/com/android/internal/telephony/data/DataEvaluation.java
@@ -225,6 +225,8 @@
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 89153ab..5d31283 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -3543,15 +3543,6 @@
}
/**
- * 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.)
@@ -3559,13 +3550,22 @@
private void onSimStateChanged(@SimState int simState) {
log("onSimStateChanged: state=" + TelephonyManager.simStateToString(simState));
if (mSimState != simState) {
- mSimState = simState;
if (simState == TelephonyManager.SIM_STATE_ABSENT) {
- onSimAbsent();
+ 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));
+ }
} 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/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index ab54e9f..7e9f3ff 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -238,9 +238,9 @@
private static final int EVENT_SATELLITE_CONFIG_DATA_UPDATED = 40;
private static final int EVENT_SATELLITE_SUPPORTED_STATE_CHANGED = 41;
private static final int EVENT_NOTIFY_NTN_HYSTERESIS_TIMED_OUT = 42;
- private static final int EVENT_EVALUATE_ESOS_PROFILES_PRIORITIZATION = 43;
- private static final int CMD_PROVISION_SATELLITE_TOKEN_UPDATED = 44;
- private static final int EVENT_PROVISION_SATELLITE_TOKEN_UPDATED = 45;
+ private static final int CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION = 43;
+ private static final int CMD_UPDATE_PROVISION_SATELLITE_TOKEN = 44;
+ private static final int EVENT_UPDATE_PROVISION_SATELLITE_TOKEN_DONE = 45;
private static final int EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT = 46;
private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47;
private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48;
@@ -512,10 +512,24 @@
// Variable for backup and restore device's screen rotation settings.
private String mDeviceRotationLockToBackupAndRestore = null;
+ // This is used for testing only. Context#getSystemService is a final API and cannot be
+ // mocked. Using this to inject a mock SubscriptionManager to work around this limitation.
+ private SubscriptionManager mInjectSubscriptionManager = null;
private final Object mIsWifiConnectedLock = new Object();
@GuardedBy("mIsWifiConnectedLock")
private boolean mIsWifiConnected = false;
+ private BroadcastReceiver
+ mDefaultSmsSubscriptionChangedBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(
+ SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED)) {
+ plogd("Default SMS subscription changed");
+ sendRequestAsync(CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION, null, null);
+ }
+ }
+ };
/**
* @return The singleton instance of SatelliteController.
@@ -567,7 +581,7 @@
// to the satellite service and HAL interface.
mSatelliteModemInterface = SatelliteModemInterface.make(
mContext, this, mFeatureFlags);
- mCountryDetector = TelephonyCountryDetector.getInstance(context);
+ mCountryDetector = TelephonyCountryDetector.getInstance(context, mFeatureFlags);
mCountryDetector.registerForWifiConnectivityStateChanged(this,
EVENT_WIFI_CONNECTIVITY_STATE_CHANGED, null);
mTelecomManager = mContext.getSystemService(TelecomManager.class);
@@ -648,7 +662,7 @@
getDemoPointingNotAlignedDurationMillisFromResources();
mSatelliteEmergencyModeDurationMillis =
getSatelliteEmergencyModeDurationFromOverlayConfig(context);
- sendMessageDelayed(obtainMessage(EVENT_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
+ sendMessageDelayed(obtainMessage(CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
/* delayMillis= */ TimeUnit.MINUTES.toMillis(1));
SubscriptionManager subscriptionManager = mContext.getSystemService(
@@ -658,6 +672,7 @@
subscriptionManager.addOnSubscriptionsChangedListener(
new HandlerExecutor(new Handler(looper)), mSubscriptionsChangedListener);
}
+ registerDefaultSmsSubscriptionChangedBroadcastReceiver();
}
class SatelliteSubscriptionsChangedListener
@@ -1573,50 +1588,49 @@
break;
}
- case EVENT_EVALUATE_ESOS_PROFILES_PRIORITIZATION: {
+ case CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION: {
evaluateESOSProfilesPrioritization();
break;
}
- case CMD_PROVISION_SATELLITE_TOKEN_UPDATED: {
+ case CMD_UPDATE_PROVISION_SATELLITE_TOKEN: {
request = (SatelliteControllerHandlerRequest) msg.obj;
RequestProvisionSatelliteArgument argument =
(RequestProvisionSatelliteArgument) request.argument;
- onCompleted = obtainMessage(EVENT_PROVISION_SATELLITE_TOKEN_UPDATED, request);
+ onCompleted = obtainMessage(EVENT_UPDATE_PROVISION_SATELLITE_TOKEN_DONE, request);
// only pass to index 0.
// TODO: Select the subscription with highest priority and set it to mSatelliteSubId
int subId = -1;
synchronized (mSatelliteTokenProvisionedLock) {
subId = mSubscriberIdPerSub.getOrDefault(
argument.mSatelliteSubscriberInfoList.get(0).getSubscriberId(), -1);
- for (SatelliteSubscriberInfo subscriberInfo :
- argument.mSatelliteSubscriberInfoList) {
- mProvisionedSubscriberId.put(subscriberInfo.getSubscriberId(), true);
- }
}
setSatellitePhone(subId);
String iccId = mSubscriptionManagerService.getSubscriptionInfo(subId).getIccId();
argument.setIccId(iccId);
+ boolean sendResponse = false;
synchronized (mSatelliteTokenProvisionedLock) {
if (!iccId.equals(mLastConfiguredIccId)) {
logd("updateSatelliteSubscription subId=" + subId + ", iccId=" + iccId
+ " to modem");
mSatelliteModemInterface.updateSatelliteSubscription(iccId, onCompleted);
+ } else {
+ sendResponse = true;
}
}
- Consumer<Integer> result = new Consumer<Integer>() {
- @Override
- public void accept(Integer integer) {
- logd("invoke CMD_PROVISION_SATELLITE_TOKEN_UPDATED done.");
- }
- };
- ProvisionSatelliteServiceArgument internalArgument =
- new ProvisionSatelliteServiceArgument(iccId, null, result, subId);
- sendRequestAsync(CMD_PROVISION_SATELLITE_SERVICE, internalArgument, null);
+ handleEventSatelliteSubscriptionProvisionStateChanged(
+ argument.mSatelliteSubscriberInfoList, true);
+ if (sendResponse) {
+ // The response is sent immediately because the ICCID has already been
+ // delivered to the modem.
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(SatelliteManager.KEY_PROVISION_SATELLITE_TOKENS, true);
+ argument.mResult.send(SATELLITE_RESULT_SUCCESS, bundle);
+ }
break;
}
- case EVENT_PROVISION_SATELLITE_TOKEN_UPDATED: {
+ case EVENT_UPDATE_PROVISION_SATELLITE_TOKEN_DONE: {
ar = (AsyncResult) msg.obj;
request = (SatelliteControllerHandlerRequest) ar.userObj;
RequestProvisionSatelliteArgument argument =
@@ -3790,6 +3804,48 @@
});
}
+ private void handleEventSatelliteSubscriptionProvisionStateChanged(
+ List<SatelliteSubscriberInfo> newList, boolean provisioned) {
+ logd("handleEventSatelliteSubscriptionProvisionStateChanged: newList=" + newList
+ + " , provisioned=" + provisioned);
+ boolean provisionChanged = false;
+ synchronized (mSatelliteTokenProvisionedLock) {
+ for (SatelliteSubscriberInfo subscriberInfo : newList) {
+ if (mProvisionedSubscriberId.getOrDefault(subscriberInfo.getSubscriberId(), false)
+ == provisioned) {
+ continue;
+ }
+ provisionChanged = true;
+ mProvisionedSubscriberId.put(subscriberInfo.getSubscriberId(), provisioned);
+ }
+ }
+ if (!provisionChanged) {
+ logd("handleEventSatelliteSubscriptionProvisionStateChanged: provision state nothing "
+ + "changed.");
+ return;
+ }
+ List<SatelliteSubscriberProvisionStatus> informList =
+ getPrioritizedSatelliteSubscriberProvisionStatusList();
+ plogd("handleEventSatelliteSubscriptionProvisionStateChanged: " + informList);
+ notifySatelliteSubscriptionProvisionStateChanged(informList);
+ }
+
+ private void notifySatelliteSubscriptionProvisionStateChanged(
+ @NonNull List<SatelliteSubscriberProvisionStatus> list) {
+ List<ISatelliteProvisionStateCallback> deadCallersList = new ArrayList<>();
+ mSatelliteProvisionStateChangedListeners.values().forEach(listener -> {
+ try {
+ listener.onSatelliteSubscriptionProvisionStateChanged(list);
+ } catch (RemoteException e) {
+ plogd("notifySatelliteSubscriptionProvisionStateChanged: " + e);
+ deadCallersList.add(listener);
+ }
+ });
+ deadCallersList.forEach(listener -> {
+ mSatelliteProvisionStateChangedListeners.remove(listener.asBinder());
+ });
+ }
+
private void handleEventSatelliteModemStateChanged(
@SatelliteManager.SatelliteModemState int state) {
plogd("handleEventSatelliteModemStateChanged: state=" + state);
@@ -4312,13 +4368,13 @@
processNewCarrierConfigData(subId);
resetCarrierRoamingSatelliteModeParams(subId);
handleStateChangedForCarrierRoamingNtnEligibility();
- sendMessageDelayed(obtainMessage(EVENT_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
+ sendMessageDelayed(obtainMessage(CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
TimeUnit.MINUTES.toMillis(1));
}
// imsi, msisdn, default sms subId change
private void handleSubscriptionsChanged() {
- sendMessageDelayed(obtainMessage(EVENT_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
+ sendMessageDelayed(obtainMessage(CMD_EVALUATE_ESOS_PROFILES_PRIORITIZATION),
TimeUnit.MINUTES.toMillis(1));
}
@@ -5577,11 +5633,12 @@
*/
private void evaluateESOSProfilesPrioritization() {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("evaluateESOSProfilesPrioritization: Flag CarrierRoamingNbIotNtn is disabled");
return;
}
List<SubscriptionInfo> allSubInfos = mSubscriptionManagerService.getAllSubInfoList(
mContext.getOpPackageName(), mContext.getAttributionTag());
- //key : priority, low value is high, value : List<SubscriptionInfo>
+ // Key : priority - lower value has higher priority; Value : List<SubscriptionInfo>
Map<Integer, List<SubscriptionInfo>> newSubsInfoListPerPriority = new HashMap<>();
for (SubscriptionInfo info : allSubInfos) {
int subId = info.getSubscriptionId();
@@ -5599,15 +5656,18 @@
if (keyPriority != -1) {
newSubsInfoListPerPriority.computeIfAbsent(keyPriority,
k -> new ArrayList<>()).add(info);
+ } else {
+ plogw("evaluateESOSProfilesPrioritization: Got -1 keyPriority for subId="
+ + info.getSubscriptionId());
}
}
if (newSubsInfoListPerPriority.size() == 0) {
- logd("evaluateESOSProfilesPrioritization: no available");
+ logd("evaluateESOSProfilesPrioritization: no satellite subscription available");
return;
}
- // if priority is changed, send broadcast for provisioned ESOS subs ids
+ // If priority has changed, send broadcast for provisioned ESOS subs IDs
synchronized (mSatelliteTokenProvisionedLock) {
if (isPriorityChanged(mSubsInfoListPerPriority, newSubsInfoListPerPriority)) {
mSubsInfoListPerPriority = newSubsInfoListPerPriority;
@@ -5639,6 +5699,10 @@
subId);
SubscriptionManager subscriptionManager = mContext.getSystemService(
SubscriptionManager.class);
+ if (mInjectSubscriptionManager != null) {
+ logd("getPhoneNumberBasedCarrier: InjectSubscriptionManager");
+ subscriptionManager = mInjectSubscriptionManager;
+ }
String phoneNumber = subscriptionManager.getPhoneNumber(subId);
if (phoneNumber == null) {
logd("getPhoneNumberBasedCarrier: phoneNumber null");
@@ -5707,15 +5771,23 @@
result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
return;
}
+ List<SatelliteSubscriberProvisionStatus> list =
+ getPrioritizedSatelliteSubscriberProvisionStatusList();
+ logd("requestSatelliteSubscriberProvisionStatus: " + list);
+ final Bundle bundle = new Bundle();
+ bundle.putParcelableList(SatelliteManager.KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN, list);
+ result.send(SATELLITE_RESULT_SUCCESS, bundle);
+ }
+ private List<SatelliteSubscriberProvisionStatus>
+ getPrioritizedSatelliteSubscriberProvisionStatusList() {
List<SatelliteSubscriberProvisionStatus> list = new ArrayList<>();
synchronized (mSatelliteTokenProvisionedLock) {
- mSubscriberIdPerSub = new HashMap<>();
for (int priority : mSubsInfoListPerPriority.keySet()) {
List<SubscriptionInfo> infoList = mSubsInfoListPerPriority.get(priority);
if (infoList == null) {
- logd("requestSatelliteSubscriberProvisionStatus: no exist this priority "
- + priority);
+ logd("getPrioritySatelliteSubscriberProvisionStatusList: no exist this "
+ + "priority " + priority);
continue;
}
for (SubscriptionInfo info : infoList) {
@@ -5724,10 +5796,10 @@
int carrierId = info.getCarrierId();
String apn = getConfigForSubId(info.getSubscriptionId())
.getString(KEY_SATELLITE_NIDD_APN_NAME_STRING, "");
- logd("requestSatelliteSubscriberProvisionStatus: subscriberId:"
+ logd("getPrioritySatelliteSubscriberProvisionStatusList: subscriberId:"
+ subscriberId + " , carrierId=" + carrierId + " , apn=" + apn);
if (subscriberId.isEmpty()) {
- logd("requestSatelliteSubscriberProvisionStatus: getSubscriberId "
+ logd("getPrioritySatelliteSubscriberProvisionStatusList: getSubscriberId "
+ "failed skip this subscriberId.");
continue;
}
@@ -5737,10 +5809,11 @@
.setSubId(info.getSubscriptionId())
.setSubscriberIdType(subscriberIdPair.second)
.build();
- boolean provisioned = mProvisionedSubscriberId.getOrDefault(
- subscriberId, false);
- logd("requestSatelliteSubscriberProvisionStatus: satelliteSubscriberInfo="
- + satelliteSubscriberInfo + ", provisioned=" + provisioned);
+ boolean provisioned = mProvisionedSubscriberId.getOrDefault(subscriberId,
+ false);
+ logd("getPrioritySatelliteSubscriberProvisionStatusList: "
+ + "satelliteSubscriberInfo=" + satelliteSubscriberInfo
+ + ", provisioned=" + provisioned);
list.add(new SatelliteSubscriberProvisionStatus.Builder()
.setSatelliteSubscriberInfo(satelliteSubscriberInfo)
.setProvisionStatus(provisioned).build());
@@ -5748,11 +5821,7 @@
}
}
}
-
- logd("requestSatelliteSubscriberProvisionStatus: " + list);
- final Bundle bundle = new Bundle();
- bundle.putParcelableList(SatelliteManager.KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN, list);
- result.send(SATELLITE_RESULT_SUCCESS, bundle);
+ return list;
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@@ -5795,7 +5864,7 @@
logd("provisionSatellite:" + list);
RequestProvisionSatelliteArgument request = new RequestProvisionSatelliteArgument(list,
result);
- sendRequestAsync(CMD_PROVISION_SATELLITE_TOKEN_UPDATED, request, null);
+ sendRequestAsync(CMD_UPDATE_PROVISION_SATELLITE_TOKEN, request, null);
}
@@ -5969,4 +6038,15 @@
}
}
}
+
+ private void registerDefaultSmsSubscriptionChangedBroadcastReceiver() {
+ if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+ plogd("registerDefaultSmsSubscriptionChangedBroadcastReceiver: Flag "
+ + "CarrierRoamingNbIotNtn is disabled");
+ return;
+ }
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
+ mContext.registerReceiver(mDefaultSmsSubscriptionChangedBroadcastReceiver, intentFilter);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyCountryDetectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyCountryDetectorTest.java
index 1daab00..9b3777b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyCountryDetectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyCountryDetectorTest.java
@@ -51,6 +51,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.telephony.flags.FeatureFlags;
import org.junit.After;
import org.junit.Before;
@@ -76,6 +77,8 @@
LocaleTracker mMockLocaleTracker2;
@Mock Location mMockLocation;
@Mock Network mMockNetwork;
+ @Mock
+ private FeatureFlags mMockFeatureFlags;
@Captor
private ArgumentCaptor<LocationListener> mLocationListenerCaptor;
@@ -118,8 +121,9 @@
when(mLocationManager.getProviders(true)).thenReturn(Arrays.asList("TEST_PROVIDER"));
+ when(mMockFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
mCountryDetectorUT = new TestTelephonyCountryDetector(
- mLooper, mContext, mLocationManager, mConnectivityManager);
+ mLooper, mContext, mLocationManager, mConnectivityManager, mMockFeatureFlags);
if (isGeoCoderImplemented()) {
verify(mLocationManager).requestLocationUpdates(anyString(), anyLong(), anyFloat(),
mLocationListenerCaptor.capture());
@@ -141,8 +145,10 @@
clearInvocations(mLocationManager);
clearInvocations(mConnectivityManager);
when(mMockLocaleTracker.getCurrentCountry()).thenReturn("US");
- TelephonyCountryDetector inst1 = TelephonyCountryDetector.getInstance(mContext);
- TelephonyCountryDetector inst2 = TelephonyCountryDetector.getInstance(mContext);
+ TelephonyCountryDetector inst1 = TelephonyCountryDetector
+ .getInstance(mContext, mMockFeatureFlags);
+ TelephonyCountryDetector inst2 = TelephonyCountryDetector
+ .getInstance(mContext, mMockFeatureFlags);
assertEquals(inst1, inst2);
if (isGeoCoderImplemented()) {
verify(mLocationManager, never()).requestLocationUpdates(anyString(), anyLong(),
@@ -386,8 +392,9 @@
* @param locationManager The LocationManager instance.
*/
TestTelephonyCountryDetector(Looper looper, Context context,
- LocationManager locationManager, ConnectivityManager connectivityManager) {
- super(looper, context, locationManager, connectivityManager);
+ LocationManager locationManager, ConnectivityManager connectivityManager,
+ FeatureFlags featureFlags) {
+ super(looper, context, locationManager, connectivityManager, featureFlags);
}
@Override
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 5dce5c2..0b66459 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -888,8 +888,11 @@
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());
@@ -4196,7 +4199,7 @@
}
@Test
- public void testImsGracefulTearDown() throws Exception {
+ public void testImsGracefulTearDownSimRemoval() throws Exception {
setImsRegistered(true);
setRcsRegistered(true);
@@ -4242,6 +4245,52 @@
}
@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/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 483db50..872cc28 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -21,6 +21,8 @@
import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_NIDD_APN_NAME_STRING;
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS;
import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_GOOD;
@@ -30,6 +32,8 @@
import static android.telephony.satellite.SatelliteManager.KEY_DEMO_MODE_ENABLED;
import static android.telephony.satellite.SatelliteManager.KEY_EMERGENCY_MODE_ENABLED;
import static android.telephony.satellite.SatelliteManager.KEY_NTN_SIGNAL_STRENGTH;
+import static android.telephony.satellite.SatelliteManager.KEY_PROVISION_SATELLITE_TOKENS;
+import static android.telephony.satellite.SatelliteManager.KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_CAPABILITIES;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_ENABLED;
@@ -96,6 +100,7 @@
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -113,6 +118,8 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.satellite.INtnSignalStrengthCallback;
import android.telephony.satellite.ISatelliteCapabilitiesCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
@@ -126,6 +133,7 @@
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteManager.SatelliteException;
import android.telephony.satellite.SatelliteModemEnableRequestAttributes;
+import android.telephony.satellite.SatelliteSubscriberInfo;
import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.telephony.satellite.SatelliteSubscriptionInfo;
import android.testing.AndroidTestingRunner;
@@ -146,6 +154,7 @@
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.ProvisionMetricsStats;
import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
+import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.After;
@@ -157,6 +166,7 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -216,6 +226,9 @@
@Mock private CellSignalStrength mCellSignalStrength;
@Mock private SatelliteConfig mMockConfig;
@Mock private DemoSimulator mMockDemoSimulator;
+ @Mock private Resources mResources;
+ @Mock private SubscriptionManager mSubscriptionManager;
+ @Mock private SubscriptionInfo mSubscriptionInfo;
private Semaphore mIIntegerConsumerSemaphore = new Semaphore(0);
private IIntegerConsumer mIIntegerConsumer = new IIntegerConsumer.Stub() {
@@ -244,6 +257,17 @@
private SatelliteCapabilities mEmptySatelliteCapabilities = new SatelliteCapabilities(
new HashSet<>(), mIsPointingRequired, MAX_BYTES_PER_OUT_GOING_DATAGRAM,
new HashMap<>());
+ final int mCarrierId = 0;
+ final String mImsi = "1234567890123";
+ final String mNiddApn = "testApn";
+ final String mMsisdn = "0987654321";
+ final String mSubscriberId = mImsi.substring(0, 6) + mMsisdn;
+ final String mIccId = "1000000000000001";
+ final String mIccId2 = "2000000000000002";
+ final String mImsi2 = "2345678901234";
+ final String mMsisdn2 = "9876543210";
+ final String mSubscriberId2 = mIccId2;
+
private Semaphore mSatelliteCapabilitiesSemaphore = new Semaphore(0);
private SatelliteCapabilities mQueriedSatelliteCapabilities = null;
private int mQueriedSatelliteCapabilitiesResultCode = SATELLITE_RESULT_SUCCESS;
@@ -600,6 +624,9 @@
doReturn(mMockConfigParser).when(mMockTelephonyConfigUpdateInstallReceiver)
.getConfigParser(ConfigProviderAdaptor.DOMAIN_SATELLITE);
+ doReturn(mSubscriptionInfo).when(mMockSubscriptionManagerService).getSubscriptionInfo(
+ anyInt());
+ doReturn("").when(mSubscriptionInfo).getIccId();
}
@After
@@ -4087,6 +4114,264 @@
assertFalse(mSatelliteControllerUT.getWwanIsInService(mServiceState));
}
+ private boolean mProvisionState = false;
+ private int mProvisionSateResultCode = -1;
+ private Semaphore mProvisionSateSemaphore = new Semaphore(0);
+ private ResultReceiver mProvisionSatelliteReceiver = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mProvisionSateResultCode = resultCode;
+ logd("mProvisionSatelliteReceiver: resultCode=" + resultCode);
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_PROVISION_SATELLITE_TOKENS)) {
+ mProvisionState = resultData.getBoolean(KEY_PROVISION_SATELLITE_TOKENS);
+ logd("mProvisionSatelliteReceiver: mProvisionState=" + mProvisionState);
+ } else {
+ loge("KEY_PROVISION_SATELLITE_TOKENS does not exist.");
+ mProvisionState = false;
+ }
+ } else {
+ mProvisionState = false;
+ }
+ try {
+ mProvisionSateSemaphore.release();
+ } catch (Exception ex) {
+ loge("mProvisionSatelliteReceiver: Got exception in releasing semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ private List<SatelliteSubscriberProvisionStatus>
+ mRequestSatelliteSubscriberProvisionStatusResultList = new ArrayList<>();
+ private int mRequestSatelliteSubscriberProvisionStatusResultCode = SATELLITE_RESULT_SUCCESS;
+ private Semaphore mRequestSatelliteSubscriberProvisionStatusSemaphore = new Semaphore(0);
+ private ResultReceiver mRequestSatelliteSubscriberProvisionStatusReceiver = new ResultReceiver(
+ null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ mRequestSatelliteSubscriberProvisionStatusResultCode = resultCode;
+ logd("mRequestSatelliteSubscriberProvisionStatusReceiver: resultCode=" + resultCode);
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
+ if (resultData.containsKey(KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN)) {
+ mRequestSatelliteSubscriberProvisionStatusResultList =
+ resultData.getParcelableArrayList(
+ KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN,
+ SatelliteSubscriberProvisionStatus.class);
+ } else {
+ loge("KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN does not exist.");
+ mRequestSatelliteSubscriberProvisionStatusResultList = new ArrayList<>();
+ }
+ } else {
+ mRequestSatelliteSubscriberProvisionStatusResultList = new ArrayList<>();
+ }
+ try {
+ mRequestSatelliteSubscriberProvisionStatusSemaphore.release();
+ } catch (Exception ex) {
+ loge("mRequestSatelliteSubscriberProvisionStatusReceiver: Got exception in "
+ + "releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+
+ @Test
+ public void testRequestSatelliteSubscriberProvisionStatus() throws Exception {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ verifyRequestSatelliteSubscriberProvisionStatus();
+ }
+
+ private void verifyRequestSatelliteSubscriberProvisionStatus() throws Exception {
+ setSatelliteSubscriberTesting();
+ List<SatelliteSubscriberInfo> list = getExpectedSatelliteSubscriberInfoList();
+ mCarrierConfigBundle.putString(KEY_SATELLITE_NIDD_APN_NAME_STRING, mNiddApn);
+ mCarrierConfigBundle.putBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL, true);
+ for (Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener> pair
+ : mCarrierConfigChangedListenerList) {
+ pair.first.execute(() -> pair.second.onCarrierConfigChanged(
+ /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0)
+ );
+ }
+ moveTimeForward(TimeUnit.MINUTES.toMillis(1));
+ processAllMessages();
+
+ // Verify that calling requestSatelliteSubscriberProvisionStatus returns the expected
+ // list of SatelliteSubscriberProvisionStatus.
+ mSatelliteControllerUT.requestSatelliteSubscriberProvisionStatus(
+ mRequestSatelliteSubscriberProvisionStatusReceiver);
+ moveTimeForward(TimeUnit.MINUTES.toMillis(1));
+ processAllMessages();
+ assertEquals(SATELLITE_RESULT_SUCCESS,
+ mRequestSatelliteSubscriberProvisionStatusResultCode);
+ assertEquals(list.get(0), mRequestSatelliteSubscriberProvisionStatusResultList.get(
+ 0).getSatelliteSubscriberInfo());
+ }
+
+ @Test
+ public void testProvisionSatellite() throws Exception {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ verifyRequestSatelliteSubscriberProvisionStatus();
+ List<SatelliteSubscriberInfo> inputList = getExpectedSatelliteSubscriberInfoList();
+ verifyProvisionSatellite(inputList);
+ }
+
+ private void verifyProvisionSatellite(List<SatelliteSubscriberInfo> inputList) {
+ doAnswer(invocation -> {
+ Message message = (Message) invocation.getArguments()[1];
+ AsyncResult.forMessage(message, null, new SatelliteException(SATELLITE_RESULT_SUCCESS));
+ message.sendToTarget();
+ return null;
+ }).when(mMockSatelliteModemInterface).updateSatelliteSubscription(anyString(), any());
+
+ mSatelliteControllerUT.provisionSatellite(inputList, mProvisionSatelliteReceiver);
+ processAllMessages();
+ assertEquals(SATELLITE_RESULT_SUCCESS, mProvisionSateResultCode);
+ assertTrue(mProvisionState);
+ }
+
+
+ @Test
+ public void testRegisterForSatelliteSubscriptionProvisionStateChanged() throws Exception {
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+
+ Semaphore semaphore = new Semaphore(0);
+ SatelliteSubscriberProvisionStatus[] resultArray =
+ new SatelliteSubscriberProvisionStatus[2];
+ ISatelliteProvisionStateCallback callback = new ISatelliteProvisionStateCallback.Stub() {
+ @Override
+ public void onSatelliteProvisionStateChanged(boolean provisioned) {
+ logd("onSatelliteProvisionStateChanged: provisioned=" + provisioned);
+ }
+
+ @Override
+ public void onSatelliteSubscriptionProvisionStateChanged(
+ List<SatelliteSubscriberProvisionStatus> satelliteSubscriberProvisionStatus) {
+ logd("onSatelliteSubscriptionProvisionStateChanged: "
+ + satelliteSubscriberProvisionStatus);
+ for (int i = 0; i < satelliteSubscriberProvisionStatus.size(); i++) {
+ resultArray[i] = satelliteSubscriberProvisionStatus.get(i);
+ }
+ try {
+ semaphore.release();
+ } catch (Exception ex) {
+ loge("onSatelliteSubscriptionProvisionStateChanged: Got exception in releasing "
+ + "semaphore, ex=" + ex);
+ }
+ }
+ };
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ int errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(SUB_ID,
+ callback);
+ processAllMessages();
+ assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);
+
+ verifyRequestSatelliteSubscriberProvisionStatus();
+
+ // Verify that onSatelliteSubscriptionProvisionStateChanged is called when requesting
+ // provisioning for the first time.
+ List<SatelliteSubscriberInfo> list = getExpectedSatelliteSubscriberInfoList();
+ List<SatelliteSubscriberInfo> inputList = new ArrayList<>();
+ inputList.add(list.get(0));
+ verifyProvisionSatellite(inputList);
+
+ verify(mMockSatelliteModemInterface, times(1)).updateSatelliteSubscription(anyString(),
+ any());
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
+ assertTrue(resultArray[0].getProvisionStatus());
+ assertEquals(mSubscriberId, resultArray[0].getSatelliteSubscriberInfo().getSubscriberId());
+
+ // Request provisioning with SatelliteSubscriberInfo that has not been provisioned
+ // before, and verify that onSatelliteSubscriptionProvisionStateChanged is called.
+ inputList = new ArrayList<>();
+ inputList.add(list.get(1));
+ verifyProvisionSatellite(inputList);
+
+ verify(mMockSatelliteModemInterface, times(2)).updateSatelliteSubscription(anyString(),
+ any());
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
+ assertTrue(resultArray[1].getProvisionStatus());
+ assertEquals(mSubscriberId2, resultArray[1].getSatelliteSubscriberInfo().getSubscriberId());
+
+ // Request provisioning with the same SatelliteSubscriberInfo that was previously
+ // requested, and verify that onSatelliteSubscriptionProvisionStateChanged is not called.
+ verifyProvisionSatellite(inputList);
+
+ verify(mMockSatelliteModemInterface, times(2)).updateSatelliteSubscription(anyString(),
+ any());
+ assertFalse(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteSubscriptionProvisionStateChanged"));
+ }
+
+ private void setSatelliteSubscriberTesting() throws Exception {
+ doReturn("123").when(mContext).getAttributionTag();
+ final int carrierId = 0;
+ SubscriptionInfo subscriptionInfo = new SubscriptionInfo.Builder()
+ .setId(SUB_ID).setIccId(mIccId).setSimSlotIndex(0).setOnlyNonTerrestrialNetwork(
+ false).setSatelliteESOSSupported(true).setCarrierId(carrierId).build();
+ SubscriptionInfo subscriptionInfo2 = new SubscriptionInfo.Builder()
+ .setId(SUB_ID1).setIccId(mIccId2).setSimSlotIndex(1).setOnlyNonTerrestrialNetwork(
+ true).setSatelliteESOSSupported(false).setCarrierId(carrierId).build();
+ List<SubscriptionInfo> allSubInfos = new ArrayList<>();
+ allSubInfos.add(subscriptionInfo);
+ allSubInfos.add(subscriptionInfo2);
+ doReturn(allSubInfos).when(mMockSubscriptionManagerService).getAllSubInfoList(
+ anyString(), anyString());
+ SubscriptionInfoInternal subInfoInternal =
+ new SubscriptionInfoInternal.Builder().setCarrierId(0).setImsi(mImsi).setIccId(
+ mIccId).build();
+ SubscriptionInfoInternal subInfoInternal2 =
+ new SubscriptionInfoInternal.Builder().setCarrierId(0).setImsi(mImsi2).setIccId(
+ mIccId2).build();
+ doReturn(subscriptionInfo).when(mMockSubscriptionManagerService).getSubscriptionInfo(
+ eq(SUB_ID));
+ doReturn(subscriptionInfo2).when(mMockSubscriptionManagerService).getSubscriptionInfo(
+ eq(SUB_ID1));
+ Field field = SatelliteController.class.getDeclaredField("mInjectSubscriptionManager");
+ field.setAccessible(true);
+ field.set(mSatelliteControllerUT, mSubscriptionManager);
+ doReturn(mMsisdn).when(mSubscriptionManager).getPhoneNumber(eq(SUB_ID));
+ doReturn(mMsisdn2).when(mSubscriptionManager).getPhoneNumber(eq(SUB_ID1));
+ Field provisionedSubscriberIdField = SatelliteController.class.getDeclaredField(
+ "mProvisionedSubscriberId");
+ provisionedSubscriberIdField.setAccessible(true);
+ provisionedSubscriberIdField.set(mSatelliteControllerUT, new HashMap<>());
+ Field subscriberIdPerSubField = SatelliteController.class.getDeclaredField(
+ "mSubscriberIdPerSub");
+ subscriberIdPerSubField.setAccessible(true);
+ subscriberIdPerSubField.set(mSatelliteControllerUT, new HashMap<>());
+ Field lastConfiguredIccIdField = SatelliteController.class.getDeclaredField(
+ "mLastConfiguredIccId");
+ lastConfiguredIccIdField.setAccessible(true);
+ lastConfiguredIccIdField.set(mSatelliteControllerUT, null);
+ doReturn(subInfoInternal).when(mMockSubscriptionManagerService).getSubscriptionInfoInternal(
+ eq(SUB_ID));
+ doReturn(subInfoInternal2).when(
+ mMockSubscriptionManagerService).getSubscriptionInfoInternal(eq(SUB_ID1));
+ doReturn(mResources).when(mContext).getResources();
+ doReturn("package").when(mResources).getString(
+ eq(R.string.config_satellite_gateway_service_package));
+ doReturn("className").when(mResources).getString(
+ eq(R.string.config_satellite_carrier_roaming_esos_provisioned_class));
+ doReturn("action").when(mResources).getString(
+ eq(R.string.config_satellite_carrier_roaming_esos_provisioned_intent_action));
+ }
+
+ private List<SatelliteSubscriberInfo> getExpectedSatelliteSubscriberInfoList() {
+ List<SatelliteSubscriberInfo> list = new ArrayList<>();
+ list.add(new SatelliteSubscriberInfo.Builder().setSubscriberId(mSubscriberId).setCarrierId(
+ mCarrierId).setNiddApn(mNiddApn).setSubId(SUB_ID).setSubscriberIdType(
+ SatelliteSubscriberInfo.IMSI_MSISDN).build());
+ list.add(new SatelliteSubscriberInfo.Builder().setSubscriberId(mSubscriberId2).setCarrierId(
+ mCarrierId).setNiddApn(mNiddApn).setSubId(SUB_ID1).setSubscriberIdType(
+ SatelliteSubscriberInfo.ICCID).build());
+ return list;
+ }
+
private void resetSatelliteControllerUTEnabledState() {
logd("resetSatelliteControllerUTEnabledState");
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);