Merge "Sending the carrier restriction rules to CP in CarrierInfo format in RADIO_HAL 2.2" into main
diff --git a/flags/data.aconfig b/flags/data.aconfig
index d956104..bd9b21e 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -172,3 +172,23 @@
description: "Write DataRatStateChanged atom"
bug:"318519337"
}
+
+# OWNER=jackyu TARGET=24Q4
+flag {
+ name: "dds_callback"
+ namespace: "telephony"
+ description: "Adding new callback when DDS changed"
+ bug:"353723350"
+}
+
+# OWNER=jackyu TARGET=25Q1
+flag {
+ name: "support_network_provider"
+ namespace: "telephony"
+ description: "Deprecate network factory and adapt the new network provider model from connectivity service"
+ bug: "343370895"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
diff --git a/flags/messaging.aconfig b/flags/messaging.aconfig
index 63f707f..905dc94 100644
--- a/flags/messaging.aconfig
+++ b/flags/messaging.aconfig
@@ -45,5 +45,5 @@
name: "sms_mms_deliver_broadcasts_redirect_to_main_user"
namespace: "telephony"
description: "This flag controls the redirection of SMS_DELIVER AND WAP_PUSH_DELIVER broadcasts to the MAIN user."
- bug: "335820374"
+ bug: "314321617"
}
\ No newline at end of file
diff --git a/flags/subscription.aconfig b/flags/subscription.aconfig
index 9a5dabc..dc17a61 100644
--- a/flags/subscription.aconfig
+++ b/flags/subscription.aconfig
@@ -77,3 +77,15 @@
purpose: PURPOSE_BUGFIX
}
}
+
+# OWNER=jackyu TARGET=24Q4
+flag {
+ name: "uicc_phone_number_fix"
+ namespace: "telephony"
+ description: "Fixed that empty phone number when getLine1Number returns empty"
+ bug: "302437869"
+
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index cf10c92..f41fad3 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -69,3 +69,11 @@
purpose: PURPOSE_BUGFIX
}
}
+
+# OWNER=mewan TARGET=24Q4
+flag {
+ name: "optimization_apdu_sender"
+ namespace: "telephony"
+ description: "This flag controls optimization of apdu sender class."
+ bug:"335257880"
+}
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 48e7b0d..2010ce1 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -320,6 +320,7 @@
optional bool is_ntn = 41;
optional bool supports_business_call_composer = 42;
optional int32 call_composer_status = 43;
+ optional int32 precise_call_state_on_setup = 44;
// Internal use only
optional int64 setup_begin_millis = 10001;
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 7bb89d0..c4ba77d 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -258,6 +258,8 @@
return mCarrierActionOnRadioEnabled;
case CARRIER_ACTION_REPORT_DEFAULT_NETWORK_STATUS:
return mCarrierActionReportDefaultNetworkStatus;
+ case EVENT_APN_SETTINGS_CHANGED:
+ return null; // we don't know if it's enabled, but this is not "unsupported" action
default:
loge("Unsupported action: " + action);
return null;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 9e400ee..6044746 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -1119,6 +1119,7 @@
@Override
public GsmCdmaCall getForegroundCall() {
+ if (!hasCalling()) return null;
return mCT.mForegroundCall;
}
@@ -1396,6 +1397,8 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean isInCall() {
+ if (!hasCalling()) return false;
+
GsmCdmaCall.State foregroundCallState = getForegroundCall().getState();
GsmCdmaCall.State backgroundCallState = getBackgroundCall().getState();
GsmCdmaCall.State ringingCallState = getRingingCall().getState();
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 65d113d..37d8aa6 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -1069,7 +1069,7 @@
SmsBroadcastReceiver resultReceiver = tracker.getSmsBroadcastReceiver(this);
- if (!mUserManager.isUserUnlocked()) {
+ if (!isMainUserUnlocked()) {
log("processMessagePart: !isUserUnlocked; calling processMessagePartWithUserLocked. "
+ "Port: " + destPort, tracker.getMessageId());
return processMessagePartWithUserLocked(
@@ -1187,6 +1187,15 @@
return false;
}
+ private boolean isMainUserUnlocked() {
+ UserHandle mainUser = mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser() ?
+ mUserManager.getMainUser() : null;
+ if (mainUser != null) {
+ return mUserManager.isUserUnlocked(mainUser);
+ }
+ return mUserManager.isUserUnlocked();
+ }
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void showNewMessageNotification() {
// Do not show the notification on non-FBE devices.
@@ -1210,8 +1219,15 @@
.setChannelId(NotificationChannelController.CHANNEL_ID_SMS);
NotificationManager mNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.notify(
- NOTIFICATION_TAG, NOTIFICATION_ID_NEW_MESSAGE, mBuilder.build());
+ UserHandle mainUser = mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser() ?
+ mUserManager.getMainUser() : null;
+ if (mainUser != null) {
+ mNotificationManager.notifyAsUser(
+ NOTIFICATION_TAG, NOTIFICATION_ID_NEW_MESSAGE, mBuilder.build(), mainUser);
+ } else {
+ mNotificationManager.notify(
+ NOTIFICATION_TAG, NOTIFICATION_ID_NEW_MESSAGE, mBuilder.build());
+ }
}
static void cancelNewMessageNotification(Context context) {
@@ -2129,6 +2145,7 @@
public void onReceive(Context context, Intent intent) {
if (ACTION_OPEN_SMS_APP.equals(intent.getAction())) {
// do nothing if the user had not unlocked the device yet
+ // TODO(b/355049884): This is looking at sms package of the wrong user!
UserManager userManager =
(UserManager) context.getSystemService(Context.USER_SERVICE);
if (userManager.isUserUnlocked()) {
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index d9c5c9c..f7ce388 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -46,6 +46,7 @@
import com.android.internal.telephony.data.CellularNetworkValidator;
import com.android.internal.telephony.data.PhoneSwitcher;
import com.android.internal.telephony.data.TelephonyNetworkFactory;
+import com.android.internal.telephony.data.TelephonyNetworkProvider;
import com.android.internal.telephony.euicc.EuiccCardController;
import com.android.internal.telephony.euicc.EuiccController;
import com.android.internal.telephony.flags.FeatureFlags;
@@ -101,6 +102,7 @@
static private SimultaneousCallingTracker sSimultaneousCallingTracker;
static private PhoneSwitcher sPhoneSwitcher;
static private TelephonyNetworkFactory[] sTelephonyNetworkFactories;
+ private static TelephonyNetworkProvider sTelephonyNetworkProvider;
static private NotificationChannelController sNotificationChannelController;
static private CellularNetworkValidator sCellularNetworkValidator;
@@ -239,6 +241,12 @@
}
Rlog.i(LOG_TAG, "defaultSmsApplication: " + packageName);
+ if (sFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ // Explicitly call this, even if the user has no default Sms application, to
+ // ensure that the System apps have the appropriate permissions.
+ SmsApplication.grantPermissionsToSystemApps(context);
+ }
+
// Set up monitor to watch for changes to SMS packages
SmsApplication.initSmsPackageMonitor(context);
@@ -279,9 +287,15 @@
sNotificationChannelController = new NotificationChannelController(context);
- for (int i = 0; i < numPhones; i++) {
- sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
- Looper.myLooper(), sPhones[i], featureFlags);
+ if (featureFlags.supportNetworkProvider()) {
+ // Create the TelephonyNetworkProvider instance, which is a singleton.
+ sTelephonyNetworkProvider = new TelephonyNetworkProvider(Looper.myLooper(),
+ context, featureFlags);
+ } else {
+ for (int i = 0; i < numPhones; i++) {
+ sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
+ Looper.myLooper(), sPhones[i], featureFlags);
+ }
}
}
}
@@ -306,7 +320,10 @@
sPhones = copyOf(sPhones, activeModemCount);
sCommandsInterfaces = copyOf(sCommandsInterfaces, activeModemCount);
- sTelephonyNetworkFactories = copyOf(sTelephonyNetworkFactories, activeModemCount);
+
+ if (!sFeatureFlags.supportNetworkProvider()) {
+ sTelephonyNetworkFactories = copyOf(sTelephonyNetworkFactories, activeModemCount);
+ }
int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
for (int i = prevActiveModemCount; i < activeModemCount; i++) {
@@ -318,8 +335,11 @@
PackageManager.FEATURE_TELEPHONY_IMS)) {
sPhones[i].createImsPhone();
}
- sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
- Looper.myLooper(), sPhones[i], sFeatureFlags);
+
+ if (!sFeatureFlags.supportNetworkProvider()) {
+ sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
+ Looper.myLooper(), sPhones[i], sFeatureFlags);
+ }
}
}
}
@@ -387,6 +407,10 @@
}
}
+ public static TelephonyNetworkProvider getNetworkProvider() {
+ return sTelephonyNetworkProvider;
+ }
+
/**
* Get the network factory associated with a given phone ID.
* @param phoneId the phone id
@@ -573,13 +597,22 @@
pw.flush();
pw.println("++++++++++++++++++++++++++++++++");
- sTelephonyNetworkFactories[i].dump(fd, pw, args);
+ if (!sFeatureFlags.supportNetworkProvider()) {
+ sTelephonyNetworkFactories[i].dump(fd, pw, args);
+ }
pw.flush();
pw.decreaseIndent();
pw.println("++++++++++++++++++++++++++++++++");
}
+ pw.increaseIndent();
+ if (sFeatureFlags.supportNetworkProvider()) {
+ sTelephonyNetworkProvider.dump(fd, pw, args);
+ }
+ pw.decreaseIndent();
+ pw.println("++++++++++++++++++++++++++++++++");
+
pw.println("UiccController:");
pw.increaseIndent();
try {
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index da20639..b4db14c 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -466,7 +466,7 @@
RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_DATA_MODEM,
result, mDefaultWorkSource);
if (DBG) {
- logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+ logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest) + " " + modemId);
}
try {
proxy.setPreferredDataModem(rr.mSerial, modemId);
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index e2f5980..e7500a2 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -1164,6 +1164,9 @@
mDesiredPowerState = power;
setPowerStateToDesired(forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply);
+ if (mDesiredPowerState) {
+ SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(true);
+ }
}
/**
@@ -1325,6 +1328,12 @@
// Hence, issuing shut down regardless of radio power response
mCi.requestShutdown(null);
}
+
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ loge("EVENT_RADIO_POWER_OFF_DONE: exception=" + ar.exception);
+ SatelliteController.getInstance().onPowerOffCellularRadioFailed();
+ }
break;
// GSM
@@ -4979,7 +4988,7 @@
*/
public void powerOffRadioSafely() {
synchronized (this) {
- SatelliteController.getInstance().onCellularRadioPowerOffRequested();
+ SatelliteController.getInstance().onSetCellularRadioPowerStateRequested(false);
if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
EmergencyStateTracker.getInstance().onCellularRadioPowerOffRequested();
}
diff --git a/src/java/com/android/internal/telephony/SimResponse.java b/src/java/com/android/internal/telephony/SimResponse.java
index 59defc3..97692a0 100644
--- a/src/java/com/android/internal/telephony/SimResponse.java
+++ b/src/java/com/android/internal/telephony/SimResponse.java
@@ -112,7 +112,7 @@
android.hardware.radio.sim.CarrierRestrictions carrierRestrictions,
int multiSimPolicy) {
RILRequest rr = mRil.processResponse(HAL_SERVICE_SIM, responseInfo);
- boolean carrierLockInfoSupported = mRil.getHalVersion(HAL_SERVICE_SIM).greater(
+ boolean carrierLockInfoSupported = mRil.getHalVersion(HAL_SERVICE_SIM).greaterOrEqual(
RIL.RADIO_HAL_VERSION_2_2);
if (rr == null) {
return;
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 0893b75..8c9a820 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -27,6 +27,7 @@
import android.database.Cursor;
import android.database.SQLException;
import android.os.PersistableBundle;
+import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -35,6 +36,7 @@
import com.android.internal.telephony.analytics.TelephonyAnalytics;
import com.android.internal.telephony.analytics.TelephonyAnalytics.SmsMmsAnalytics;
import com.android.internal.telephony.cdma.CdmaInboundSmsHandler;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.gsm.GsmInboundSmsHandler;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -97,6 +99,10 @@
/** Content resolver to use to access raw table from SmsProvider. */
private final ContentResolver mResolver;
+ private final UserManager mUserManager;
+
+ private final FeatureFlags mFeatureFlags;
+
/** Broadcast receiver that processes the raw table when the user unlocks the phone for the
* first time after reboot and the credential-encrypted storage is available.
*/
@@ -105,6 +111,12 @@
public void onReceive(final Context context, Intent intent) {
Rlog.d(TAG, "Received broadcast " + intent.getAction());
if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId != getMainUser().getIdentifier()) {
+ return;
+ }
+ }
new ScanRawTableThread(context).start();
}
}
@@ -126,9 +138,9 @@
}
public static void initialize(Context context, GsmInboundSmsHandler gsmInboundSmsHandler,
- CdmaInboundSmsHandler cdmaInboundSmsHandler) {
+ CdmaInboundSmsHandler cdmaInboundSmsHandler, FeatureFlags featureFlags) {
if (instance == null) {
- instance = new SmsBroadcastUndelivered(context);
+ instance = new SmsBroadcastUndelivered(context, featureFlags);
}
// Tell handlers to start processing new messages and transit from the startup state to the
@@ -143,20 +155,38 @@
}
@UnsupportedAppUsage
- private SmsBroadcastUndelivered(Context context) {
+ private SmsBroadcastUndelivered(Context context, FeatureFlags featureFlags) {
mResolver = context.getContentResolver();
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mUserManager = context.getSystemService(UserManager.class);
+ mFeatureFlags = featureFlags;
- if (userManager.isUserUnlocked()) {
+ UserHandle mainUser = getMainUser();
+ boolean isUserUnlocked = mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser() ?
+ mUserManager.isUserUnlocked(mainUser) : mUserManager.isUserUnlocked();
+ if (isUserUnlocked) {
new ScanRawTableThread(context).start();
} else {
IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_UNLOCKED);
- context.registerReceiver(mBroadcastReceiver, userFilter);
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ context.registerReceiverAsUser(
+ mBroadcastReceiver, mainUser, userFilter, null, null);
+ } else {
+ context.registerReceiver(mBroadcastReceiver, userFilter);
+ }
}
}
+ /** Returns the MainUser, which is the user designated for sending SMS broadcasts. */
+ private UserHandle getMainUser() {
+ UserHandle mainUser = null;
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ mainUser = mUserManager.getMainUser();
+ }
+ return mainUser != null ? mainUser : UserHandle.SYSTEM;
+ }
+
/**
* Scan the raw table for complete SMS messages to broadcast, and old PDUs to delete.
*/
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 68c8bd5..e14613f 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -395,7 +395,7 @@
storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher, looper, mFeatureFlags);
mGsmDispatcher = new GsmSMSDispatcher(phone, this, mGsmInboundSmsHandler);
SmsBroadcastUndelivered.initialize(phone.getContext(),
- mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
InboundSmsHandler.registerNewMessageNotificationActionHandler(phone.getContext());
mCi.registerForOn(this, EVENT_RADIO_ON, null);
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index eaa0962..e66ea69 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -100,6 +100,7 @@
import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
+import com.android.internal.telephony.data.PhoneSwitcher.PhoneSwitcherCallback;
import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.metrics.DataCallSessionStats;
@@ -271,6 +272,9 @@
/** Event for response to data network validation request. */
private static final int EVENT_DATA_NETWORK_VALIDATION_RESPONSE = 29;
+ /** Event for preferred data subscription changed. */
+ private static final int EVENT_PREFERRED_DATA_SUBSCRIPTION_CHANGED = 30;
+
/** Invalid context id. */
private static final int INVALID_CID = -1;
@@ -591,6 +595,10 @@
@NonNull
private final DataNetworkController mDataNetworkController;
+ /** Phone switcher which is responsible to determine which phone to route network request. */
+ @NonNull
+ private final PhoneSwitcher mPhoneSwitcher;
+
/** Data network controller callback. */
@NonNull
private final DataNetworkController.DataNetworkControllerCallback
@@ -676,6 +684,13 @@
/** Whether the current data network is congested. */
private boolean mCongested = false;
+ /**
+ * Whether the current data network is on preferred data modem.
+ *
+ * @see PhoneSwitcher#getPreferredDataPhoneId()
+ */
+ private boolean mOnPreferredDataPhone;
+
/** The network requests associated with this data network */
@NonNull
private final NetworkRequestList mAttachedNetworkRequestList =
@@ -815,6 +830,12 @@
private PreciseDataConnectionState mPreciseDataConnectionState;
/**
+ * Callback to listen event from {@link PhoneSwitcher}.
+ */
+ @NonNull
+ private PhoneSwitcherCallback mPhoneSwitcherCallback;
+
+ /**
* The network bandwidth.
*/
public static class NetworkBandwidth {
@@ -1027,6 +1048,8 @@
mAccessNetworksManager = phone.getAccessNetworksManager();
mVcnManager = mPhone.getContext().getSystemService(VcnManager.class);
mDataNetworkController = phone.getDataNetworkController();
+ mPhoneSwitcher = PhoneSwitcher.getInstance();
+ mOnPreferredDataPhone = phone.getPhoneId() == mPhoneSwitcher.getPreferredDataPhoneId();
mDataNetworkControllerCallback = new DataNetworkController.DataNetworkControllerCallback(
getHandler()::post) {
@Override
@@ -1156,14 +1179,25 @@
configBuilder.setNat64DetectionEnabled(false);
}
- final NetworkFactory factory = PhoneFactory.getNetworkFactory(
- mPhone.getPhoneId());
- final NetworkProvider provider = (null == factory) ? null : factory.getProvider();
+ NetworkProvider provider;
+ if (mFlags.supportNetworkProvider()) {
+ provider = PhoneFactory.getNetworkProvider();
+ } else {
+ final NetworkFactory factory = PhoneFactory.getNetworkFactory(
+ mPhone.getPhoneId());
+ provider = (null == factory) ? null : factory.getProvider();
+ }
- mNetworkScore = new NetworkScore.Builder()
- .setKeepConnectedReason(isHandoverInProgress()
+ NetworkScore.Builder builder = new NetworkScore.Builder()
+ .setKeepConnectedReason(isHandoverInProgress()
? NetworkScore.KEEP_CONNECTED_FOR_HANDOVER
- : NetworkScore.KEEP_CONNECTED_NONE).build();
+ : NetworkScore.KEEP_CONNECTED_NONE);
+ if (mFlags.supportNetworkProvider()) {
+ builder.setTransportPrimary(mOnPreferredDataPhone);
+ }
+ mNetworkScore = builder.build();
+ logl("mNetworkScore: isPrimary=" + mNetworkScore.isTransportPrimary()
+ + ", keepConnectedReason=" + mNetworkScore.getKeepConnectedReason());
return new TelephonyNetworkAgent(mPhone, getHandler().getLooper(), this,
mNetworkScore, configBuilder.build(), provider,
@@ -1225,6 +1259,16 @@
mDataNetworkController.getDataSettingsManager()
.registerCallback(mDataSettingsManagerCallback);
+ if (mFlags.supportNetworkProvider()) {
+ mPhoneSwitcherCallback = new PhoneSwitcherCallback(Runnable::run) {
+ @Override
+ public void onPreferredDataPhoneIdChanged(int phoneId) {
+ sendMessage(EVENT_PREFERRED_DATA_SUBSCRIPTION_CHANGED, phoneId, 0);
+ }
+ };
+ mPhoneSwitcher.registerCallback(mPhoneSwitcherCallback);
+ }
+
mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
@@ -1318,6 +1362,9 @@
mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
getHandler());
+ if (mFlags.supportNetworkProvider()) {
+ mPhoneSwitcher.unregisterCallback(mPhoneSwitcherCallback);
+ }
mDataNetworkController.getDataSettingsManager()
.unregisterCallback(mDataSettingsManagerCallback);
mRil.unregisterForPcoData(getHandler());
@@ -1351,13 +1398,13 @@
}
case EVENT_ATTACH_NETWORK_REQUEST: {
onAttachNetworkRequests((NetworkRequestList) msg.obj);
- updateNetworkScore(isHandoverInProgress());
+ updateNetworkScore();
break;
}
case EVENT_DETACH_NETWORK_REQUEST: {
onDetachNetworkRequest((TelephonyNetworkRequest) msg.obj,
msg.arg1 != 0 /* shouldRetry */);
- updateNetworkScore(isHandoverInProgress());
+ updateNetworkScore();
break;
}
case EVENT_DETACH_ALL_NETWORK_REQUESTS: {
@@ -1428,6 +1475,12 @@
// handle the resultCode in response for the request.
handleDataNetworkValidationRequestResultCode(msg.arg1 /* resultCode */);
break;
+ case EVENT_PREFERRED_DATA_SUBSCRIPTION_CHANGED:
+ mOnPreferredDataPhone = mPhone.getPhoneId() == msg.arg1;
+ logl("Preferred data phone id changed to " + msg.arg1
+ + ", mOnPreferredDataPhone=" + mOnPreferredDataPhone);
+ updateNetworkScore();
+ break;
default:
loge("Unhandled event " + eventToString(msg.what));
break;
@@ -3314,6 +3367,12 @@
return mLinkStatus;
}
+ /**
+ * Update the network score and report to connectivity service if necessary.
+ */
+ private void updateNetworkScore() {
+ updateNetworkScore(isHandoverInProgress());
+ }
/**
* Update the network score and report to connectivity service if necessary.
@@ -3323,10 +3382,18 @@
private void updateNetworkScore(boolean keepConnectedForHandover) {
int connectedReason = keepConnectedForHandover
? NetworkScore.KEEP_CONNECTED_FOR_HANDOVER : NetworkScore.KEEP_CONNECTED_NONE;
- if (mNetworkScore.getKeepConnectedReason() != connectedReason) {
- mNetworkScore = new NetworkScore.Builder()
- .setKeepConnectedReason(connectedReason).build();
+ if (mNetworkScore.getKeepConnectedReason() != connectedReason
+ || (mFlags.supportNetworkProvider()
+ && mNetworkScore.isTransportPrimary() != mOnPreferredDataPhone)) {
+ NetworkScore.Builder builder = new NetworkScore.Builder()
+ .setKeepConnectedReason(connectedReason);
+ if (mFlags.supportNetworkProvider()) {
+ builder.setTransportPrimary(mOnPreferredDataPhone);
+ }
+ mNetworkScore = builder.build();
mNetworkAgent.sendNetworkScore(mNetworkScore);
+ logl("updateNetworkScore: isPrimary=" + mNetworkScore.isTransportPrimary()
+ + ", keepConnectedForHandover=" + keepConnectedForHandover);
}
}
@@ -3360,7 +3427,7 @@
public int getApnTypeNetworkCapability() {
if (!mAttachedNetworkRequestList.isEmpty()) {
// The highest priority network request is always at the top of list.
- return mAttachedNetworkRequestList.get(0).getApnTypeNetworkCapability();
+ return mAttachedNetworkRequestList.get(0).getHighestPriorityApnTypeNetworkCapability();
} else {
return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed()
.filter(cap -> DataUtils.networkCapabilityToApnType(cap)
@@ -4055,12 +4122,14 @@
pw.println("Tag: " + name());
pw.increaseIndent();
pw.println("mSubId=" + mSubId);
+ pw.println("mOnPreferredDataPhone=" + mOnPreferredDataPhone);
pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
pw.println("mLastKnownDataNetworkType=" + TelephonyManager
.getNetworkTypeName(mLastKnownDataNetworkType));
pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
pw.println("mNetworkScore=" + mNetworkScore);
+ pw.println("keepConnectedReason=" + mNetworkScore.getKeepConnectedReason());
pw.println("mDataAllowedReason=" + mDataAllowedReason);
pw.println("mPduSessionId=" + mPduSessionId);
pw.println("mDataProfile=" + mDataProfile);
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 010e0fe..1b0af47 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1299,6 +1299,13 @@
* @param networkRequest The network request.
*/
private void onAddNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
+ // TelephonyNetworkRequest at TelephonyNetworkProvider layer does not have config assigned
+ // (Because TelephonyNetworkProvider is a singleton across all SIMs. We are not able to
+ // retrieve the right carrier config for it.). So as soon as the request arrives
+ // DataNetworkController, we need to update the config in the request so it can update
+ // some of its config-dependent properties like request priority.
+ networkRequest.updateDataConfig(mDataConfigManager);
+
// To detect IMS back-to-back release-request anomaly event
if (mLastImsOperationIsRelease) {
mLastImsOperationIsRelease = false;
@@ -1579,7 +1586,7 @@
@NonNull TelephonyNetworkRequest networkRequest, DataEvaluationReason reason) {
DataEvaluation evaluation = new DataEvaluation(reason);
int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
- networkRequest.getApnTypeNetworkCapability());
+ networkRequest.getHighestPriorityApnTypeNetworkCapability());
// Check if the request can be satisfied by cellular network or satellite network.
if (mFeatureFlags.satelliteInternet()
@@ -1711,7 +1718,7 @@
if (mDataSettingsManager.isDataInitialized()) {
if (!mDataSettingsManager.isDataEnabled(DataUtils.networkCapabilityToApnType(
- networkRequest.getApnTypeNetworkCapability()))) {
+ networkRequest.getHighestPriorityApnTypeNetworkCapability()))) {
evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED);
}
} else {
@@ -1746,7 +1753,9 @@
// Check if request is unmetered (WiFi or unmetered APN).
evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
} else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- if (!networkRequest.isMeteredRequest()) {
+ boolean isMeteredRequest = mDataConfigManager.isAnyMeteredCapability(
+ networkRequest.getCapabilities(), mServiceState.getDataRoaming());
+ if (!isMeteredRequest) {
evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
}
}
@@ -1985,7 +1994,7 @@
if (mAllNetworkRequestList.stream()
.filter(request -> dataNetwork.getTransport()
== mAccessNetworksManager.getPreferredTransportByNetworkCapability(
- request.getApnTypeNetworkCapability()))
+ request.getHighestPriorityApnTypeNetworkCapability()))
.filter(request
-> !hasCapabilityExemptsFromSinglePdnRule(request.getCapabilities()))
.anyMatch(request -> request.getPriority() > dataNetwork.getPriority())) {
@@ -2507,6 +2516,30 @@
}
private void onRemoveNetworkRequest(@NonNull TelephonyNetworkRequest request) {
+ if (mFeatureFlags.supportNetworkProvider()) {
+ if (!mAllNetworkRequestList.remove(request)) {
+ loge("onRemoveNetworkRequest: Network request does not exist. " + request);
+ return;
+ }
+
+ if (request.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
+ mImsThrottleCounter.addOccurrence();
+ mLastReleasedImsRequestCapabilities = request.getCapabilities();
+ mLastImsOperationIsRelease = true;
+ }
+
+ if (request.getAttachedNetwork() != null) {
+ request.getAttachedNetwork().detachNetworkRequest(
+ request, false /* shouldRetry */);
+ }
+
+ request.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
+ request.setEvaluation(null);
+
+ log("onRemoveNetworkRequest: Removed " + request);
+ return;
+ }
+
// The request generated from telephony network factory does not contain the information
// the original request has, for example, attached data network. We need to find the
// original one.
@@ -2527,7 +2560,7 @@
if (networkRequest.getAttachedNetwork() != null) {
networkRequest.getAttachedNetwork().detachNetworkRequest(
- networkRequest, false /* shouldRetry */);
+ networkRequest, false /* shouldRetry */);
}
log("onRemoveNetworkRequest: Removed " + networkRequest);
}
@@ -2869,7 +2902,7 @@
}
int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
- networkRequestList.get(0).getApnTypeNetworkCapability());
+ networkRequestList.get(0).getHighestPriorityApnTypeNetworkCapability());
logl("Creating data network on "
+ AccessNetworkConstants.transportTypeToString(transport) + " with " + dataProfile
+ ", and attaching " + networkRequestList.size() + " network requests to it.");
@@ -3141,7 +3174,8 @@
log("onDataNetworkSetupRetry: Request list:" + requestList);
TelephonyNetworkRequest telephonyNetworkRequest = requestList.get(0);
- int networkCapability = telephonyNetworkRequest.getApnTypeNetworkCapability();
+ int networkCapability = telephonyNetworkRequest
+ .getHighestPriorityApnTypeNetworkCapability();
int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
networkCapability);
if (preferredTransport != dataSetupRetryEntry.transport) {
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index d35e9e8..2a009c8 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -1277,7 +1277,8 @@
return;
}
for (NetworkRequestList networkRequestList : groupedNetworkRequestLists) {
- int capability = networkRequestList.get(0).getApnTypeNetworkCapability();
+ int capability = networkRequestList.get(0)
+ .getHighestPrioritySupportedNetworkCapability();
if (retryRule.canBeMatched(capability, cause)) {
// Check if there is already a similar network request retry scheduled.
if (isSimilarNetworkRequestRetryScheduled(
@@ -1492,7 +1493,8 @@
mPhone.getCarrierId());
continue;
}
- if (entry.networkRequestList.get(0).getApnTypeNetworkCapability()
+ if (entry.networkRequestList.get(0)
+ .getHighestPrioritySupportedNetworkCapability()
== networkCapability
&& entry.appliedDataRetryRule.equals(dataRetryRule)) {
if (entry.getState() == DataRetryEntry.RETRY_STATE_SUCCEEDED
@@ -1779,8 +1781,9 @@
mPhone.getCarrierId());
continue;
}
- if (entry.networkRequestList.get(0).getApnTypeNetworkCapability()
- == networkRequest.getApnTypeNetworkCapability()
+ if (entry.networkRequestList.get(0)
+ .getHighestPrioritySupportedNetworkCapability()
+ == networkRequest.getHighestPrioritySupportedNetworkCapability()
&& entry.transport == transport) {
return true;
}
diff --git a/src/java/com/android/internal/telephony/data/DataSettingsManager.java b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
index fb112d9..0b9ac27 100644
--- a/src/java/com/android/internal/telephony/data/DataSettingsManager.java
+++ b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
@@ -326,7 +326,7 @@
@Override
public void onUserDataEnabledChanged(boolean enabled,
@NonNull String callingPackage) {
- log("phone" + phone.getPhoneId() + " onUserDataEnabledChanged "
+ log("phone " + phone.getPhoneId() + " onUserDataEnabledChanged "
+ enabled + " by " + callingPackage
+ ", reevaluating mobile data policies");
DataSettingsManager.this.updateDataEnabledAndNotify(
@@ -335,6 +335,16 @@
});
}
}
+ SubscriptionManagerService.getInstance().registerCallback(
+ new SubscriptionManagerService.SubscriptionManagerServiceCallback(this::post) {
+ @Override
+ public void onDefaultDataSubscriptionChanged(int subId) {
+ log((subId == mSubId ? "Became" : "Not")
+ + " default data sub, reevaluating mobile data policies");
+ DataSettingsManager.this.updateDataEnabledAndNotify(
+ TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
+ }
+ });
updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN);
}
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index 27b4331..1005bb7 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -30,6 +30,7 @@
import static java.util.Arrays.copyOf;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
@@ -63,6 +64,7 @@
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
import android.util.SparseIntArray;
@@ -89,6 +91,7 @@
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
import com.android.internal.telephony.subscription.SubscriptionManagerService.WatchedInt;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -182,6 +185,27 @@
}
}
+ /**
+ * Callback from PhoneSwitcher
+ */
+ public static class PhoneSwitcherCallback extends DataCallback {
+ /**
+ * Constructor
+ *
+ * @param executor The executor of the callback.
+ */
+ public PhoneSwitcherCallback(@NonNull @CallbackExecutor Executor executor) {
+ super(executor);
+ }
+
+ /**
+ * Called when preferred data phone id changed.
+ *
+ * @param phoneId The phone id of the preferred data.
+ */
+ public void onPreferredDataPhoneIdChanged(int phoneId) {}
+ }
+
@NonNull
private final NetworkRequestList mNetworkRequestList = new NetworkRequestList();
protected final RegistrantList mActivePhoneRegistrants;
@@ -260,6 +284,10 @@
private ISetOpportunisticDataCallback mSetOpptSubCallback;
+ /** Phone switcher callbacks. */
+ @NonNull
+ private final Set<PhoneSwitcherCallback> mPhoneSwitcherCallbacks = new ArraySet<>();
+
private static final int EVENT_PRIMARY_DATA_SUB_CHANGED = 101;
protected static final int EVENT_SUBSCRIPTION_CHANGED = 102;
private static final int EVENT_REQUEST_NETWORK = 103;
@@ -467,6 +495,24 @@
}
}
+ /**
+ * Register the callback for receiving information from {@link PhoneSwitcher}.
+ *
+ * @param callback The callback.
+ */
+ public void registerCallback(@NonNull PhoneSwitcherCallback callback) {
+ mPhoneSwitcherCallbacks.add(callback);
+ }
+
+ /**
+ * Unregister the callback for receiving information from {@link PhoneSwitcher}.
+ *
+ * @param callback The callback.
+ */
+ public void unregisterCallback(@NonNull PhoneSwitcherCallback callback) {
+ mPhoneSwitcherCallbacks.remove(callback);
+ }
+
private void evaluateIfImmediateDataSwitchIsNeeded(String evaluationReason, int switchReason) {
if (onEvaluate(REQUESTS_UNCHANGED, evaluationReason)) {
logDataSwitchEvent(mPreferredDataSubId.get(),
@@ -587,54 +633,54 @@
};
mAutoDataSwitchController = new AutoDataSwitchController(context, looper, this,
mFlags, mAutoDataSwitchCallback);
-
- mContext.registerReceiver(mDefaultDataChangedReceiver,
- new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
+ if (!mFlags.ddsCallback()) {
+ mContext.registerReceiver(mDefaultDataChangedReceiver,
+ new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
+ } else {
+ mSubscriptionManagerService.registerCallback(new SubscriptionManagerServiceCallback(
+ this::post) {
+ @Override
+ public void onDefaultDataSubscriptionChanged(int subId) {
+ evaluateIfImmediateDataSwitchIsNeeded("default data sub changed to " + subId,
+ DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
+ }
+ });
+ }
PhoneConfigurationManager.registerForMultiSimConfigChange(
this, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, this);
- final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
- .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
- .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
- .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
- .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
- .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
- .setNetworkSpecifier(new MatchAllNetworkSpecifier());
+ if (!mFlags.supportNetworkProvider()) {
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
+ .setNetworkSpecifier(new MatchAllNetworkSpecifier());
+ TelephonyNetworkRequest.getAllSupportedNetworkCapabilities()
+ .forEach(builder::addCapability);
- if (mFlags.satelliteInternet()) {
- // TODO: b/328622096 remove the try/catch
- try {
- builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
- } catch (IllegalArgumentException exception) {
- loge("TRANSPORT_SATELLITE is not supported.");
+ if (mFlags.satelliteInternet()) {
+ // TODO: b/328622096 remove the try/catch
+ try {
+ builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+ } catch (IllegalArgumentException exception) {
+ loge("TRANSPORT_SATELLITE is not supported.");
+ }
}
- }
- NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
- builder.build(), this);
- // we want to see all requests
- networkFactory.registerIgnoringScore();
+ NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
+ builder.build(), this);
+ // we want to see all requests
+ networkFactory.registerIgnoringScore();
+ }
updateHalCommandToUse();
@@ -1054,11 +1100,12 @@
return false;
}
+ // TODO: Remove after removing TelephonyNetworkFactory
private static class PhoneSwitcherNetworkRequestListener extends NetworkFactory {
private final PhoneSwitcher mPhoneSwitcher;
public PhoneSwitcherNetworkRequestListener (Looper l, Context c,
NetworkCapabilities nc, PhoneSwitcher ps) {
- super(l, c, "PhoneSwitcherNetworkRequstListener", nc);
+ super(l, c, "PhoneSwitcherNetworkRequestListener", nc);
mPhoneSwitcher = ps;
}
@@ -1079,7 +1126,13 @@
}
}
- private void onRequestNetwork(NetworkRequest networkRequest) {
+ /**
+ * Called when receiving a network request.
+ *
+ * @param networkRequest The network request.
+ */
+ // TODO: Transform to TelephonyNetworkRequest after removing TelephonyNetworkFactory
+ public void onRequestNetwork(@NonNull NetworkRequest networkRequest) {
TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
networkRequest, PhoneFactory.getDefaultPhone(), mFlags);
if (!mNetworkRequestList.contains(telephonyNetworkRequest)) {
@@ -1088,7 +1141,13 @@
}
}
- private void onReleaseNetwork(NetworkRequest networkRequest) {
+ /**
+ * Called when releasing a network request.
+ *
+ * @param networkRequest The network request to release.
+ */
+ // TODO: Transform to TelephonyNetworkRequest after removing TelephonyNetworkFactory
+ public void onReleaseNetwork(@NonNull NetworkRequest networkRequest) {
TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
networkRequest, PhoneFactory.getDefaultPhone(), mFlags);
if (mNetworkRequestList.remove(telephonyNetworkRequest)) {
@@ -1102,18 +1161,6 @@
mDefaultNetworkCallback.mSwitchReason = reason;
}
- private void collectRequestNetworkMetrics(NetworkRequest networkRequest) {
- // Request network for MMS will temporary disable the network on default data subscription,
- // this only happen on multi-sim device.
- if (mActiveModemCount > 1 && networkRequest.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_MMS)) {
- OnDemandDataSwitch onDemandDataSwitch = new OnDemandDataSwitch();
- onDemandDataSwitch.apn = TelephonyEvent.ApnType.APN_TYPE_MMS;
- onDemandDataSwitch.state = TelephonyEvent.EventState.EVENT_STATE_START;
- TelephonyMetrics.getInstance().writeOnDemandDataSwitch(onDemandDataSwitch);
- }
- }
-
private void collectReleaseNetworkMetrics(NetworkRequest networkRequest) {
// Release network for MMS will recover the network on default data subscription, this only
// happen on multi-sim device.
@@ -1562,6 +1609,7 @@
* If preferred phone changes, or phone activation status changes, registrants
* will be notified.
*/
+ // TODO: Remove after removing TelephonyNetworkFactory
public void registerForActivePhoneSwitch(Handler h, int what, Object o) {
Registrant r = new Registrant(h, what, o);
mActivePhoneRegistrants.add(r);
@@ -1983,6 +2031,10 @@
// Notify all registrants
mActivePhoneRegistrants.notifyRegistrants();
notifyPreferredDataSubIdChanged();
+ if (mFlags.supportNetworkProvider()) {
+ mPhoneSwitcherCallbacks.forEach(callback -> callback.invokeFromExecutor(
+ () -> callback.onPreferredDataPhoneIdChanged(phoneId)));
+ }
}
private boolean isPhoneIdValidForRetry(int phoneId) {
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
index ca34ca7..7d1746c 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
@@ -138,31 +138,19 @@
public NetworkCapabilities makeNetworkFilter(int subscriptionId) {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
.addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
.addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
.addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
.addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
.addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
- .setSubscriptionId(subscriptionId).build());
+ .setSubscriptionId(subscriptionId).build());
+ TelephonyNetworkRequest.getAllSupportedNetworkCapabilities()
+ .forEach(builder::addCapability);
if (mFlags.satelliteInternet()) {
// TODO: b/328622096 remove the try/catch
@@ -206,7 +194,7 @@
private int getTransportTypeFromNetworkRequest(TelephonyNetworkRequest networkRequest) {
int transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
- int capability = networkRequest.getApnTypeNetworkCapability();
+ int capability = networkRequest.getHighestPriorityApnTypeNetworkCapability();
if (capability >= 0) {
transport = mAccessNetworksManager
.getPreferredTransportByNetworkCapability(capability);
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkProvider.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkProvider.java
new file mode 100644
index 0000000..63edefa
--- /dev/null
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkProvider.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.data;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkAgent;
+import android.net.NetworkCapabilities;
+import android.net.NetworkProvider;
+import android.net.NetworkProvider.NetworkOfferCallback;
+import android.net.NetworkRequest;
+import android.net.NetworkScore;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.SubscriptionManager;
+import android.util.ArrayMap;
+import android.util.LocalLog;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.data.PhoneSwitcher.PhoneSwitcherCallback;
+import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Map;
+
+/**
+ * TelephonyNetworkProvider is a singleton network provider responsible for providing all
+ * telephony related networks including networks on cellular and IWLAN across all active SIMs.
+ */
+public class TelephonyNetworkProvider extends NetworkProvider implements NetworkOfferCallback {
+
+ public final String LOG_TAG = "TNP";
+
+ /** Android feature flags */
+ @NonNull
+ private final FeatureFlags mFlags;
+
+ /** The event handler */
+ @NonNull
+ private final Handler mHandler;
+
+ /** Phone switcher responsible to determine request routing on dual-SIM device */
+ @NonNull
+ private final PhoneSwitcher mPhoneSwitcher;
+
+ /** Network requests map. Key is the network request, value is the phone id it applies to. */
+ private final Map<TelephonyNetworkRequest, Integer> mNetworkRequests = new ArrayMap<>();
+
+ /** Persisted log */
+ @NonNull
+ private final LocalLog mLocalLog = new LocalLog(256);
+
+ /**
+ * Constructor
+ *
+ * @param looper The looper for event handling
+ * @param context The context
+ * @param featureFlags Android feature flags
+ */
+ public TelephonyNetworkProvider(@NonNull Looper looper, @NonNull Context context,
+ @NonNull FeatureFlags featureFlags) {
+ super(context, looper, TelephonyNetworkProvider.class.getSimpleName());
+
+ mFlags = featureFlags;
+ mHandler = new Handler(looper);
+ mPhoneSwitcher = PhoneSwitcher.getInstance();
+
+ // Register for subscription changed event.
+ context.getSystemService(SubscriptionManager.class)
+ .addOnSubscriptionsChangedListener(mHandler::post,
+ new SubscriptionManager.OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ logl("Subscription changed.");
+ reevaluateNetworkRequests("subscription changed");
+ }});
+
+ // Register for preferred data changed event
+ mPhoneSwitcher.registerCallback(new PhoneSwitcherCallback(mHandler::post) {
+ @Override
+ public void onPreferredDataPhoneIdChanged(int phoneId) {
+ logl("Preferred data sub phone id changed to " + phoneId);
+ reevaluateNetworkRequests("Preferred data subscription changed");
+ }
+ });
+
+ // Register the provider and tell connectivity service what network offer telephony can
+ // provide
+ ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
+ if (cm != null) {
+ cm.registerNetworkProvider(this);
+ NetworkCapabilities caps = makeNetworkFilter();
+ registerNetworkOffer(new NetworkScore.Builder().build(), caps, mHandler::post, this);
+ logl("registerNetworkOffer: " + caps);
+ }
+ }
+
+ /**
+ * Get the phone id for the network request.
+ *
+ * @param request The network request
+ * @return The id of the phone where the network request should route to. If the network request
+ * can't be applied to any phone, {@link SubscriptionManager#INVALID_PHONE_INDEX} will be
+ * returned.
+ */
+ private int getPhoneIdForNetworkRequest(@NonNull TelephonyNetworkRequest request) {
+ for (Phone phone : PhoneFactory.getPhones()) {
+ int phoneId = phone.getPhoneId();
+ if (mPhoneSwitcher.shouldApplyNetworkRequest(request, phoneId)) {
+ // Return here because by design the network request can be only applied to *one*
+ // phone. It's not possible to have two DataNetworkController to attempt to setup
+ // data call for the same network request.
+ return phoneId;
+ }
+ }
+
+ return SubscriptionManager.INVALID_PHONE_INDEX;
+ }
+
+ /**
+ * Called when receiving a network request from connectivity service. This is the entry point
+ * that a network request arrives telephony.
+ *
+ * @param request The network request
+ */
+ @Override
+ public void onNetworkNeeded(@NonNull NetworkRequest request) {
+ TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(request, mFlags);
+ if (mNetworkRequests.containsKey(networkRequest)) {
+ loge("Duplicate network request " + networkRequest);
+ return;
+ }
+
+ mPhoneSwitcher.onRequestNetwork(request);
+
+ // Check with PhoneSwitcher to see where to route the request.
+ int phoneId = getPhoneIdForNetworkRequest(networkRequest);
+ if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) {
+ logl("onNetworkNeeded: phoneId=" + phoneId + ", " + networkRequest);
+ PhoneFactory.getPhone(phoneId).getDataNetworkController()
+ .addNetworkRequest(networkRequest);
+ } else {
+ logl("onNetworkNeeded: Not applied. " + networkRequest);
+ }
+
+ mNetworkRequests.put(networkRequest, phoneId);
+ }
+
+ /**
+ * Called when connectivity service remove the network request. Note this will not result in
+ * network tear down. Even there is no network request attached to the network, telephony still
+ * relies on {@link NetworkAgent#onNetworkUnwanted()} to tear down the network.
+ *
+ * @param request The released network request
+ *
+ * @see TelephonyNetworkAgent#onNetworkUnwanted()
+ */
+ @Override
+ public void onNetworkUnneeded(@NonNull NetworkRequest request) {
+ TelephonyNetworkRequest networkRequest = mNetworkRequests.keySet().stream()
+ .filter(r -> r.getNativeNetworkRequest().equals(request))
+ .findFirst()
+ .orElse(null);
+ if (networkRequest == null) {
+ loge("onNetworkUnneeded: Cannot find " + request);
+ return;
+ }
+
+ mPhoneSwitcher.onReleaseNetwork(request);
+ int phoneId = mNetworkRequests.remove(networkRequest);
+ Phone phone = PhoneFactory.getPhone(phoneId);
+ if (phone != null) {
+ logl("onNetworkUnneeded: phoneId=" + phoneId + ", " + networkRequest);
+ // Remove the network request from network controller. Note this will not result
+ // in disconnecting the data network.
+ phone.getDataNetworkController().removeNetworkRequest(networkRequest);
+ } else {
+ loge("onNetworkUnneeded: Unable to get phone. phoneId=" + phoneId);
+ }
+ }
+
+ /**
+ * Re-evaluate the existing networks and re-apply to the applicable phone.
+ *
+ * @param reason The reason for re-evaluating network request. Note this can be only used for
+ * debugging message purposes.
+ */
+ private void reevaluateNetworkRequests(@NonNull String reason) {
+ logl("reevaluateNetworkRequests: " + reason + ".");
+ mNetworkRequests.forEach((request, oldPhoneId) -> {
+ int newPhoneId = getPhoneIdForNetworkRequest(request);
+ if (newPhoneId != oldPhoneId) {
+ // We need to move the request from old phone to the new phone. This can happen
+ // when the user changes the default data subscription.
+
+ if (oldPhoneId != SubscriptionManager.INVALID_PHONE_INDEX) {
+ PhoneFactory.getPhone(oldPhoneId).getDataNetworkController()
+ .removeNetworkRequest(request);
+ }
+
+ if (newPhoneId != SubscriptionManager.INVALID_PHONE_INDEX) {
+ PhoneFactory.getPhone(newPhoneId).getDataNetworkController()
+ .addNetworkRequest(request);
+ }
+
+ logl("Request moved. phoneId " + oldPhoneId + " -> " + newPhoneId + " " + request);
+ mNetworkRequests.put(request, newPhoneId);
+ }
+ });
+ }
+
+ /**
+ * @return The maximal network capabilities that telephony can support.
+ */
+ @NonNull
+ private NetworkCapabilities makeNetworkFilter() {
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
+ .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
+ // Ideally TelephonyNetworkProvider should only accept TelephonyNetworkSpecifier,
+ // but this network provider is a singleton across all SIMs, and
+ // TelephonyNetworkSpecifier can't accept more than one subscription id, so we let
+ // the provider accepts all different kinds NetworkSpecifier.
+ .setNetworkSpecifier(new MatchAllNetworkSpecifier());
+ TelephonyNetworkRequest.getAllSupportedNetworkCapabilities()
+ .forEach(builder::addCapability);
+
+ // TODO: b/328622096 remove the try/catch
+ try {
+ builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
+ } catch (IllegalArgumentException exception) {
+ log("TRANSPORT_SATELLITE is not supported.");
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Log debug message to logcat.
+ *
+ * @param s The debug message to log
+ */
+ private void log(@NonNull String s) {
+ Rlog.d(LOG_TAG, s);
+ }
+
+ /**
+ * Log error debug messages to logcat.
+ * @param s The error debug messages
+ */
+ private void loge(@NonNull String s) {
+ Rlog.e(LOG_TAG, s);
+ }
+
+ /**
+ * Log to logcat and persisted local log.
+ *
+ * @param s The debug message to log
+ */
+ private void logl(@NonNull String s) {
+ log(s);
+ mLocalLog.log(s);
+ }
+
+ /**
+ * Dump the state of telephony network provider.
+ *
+ * @param fd File descriptor
+ * @param writer Print writer
+ * @param args Arguments
+ */
+ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
+ pw.println("TelephonyNetworkProvider:");
+ pw.increaseIndent();
+
+ pw.println("mPreferredDataPhoneId=" + mPhoneSwitcher.getPreferredDataPhoneId());
+ int defaultDataSubId = SubscriptionManagerService.getInstance().getDefaultDataSubId();
+ pw.println("DefaultDataSubId=" + defaultDataSubId);
+ pw.println("DefaultDataPhoneId=" + SubscriptionManagerService.getInstance()
+ .getPhoneId(defaultDataSubId));
+
+ pw.println("Registered capabilities: " + makeNetworkFilter());
+ pw.println("Network requests:");
+ pw.increaseIndent();
+ for (Phone phone : PhoneFactory.getPhones()) {
+ pw.println("Phone " + phone.getPhoneId() + ":");
+ pw.increaseIndent();
+ mNetworkRequests.forEach((request, phoneId) -> {
+ if (phoneId == phone.getPhoneId()) {
+ pw.println(request);
+ }
+ });
+ pw.decreaseIndent();
+ }
+ pw.println("Not applied requests:");
+ pw.increaseIndent();
+ mNetworkRequests.forEach((request, phoneId) -> {
+ if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
+ pw.println(request);
+ }
+ });
+ pw.decreaseIndent();
+ pw.decreaseIndent();
+ pw.println();
+ pw.println("Local logs:");
+ pw.increaseIndent();
+ mLocalLog.dump(fd, pw, args);
+ pw.decreaseIndent();
+ pw.decreaseIndent();
+ }
+}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
index 117eb36..ca1ca21 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
@@ -137,10 +137,6 @@
CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN)
);
- /** The phone instance. */
- @NonNull
- private final Phone mPhone;
-
/**
* Native network request from the clients. See {@link NetworkRequest};
*/
@@ -164,8 +160,8 @@
/**
* Data config manager for retrieving data config.
*/
- @NonNull
- private final DataConfigManager mDataConfigManager;
+ @Nullable
+ private DataConfigManager mDataConfigManager;
/**
* The attached data network. Note that the data network could be in any state. {@code null}
@@ -205,7 +201,19 @@
*/
public TelephonyNetworkRequest(@NonNull NetworkRequest request, @NonNull Phone phone,
@NonNull FeatureFlags featureFlags) {
- mPhone = phone;
+ this(request, featureFlags);
+ mDataConfigManager = phone.getDataNetworkController().getDataConfigManager();
+ updatePriority();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param request The native network request from the clients.
+ * @param featureFlags The feature flag
+ */
+ public TelephonyNetworkRequest(@NonNull NetworkRequest request,
+ @NonNull FeatureFlags featureFlags) {
mNativeNetworkRequest = request;
mFeatureFlags = featureFlags;
@@ -222,7 +230,15 @@
// to satisfy it.
mState = REQUEST_STATE_UNSATISFIED;
mCreatedTimeMillis = SystemClock.elapsedRealtime();
- mDataConfigManager = phone.getDataNetworkController().getDataConfigManager();
+ }
+
+ /**
+ * Update the associated data config manager.
+ *
+ * @param dataConfigManager Data config manager
+ */
+ public void updateDataConfig(@NonNull DataConfigManager dataConfigManager) {
+ mDataConfigManager = dataConfigManager;
updatePriority();
}
@@ -315,13 +331,15 @@
if (mNativeNetworkRequest.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
&& !mNativeNetworkRequest.hasTransport(
NetworkCapabilities.TRANSPORT_SATELLITE)) {
- if (Arrays.stream(getCapabilities()).noneMatch(mDataConfigManager
- .getForcedCellularTransportCapabilities()::contains)) {
- // If the request is explicitly for the cellular, then the data profile
- // needs to support cellular.
- if (!dataProfile.getApnSetting().isForInfrastructure(
- ApnSetting.INFRASTRUCTURE_CELLULAR)) {
- return false;
+ if (mDataConfigManager != null) {
+ if (Arrays.stream(getCapabilities()).noneMatch(mDataConfigManager
+ .getForcedCellularTransportCapabilities()::contains)) {
+ // If the request is explicitly for the cellular, then the data profile
+ // needs to support cellular.
+ if (!dataProfile.getApnSetting().isForInfrastructure(
+ ApnSetting.INFRASTRUCTURE_CELLULAR)) {
+ return false;
+ }
}
}
} else if (mNativeNetworkRequest.hasTransport(
@@ -371,10 +389,12 @@
* Update the priority from data config manager.
*/
public void updatePriority() {
- mPriority = Arrays.stream(mNativeNetworkRequest.getCapabilities())
- .map(mDataConfigManager::getNetworkCapabilityPriority)
- .max()
- .orElse(0);
+ if (mDataConfigManager != null) {
+ mPriority = Arrays.stream(mNativeNetworkRequest.getCapabilities())
+ .map(mDataConfigManager::getNetworkCapabilityPriority)
+ .max()
+ .orElse(0);
+ }
}
/**
@@ -385,13 +405,41 @@
* if there is no APN type capabilities in this network request.
*/
@NetCapability
- public int getApnTypeNetworkCapability() {
+ public int getHighestPriorityApnTypeNetworkCapability() {
if (!hasAttribute(CAPABILITY_ATTRIBUTE_APN_SETTING)) return -1;
+ if (mDataConfigManager == null) return -1;
return Arrays.stream(getCapabilities()).boxed()
.filter(cap -> DataUtils.networkCapabilityToApnType(cap) != ApnSetting.TYPE_NONE)
.max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority))
.orElse(-1);
}
+
+ /**
+ * A parent set of {@link #getHighestPriorityApnTypeNetworkCapability()}.
+ * Get the network capability from the network request that can lead to data setup. If there are
+ * multiple capabilities, the highest priority one will be returned.
+ *
+ * @return The highest priority traffic descriptor type network capability from this network
+ * request. -1 if there is no traffic descriptor type capabilities in this network request.
+ */
+ @NetCapability
+ public int getHighestPrioritySupportedNetworkCapability() {
+ if (mDataConfigManager == null) return -1;
+ return Arrays.stream(getCapabilities()).boxed()
+ .filter(CAPABILITY_ATTRIBUTE_MAP::containsKey)
+ .max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority))
+ .orElse(-1);
+ }
+
+ /**
+ * @return Get all the network capabilities that can lead to data setup.
+ */
+ @NonNull
+ @NetCapability
+ public static List<Integer> getAllSupportedNetworkCapabilities() {
+ return CAPABILITY_ATTRIBUTE_MAP.keySet().stream().toList();
+ }
+
/**
* @return The native network request.
*/
@@ -440,7 +488,7 @@
*
* @param evaluation The data evaluation result.
*/
- public void setEvaluation(@NonNull DataEvaluation evaluation) {
+ public void setEvaluation(@Nullable DataEvaluation evaluation) {
mEvaluation = evaluation;
}
@@ -461,14 +509,6 @@
}
/**
- * @return {@code true} if this network request can result in bringing up a metered network.
- */
- public boolean isMeteredRequest() {
- return mDataConfigManager.isAnyMeteredCapability(
- getCapabilities(), mPhone.getServiceState().getDataRoaming());
- }
-
- /**
* Get Os/App id from the network request.
*
* @return Os/App id. {@code null} if the request does not have traffic descriptor based network
@@ -521,7 +561,7 @@
return "[" + mNativeNetworkRequest + ", mPriority=" + mPriority
+ ", state=" + requestStateToString(mState)
+ ", mAttachedDataNetwork=" + (mAttachedDataNetwork != null
- ? mAttachedDataNetwork.name() : null) + ", isMetered=" + isMeteredRequest()
+ ? mAttachedDataNetwork.name() : null)
+ ", created time=" + DataUtils.elapsedTimeToString(mCreatedTimeMillis)
+ ", evaluation result=" + mEvaluation + "]";
}
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index 1a5b99e..59bc980 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -837,7 +837,7 @@
subscription,
switchAfterDownload,
forceDeactivateSim,
- resolvedBundle,
+ addCallingPackageToBundle(resolvedBundle, callingPackage),
new EuiccConnector.DownloadCommandCallback() {
@Override
public void onDownloadComplete(DownloadSubscriptionResult result) {
@@ -936,6 +936,13 @@
});
}
+ private static Bundle addCallingPackageToBundle(
+ @Nullable Bundle resolvedBundle, String callingPackage) {
+ resolvedBundle = resolvedBundle == null ? new Bundle() : resolvedBundle;
+ resolvedBundle.putString(EuiccService.EXTRA_PACKAGE_NAME, callingPackage);
+ return resolvedBundle;
+ }
+
/**
* Blocking call to {@link EuiccService#onGetEuiccProfileInfoList} of the eUICC with card ID
* {@code cardId}.
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index a83cd06..2367ef5 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -1147,7 +1147,8 @@
session.vonrEnabled,
session.isNtn,
session.supportsBusinessCallComposer,
- session.callComposerStatus);
+ session.callComposerStatus,
+ session.preciseCallStateOnSetup);
}
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index 911424e..b6a26c6 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -26,6 +26,16 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DIALING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_HOLDING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_IDLE;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_INCOMING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_WAITING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_FULLBAND;
@@ -540,6 +550,7 @@
// Compute time it took to fail setup (except for MT calls that have never been picked up)
if (proto.setupFailed && proto.setupBeginMillis != 0L && proto.setupDurationMillis == 0) {
+ proto.preciseCallStateOnSetup = convertCallStateEnumToInt(Call.State.DISCONNECTED);
proto.setupDurationMillis = (int) (getTimeMillis() - proto.setupBeginMillis);
}
@@ -632,6 +643,7 @@
private void checkCallSetup(Connection conn, VoiceCallSession proto) {
if (proto.setupBeginMillis != 0L && isSetupFinished(conn.getCall())) {
+ proto.preciseCallStateOnSetup = convertCallStateEnumToInt(conn.getState());
proto.setupDurationMillis = (int) (getTimeMillis() - proto.setupBeginMillis);
proto.setupBeginMillis = 0L;
}
@@ -1092,4 +1104,29 @@
proto.handoverInProgress = false;
}
}
+
+ private int convertCallStateEnumToInt(Call.State state) {
+ switch (state) {
+ case IDLE:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_IDLE;
+ case ACTIVE:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
+ case HOLDING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_HOLDING;
+ case DIALING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DIALING;
+ case ALERTING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
+ case INCOMING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_INCOMING;
+ case WAITING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_WAITING;
+ case DISCONNECTED:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
+ case DISCONNECTING:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTING;
+ default:
+ return VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
+ }
+ }
}
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 2324ba2..0a39865 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -17,9 +17,10 @@
package com.android.internal.telephony.satellite;
import static android.provider.Settings.ACTION_SATELLITE_SETTING;
-import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_TYPE;
import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL;
+import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_TYPE;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE;
@@ -27,9 +28,10 @@
import static android.telephony.CarrierConfigManager.KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL;
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_SCREEN_OFF_INACTIVITY_TIMEOUT_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_NIDD_APN_NAME_STRING;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS;
import static android.telephony.SubscriptionManager.isValidSubscriptionId;
@@ -91,6 +93,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Telephony;
+import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.DropBoxManagerLoggerBackend;
@@ -109,10 +112,11 @@
import android.telephony.satellite.ISatelliteSupportedStateCallback;
import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
import android.telephony.satellite.NtnSignalStrength;
-import android.telephony.satellite.ProvisionSubscriberId;
import android.telephony.satellite.SatelliteCapabilities;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteSubscriberInfo;
+import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@@ -216,7 +220,6 @@
private static final int EVENT_RADIO_STATE_CHANGED = 23;
private static final int CMD_IS_SATELLITE_PROVISIONED = 24;
private static final int EVENT_IS_SATELLITE_PROVISIONED_DONE = 25;
- private static final int EVENT_SATELLITE_PROVISION_STATE_CHANGED = 26;
private static final int EVENT_PENDING_DATAGRAMS = 27;
private static final int EVENT_SATELLITE_MODEM_STATE_CHANGED = 28;
private static final int EVENT_SET_SATELLITE_PLMN_INFO_DONE = 29;
@@ -239,6 +242,7 @@
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;
+ protected static final int EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT = 49;
@NonNull private static SatelliteController sInstance;
@NonNull private final Context mContext;
@@ -253,6 +257,7 @@
@NonNull private CarrierRoamingSatelliteControllerStats mCarrierRoamingSatelliteControllerStats;
@NonNull private final SubscriptionManagerService mSubscriptionManagerService;
@NonNull private final TelephonyCountryDetector mCountryDetector;
+ @NonNull private final TelecomManager mTelecomManager;
private final CommandsInterface mCi;
private ContentResolver mContentResolver;
private final DeviceStateMonitor mDSM;
@@ -292,8 +297,6 @@
private boolean mWaitingForDisableSatelliteModemResponse = false;
private boolean mWaitingForSatelliteModemOff = false;
- private final AtomicBoolean mRegisteredForProvisionStateChangedWithSatelliteService =
- new AtomicBoolean(false);
private final AtomicBoolean mRegisteredForPendingDatagramCountWithSatelliteService =
new AtomicBoolean(false);
private final AtomicBoolean mRegisteredForSatelliteModemStateChangedWithSatelliteService =
@@ -343,12 +346,18 @@
private final Object mIsSatelliteEnabledLock = new Object();
@GuardedBy("mIsSatelliteEnabledLock")
private Boolean mIsSatelliteEnabled = null;
- private final Object mIsRadioOnLock = new Object();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected final Object mIsRadioOnLock = new Object();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected boolean mIsRadioOn;
@GuardedBy("mIsRadioOnLock")
- private boolean mIsRadioOn = false;
- private final Object mSatelliteViaOemProvisionLock = new Object();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected boolean mRadioOffRequested = false;
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ protected final Object mSatelliteViaOemProvisionLock = new Object();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@GuardedBy("mSatelliteViaOemProvisionLock")
- private Boolean mIsSatelliteViaOemProvisioned = null;
+ protected Boolean mIsSatelliteViaOemProvisioned = null;
@GuardedBy("mSatelliteViaOemProvisionLock")
private Boolean mOverriddenIsSatelliteViaOemProvisioned = null;
private final Object mSatelliteCapabilitiesLock = new Object();
@@ -469,6 +478,9 @@
// key : priority, low value is high, value : List<SubscriptionInfo>
@GuardedBy("mSatelliteTokenProvisionedLock")
private Map<Integer, List<SubscriptionInfo>> mSubsInfoListPerPriority = new HashMap<>();
+ // The last ICC ID that framework configured to modem.
+ @GuardedBy("mSatelliteTokenProvisionedLock")
+ private String mLastConfiguredIccId;
@NonNull private final Object mSatelliteTokenProvisionedLock = new Object();
private long mWaitTimeForSatelliteEnablingResponse;
private long mDemoPointingAlignedDurationMillis;
@@ -556,6 +568,7 @@
mCountryDetector = TelephonyCountryDetector.getInstance(context);
mCountryDetector.registerForWifiConnectivityStateChanged(this,
EVENT_WIFI_CONNECTIVITY_STATE_CHANGED, null);
+ mTelecomManager = mContext.getSystemService(TelecomManager.class);
// Create the PointingUIController singleton,
// which is used to manage interactions with PointingUI app.
@@ -580,7 +593,6 @@
mIsRadioOn = phone.isRadioOn();
}
- registerForSatelliteProvisionStateChanged();
registerForPendingDatagramCount();
registerForSatelliteModemStateChanged();
registerForServiceStateChanged();
@@ -1018,11 +1030,12 @@
break;
}
mSatelliteProvisionCallbacks.put(argument.subId, argument.callback);
- onCompleted = obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
// Log the current time for provision triggered
mProvisionMetricsStats.setProvisioningStartTime();
- mSatelliteModemInterface.provisionSatelliteService(argument.token,
- argument.provisionData, onCompleted);
+ Message provisionSatelliteServiceDoneEvent = this.obtainMessage(
+ EVENT_PROVISION_SATELLITE_SERVICE_DONE,
+ new AsyncResult(request, SATELLITE_RESULT_SUCCESS, null));
+ provisionSatelliteServiceDoneEvent.sendToTarget();
break;
}
@@ -1041,11 +1054,13 @@
request = (SatelliteControllerHandlerRequest) msg.obj;
ProvisionSatelliteServiceArgument argument =
(ProvisionSatelliteServiceArgument) request.argument;
- onCompleted = obtainMessage(EVENT_DEPROVISION_SATELLITE_SERVICE_DONE, request);
if (argument.callback != null) {
mProvisionMetricsStats.setProvisioningStartTime();
}
- mSatelliteModemInterface.deprovisionSatelliteService(argument.token, onCompleted);
+ Message deprovisionSatelliteServiceDoneEvent = this.obtainMessage(
+ EVENT_DEPROVISION_SATELLITE_SERVICE_DONE,
+ new AsyncResult(request, SATELLITE_RESULT_SUCCESS, null));
+ deprovisionSatelliteServiceDoneEvent.sendToTarget();
break;
}
@@ -1316,6 +1331,14 @@
mIsRadioOn = true;
} else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) {
resetCarrierRoamingSatelliteModeParams();
+ synchronized (mIsRadioOnLock) {
+ if (mRadioOffRequested) {
+ logd("EVENT_RADIO_STATE_CHANGED: set mIsRadioOn to false");
+ stopWaitForCellularModemOffTimer();
+ mIsRadioOn = false;
+ mRadioOffRequested = false;
+ }
+ }
}
}
@@ -1342,8 +1365,10 @@
case CMD_IS_SATELLITE_PROVISIONED: {
request = (SatelliteControllerHandlerRequest) msg.obj;
- onCompleted = obtainMessage(EVENT_IS_SATELLITE_PROVISIONED_DONE, request);
- mSatelliteModemInterface.requestIsSatelliteProvisioned(onCompleted);
+ Message isProvisionedDoneEvent = this.obtainMessage(
+ EVENT_IS_SATELLITE_PROVISIONED_DONE,
+ new AsyncResult(request, SATELLITE_RESULT_SUCCESS, null));
+ isProvisionedDoneEvent.sendToTarget();
break;
}
@@ -1352,15 +1377,6 @@
break;
}
- case EVENT_SATELLITE_PROVISION_STATE_CHANGED:
- ar = (AsyncResult) msg.obj;
- if (ar.result == null) {
- ploge("EVENT_SATELLITE_PROVISION_STATE_CHANGED: result is null");
- } else {
- handleEventSatelliteProvisionStateChanged((boolean) ar.result);
- }
- break;
-
case EVENT_PENDING_DATAGRAMS:
plogd("Received EVENT_PENDING_DATAGRAMS");
IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
@@ -1570,12 +1586,22 @@
int subId = -1;
synchronized (mSatelliteTokenProvisionedLock) {
subId = mSubscriberIdPerSub.getOrDefault(
- argument.mProvisionSubscriberIdList.get(0).getSubscriberId(), -1);
+ argument.mSatelliteSubscriberInfoList.get(0).getSubscriberId(), -1);
+ for (SatelliteSubscriberInfo subscriberInfo :
+ argument.mSatelliteSubscriberInfoList) {
+ mProvisionedSubscriberId.put(subscriberInfo.getSubscriberId(), true);
+ }
}
setSatellitePhone(subId);
String iccId = mSubscriptionManagerService.getSubscriptionInfo(subId).getIccId();
- logd("CMD_PROVISION_SATELLITE_TOKEN_UPDATED: subId=" + subId + ", iccId=" + iccId);
- mSatelliteModemInterface.updateSatelliteSubscription(iccId, onCompleted);
+ argument.setIccId(iccId);
+ synchronized (mSatelliteTokenProvisionedLock) {
+ if (!iccId.equals(mLastConfiguredIccId)) {
+ logd("updateSatelliteSubscription subId=" + subId + ", iccId=" + iccId
+ + " to modem");
+ mSatelliteModemInterface.updateSatelliteSubscription(iccId, onCompleted);
+ }
+ }
Consumer<Integer> result = new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
@@ -1595,10 +1621,16 @@
(RequestProvisionSatelliteArgument) request.argument;
int error = SatelliteServiceUtils.getSatelliteError(ar,
"updateSatelliteSubscription");
- logd("EVENT_PROVISION_SATELLITE_TOKEN_UPDATED =" + error);
+ if (error == SATELLITE_RESULT_SUCCESS) {
+ synchronized (mSatelliteTokenProvisionedLock) {
+ mLastConfiguredIccId = argument.getIccId();
+ }
+ }
+ logd("updateSatelliteSubscription result=" + error);
Bundle bundle = new Bundle();
- bundle.putBoolean(SatelliteManager.KEY_PROVISION_SATELLITE_TOKENS, true);
- argument.mResult.send(SATELLITE_RESULT_SUCCESS, bundle);
+ bundle.putBoolean(SatelliteManager.KEY_PROVISION_SATELLITE_TOKENS,
+ error == SATELLITE_RESULT_SUCCESS);
+ argument.mResult.send(error, bundle);
break;
}
@@ -1617,6 +1649,13 @@
break;
}
+ case EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT: {
+ plogw("Timed out to wait for cellular modem OFF state");
+ synchronized (mIsRadioOnLock) {
+ mRadioOffRequested = false;
+ }
+ }
+
default:
Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " +
msg.what);
@@ -1625,18 +1664,27 @@
}
private static final class RequestProvisionSatelliteArgument {
- public List<ProvisionSubscriberId> mProvisionSubscriberIdList;
+ public List<SatelliteSubscriberInfo> mSatelliteSubscriberInfoList;
@NonNull
public ResultReceiver mResult;
public long mRequestId;
+ public String mIccId;
- RequestProvisionSatelliteArgument(List<ProvisionSubscriberId> provisionSubscriberIdList,
+ RequestProvisionSatelliteArgument(List<SatelliteSubscriberInfo> satelliteSubscriberInfoList,
ResultReceiver result) {
- this.mProvisionSubscriberIdList = provisionSubscriberIdList;
+ this.mSatelliteSubscriberInfoList = satelliteSubscriberInfoList;
this.mResult = result;
this.mRequestId = sNextSatelliteEnableRequestId.getAndUpdate(
n -> ((n + 1) % Long.MAX_VALUE));
}
+
+ public void setIccId(String iccId) {
+ mIccId = iccId;
+ }
+
+ public String getIccId() {
+ return mIccId;
+ }
}
private void handleEventConfigDataUpdated() {
@@ -1689,6 +1737,19 @@
SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result);
return;
}
+ if (mRadioOffRequested) {
+ ploge("Radio is being powering off, can not enable satellite");
+ sendErrorAndReportSessionMetrics(
+ SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE, result);
+ return;
+ }
+ }
+
+ if (mTelecomManager.isInEmergencyCall()) {
+ plogd("requestSatelliteEnabled: reject as emergency call is ongoing.");
+ sendErrorAndReportSessionMetrics(
+ SatelliteManager.SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS, result);
+ return;
}
} else {
/* if disable satellite, always assume demo is also disabled */
@@ -2040,12 +2101,7 @@
return;
}
- Boolean satelliteProvisioned = isSatelliteViaOemProvisioned();
- if (satelliteProvisioned == null) {
- result.accept(SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
- return;
- }
- if (!satelliteProvisioned) {
+ if (Boolean.FALSE.equals(isSatelliteViaOemProvisioned())) {
result.accept(SATELLITE_RESULT_SUCCESS);
return;
}
@@ -2072,6 +2128,18 @@
}
mSatelliteProvisionStateChangedListeners.put(callback.asBinder(), callback);
+
+ boolean isProvisioned = Boolean.TRUE.equals(isSatelliteViaOemProvisioned());
+ try {
+ callback.onSatelliteProvisionStateChanged(isProvisioned);
+ } catch (RemoteException ex) {
+ loge("setSatelliteServicePackageName: " + ex);
+ }
+ synchronized (mSatelliteViaOemProvisionLock) {
+ plogd("registerForSatelliteProvisionStateChanged: report current provisioned "
+ + "state, state=" + isProvisioned);
+ }
+
return SATELLITE_RESULT_SUCCESS;
}
@@ -2573,26 +2641,28 @@
* 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.
+ * @param provisioned Whether satellite should be provisioned or not.
* @return {@code true} if the satellite vendor service is set successfully,
* {@code false} otherwise.
*/
- public boolean setSatelliteServicePackageName(@Nullable String servicePackageName) {
- if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
- plogd("setSatelliteServicePackageName: oemEnabledSatelliteFlag is disabled");
- return false;
- }
+ public boolean setSatelliteServicePackageName(@Nullable String servicePackageName,
+ String provisioned) {
if (!isMockModemAllowed()) {
plogd("setSatelliteServicePackageName: mock modem not allowed");
return false;
}
// Cached states need to be cleared whenever switching satellite vendor services.
- plogd("setSatelliteServicePackageName: Resetting cached states");
+ plogd("setSatelliteServicePackageName: Resetting cached states, provisioned="
+ + provisioned);
synchronized (mIsSatelliteSupportedLock) {
mIsSatelliteSupported = null;
}
synchronized (mSatelliteViaOemProvisionLock) {
- mIsSatelliteViaOemProvisioned = null;
+ mIsSatelliteViaOemProvisioned = Optional.ofNullable(provisioned)
+ .filter(s -> s.equalsIgnoreCase("true") || s.equalsIgnoreCase("false"))
+ .map(s -> s.equalsIgnoreCase("true"))
+ .orElse(null);
}
synchronized (mIsSatelliteEnabledLock) {
mIsSatelliteEnabled = null;
@@ -2857,27 +2927,50 @@
/**
* This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify
- * {@link SatelliteController} that it has received a request to power off the cellular radio
- * modem. {@link SatelliteController} will then power off the satellite modem.
+ * {@link SatelliteController} that it has received a request to power on or off the cellular
+ * radio modem.
+ *
+ * @param powerOn {@code true} means cellular radio is about to be powered on, {@code false}
+ * means cellular modem is about to be powered off.
*/
- public void onCellularRadioPowerOffRequested() {
- logd("onCellularRadioPowerOffRequested()");
+ public void onSetCellularRadioPowerStateRequested(boolean powerOn) {
+ logd("onSetCellularRadioPowerStateRequested: powerOn=" + powerOn);
if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
- plogd("onCellularRadioPowerOffRequested: oemEnabledSatelliteFlag is disabled");
+ plogd("onSetCellularRadioPowerStateRequested: oemEnabledSatelliteFlag is disabled");
return;
}
synchronized (mIsRadioOnLock) {
- mIsRadioOn = false;
+ mRadioOffRequested = !powerOn;
}
- requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- false /* enableSatellite */, false /* enableDemoMode */, false /* isEmergency */,
- new IIntegerConsumer.Stub() {
- @Override
- public void accept(int result) {
- plogd("onRadioPowerOffRequested: requestSatelliteEnabled result=" + result);
- }
- });
+ if (powerOn) {
+ stopWaitForCellularModemOffTimer();
+ } else {
+ requestSatelliteEnabled(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ false /* enableSatellite */, false /* enableDemoMode */,
+ false /* isEmergency */,
+ new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ plogd("onSetCellularRadioPowerStateRequested: requestSatelliteEnabled"
+ + " result=" + result);
+ }
+ });
+ startWaitForCellularModemOffTimer();
+ }
+ }
+
+ /**
+ * This function is used by {@link com.android.internal.telephony.ServiceStateTracker} to notify
+ * {@link SatelliteController} that the request to power off the cellular radio modem has
+ * failed.
+ */
+ public void onPowerOffCellularRadioFailed() {
+ logd("onPowerOffCellularRadioFailed");
+ synchronized (mIsRadioOnLock) {
+ mRadioOffRequested = false;
+ stopWaitForCellularModemOffTimer();
+ }
}
/**
@@ -3473,38 +3566,6 @@
}
/**
- * Posts the specified command to be executed on the main thread. As this is a synchronous
- * request, it waits until the request is complete and then return the result.
- *
- * @param command command to be executed on the main thread
- * @param argument additional parameters required to perform of the operation
- * @param phone phone object used to perform the operation.
- * @return result of the operation
- */
- private @Nullable Object sendRequest(int command, @NonNull Object argument,
- @Nullable Phone phone) {
- if (Looper.myLooper() == this.getLooper()) {
- throw new RuntimeException("This method will deadlock if called from the main thread");
- }
-
- SatelliteControllerHandlerRequest request = new SatelliteControllerHandlerRequest(
- argument, phone);
- Message msg = this.obtainMessage(command, request);
- msg.sendToTarget();
-
- synchronized (request) {
- while(request.result == null) {
- try {
- request.wait();
- } catch (InterruptedException e) {
- // Do nothing, go back and wait until the request is complete.
- }
- }
- }
- return request.result;
- }
-
- /**
* Check if satellite is provisioned for a subscription on the device.
* @return true if satellite is provisioned on the given subscription else return false.
*/
@@ -3519,16 +3580,13 @@
if (mIsSatelliteViaOemProvisioned != null) {
return mIsSatelliteViaOemProvisioned;
}
- }
- requestIsSatelliteProvisioned(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- new ResultReceiver(this) {
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- plogd("isSatelliteViaOemProvisioned: resultCode=" + resultCode);
- }
- });
- return null;
+ if (mIsSatelliteViaOemProvisioned == null) {
+ mIsSatelliteViaOemProvisioned = getPersistedOemEnabledSatelliteProvisionStatus();
+ }
+
+ return mIsSatelliteViaOemProvisioned;
+ }
}
private void handleSatelliteEnabled(SatelliteControllerHandlerRequest request) {
@@ -3584,7 +3642,6 @@
+ "changed to " + supported);
if (supported) {
- registerForSatelliteProvisionStateChanged();
registerForPendingDatagramCount();
registerForSatelliteModemStateChanged();
registerForNtnSignalStrengthChanged();
@@ -3633,16 +3690,6 @@
}
}
- private void registerForSatelliteProvisionStateChanged() {
- if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
- if (!mRegisteredForProvisionStateChangedWithSatelliteService.get()) {
- mSatelliteModemInterface.registerForSatelliteProvisionStateChanged(
- this, EVENT_SATELLITE_PROVISION_STATE_CHANGED, null);
- mRegisteredForProvisionStateChangedWithSatelliteService.set(true);
- }
- }
- }
-
private void registerForPendingDatagramCount() {
if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
if (!mRegisteredForPendingDatagramCountWithSatelliteService.get()) {
@@ -4005,6 +4052,13 @@
updateSatelliteEnabledState(
mSatelliteEnabledRequest.enableSatellite,
"EVENT_SET_SATELLITE_ENABLED_DONE");
+ if (mSatelliteEnabledRequest.enableSatellite
+ && !mSatelliteEnabledRequest.isEmergency) {
+ plogd("Starting pointingUI needFullscreenPointingUI=" + true
+ + "mIsDemoModeEnabled=" + mIsDemoModeEnabled + ", isEmergency="
+ + mSatelliteEnabledRequest.isEmergency);
+ mPointingAppController.startPointingUI(true, mIsDemoModeEnabled, false);
+ }
mSatelliteEnabledRequest = null;
mWaitingForRadioDisabled = false;
}
@@ -4211,8 +4265,10 @@
KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL,
KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT,
KEY_SATELLITE_ESOS_SUPPORTED_BOOL,
+ KEY_SATELLITE_NIDD_APN_NAME_STRING,
KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT,
+ KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT,
KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT
);
}
@@ -4352,6 +4408,11 @@
return getConfigForSubId(subId).getInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT);
}
+ protected int getCarrierRoamingNtnEmergencyCallToSatelliteHandoverType(int subId) {
+ return getConfigForSubId(subId).getInt(
+ KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT);
+ }
+
/**
* Check if satellite attach is enabled by user for the carrier associated with the
* {@code subId}.
@@ -4603,6 +4664,7 @@
return SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
}
if (!satelliteProvisioned) {
+ plogd("evaluateOemSatelliteRequestAllowed: satellite service is not provisioned");
return SatelliteManager.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED;
}
}
@@ -4858,28 +4920,58 @@
private void persistOemEnabledSatelliteProvisionStatus(boolean isProvisioned) {
synchronized (mSatelliteViaOemProvisionLock) {
plogd("persistOemEnabledSatelliteProvisionStatus: isProvisioned=" + isProvisioned);
-
- if (!loadSatelliteSharedPreferences()) return;
-
- if (mSharedPreferences == null) {
- ploge("persistOemEnabledSatelliteProvisionStatus: mSharedPreferences is null");
+ if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+ int subId = SatelliteServiceUtils.getOemBasedNonTerrestrialSubscriptionId(mContext);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ try {
+ mSubscriptionManagerService.setIsSatelliteProvisionedForNonIpDatagram(subId,
+ isProvisioned);
+ plogd("persistOemEnabledSatelliteProvisionStatus: subId=" + subId);
+ } catch (IllegalArgumentException | SecurityException ex) {
+ ploge("setIsSatelliteProvisionedForNonIpDatagram: subId=" + subId + ", ex="
+ + ex);
+ }
+ } else {
+ plogd("persistOemEnabledSatelliteProvisionStatus: INVALID_SUBSCRIPTION_ID");
+ }
} else {
- mSharedPreferences.edit().putBoolean(
- OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY, isProvisioned).apply();
+ if (!loadSatelliteSharedPreferences()) return;
+
+ if (mSharedPreferences == null) {
+ ploge("persistOemEnabledSatelliteProvisionStatus: mSharedPreferences is null");
+ } else {
+ mSharedPreferences.edit().putBoolean(
+ OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY, isProvisioned).apply();
+ }
}
}
}
- private boolean getPersistedOemEnabledSatelliteProvisionStatus() {
+ @Nullable
+ private Boolean getPersistedOemEnabledSatelliteProvisionStatus() {
+ plogd("getPersistedOemEnabledSatelliteProvisionStatus:");
synchronized (mSatelliteViaOemProvisionLock) {
- if (!loadSatelliteSharedPreferences()) return false;
-
- if (mSharedPreferences == null) {
- ploge("getPersistedOemEnabledSatelliteProvisionStatus: mSharedPreferences is null");
- return false;
+ if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+ int subId = SatelliteServiceUtils.getOemBasedNonTerrestrialSubscriptionId(mContext);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return mSubscriptionManagerService.isSatelliteProvisionedForNonIpDatagram(
+ subId);
+ } else {
+ plogd("getPersistedOemEnabledSatelliteProvisionStatus: "
+ + "subId=INVALID_SUBSCRIPTION_ID, return null");
+ return null;
+ }
} else {
- return mSharedPreferences.getBoolean(
- OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY, false);
+ if (!loadSatelliteSharedPreferences()) return false;
+
+ if (mSharedPreferences == null) {
+ ploge("getPersistedOemEnabledSatelliteProvisionStatus: mSharedPreferences is "
+ + "null");
+ return false;
+ } else {
+ return mSharedPreferences.getBoolean(
+ OEM_ENABLED_SATELLITE_PROVISION_STATUS_KEY, false);
+ }
}
}
}
@@ -4900,31 +4992,13 @@
}
private void handleIsSatelliteProvisionedDoneEvent(@NonNull AsyncResult ar) {
+ logd("handleIsSatelliteProvisionedDoneEvent:");
SatelliteControllerHandlerRequest request = (SatelliteControllerHandlerRequest) ar.userObj;
- int error = SatelliteServiceUtils.getSatelliteError(
- ar, "handleIsSatelliteProvisionedDoneEvent");
- boolean isSatelliteProvisionedInModem = false;
- if (error == SATELLITE_RESULT_SUCCESS) {
- if (ar.result == null) {
- ploge("handleIsSatelliteProvisionedDoneEvent: result is null");
- error = SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
- } else {
- isSatelliteProvisionedInModem = ((int[]) ar.result)[0] == 1;
- }
- } else if (error == SATELLITE_RESULT_REQUEST_NOT_SUPPORTED) {
- plogd("handleIsSatelliteProvisionedDoneEvent: Modem does not support this request");
- isSatelliteProvisionedInModem = true;
- }
- boolean isSatelliteViaOemProvisioned =
- isSatelliteProvisionedInModem && getPersistedOemEnabledSatelliteProvisionStatus();
- plogd("isSatelliteProvisionedInModem=" + isSatelliteProvisionedInModem
- + ", isSatelliteViaOemProvisioned=" + isSatelliteViaOemProvisioned);
+
Bundle bundle = new Bundle();
- bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED, isSatelliteViaOemProvisioned);
- synchronized (mSatelliteViaOemProvisionLock) {
- mIsSatelliteViaOemProvisioned = isSatelliteViaOemProvisioned;
- }
- ((ResultReceiver) request.argument).send(error, bundle);
+ bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
+ Boolean.TRUE.equals(isSatelliteViaOemProvisioned()));
+ ((ResultReceiver) request.argument).send(SATELLITE_RESULT_SUCCESS, bundle);
}
private long getWaitForSatelliteEnablingResponseTimeoutMillis() {
@@ -4932,6 +5006,32 @@
R.integer.config_wait_for_satellite_enabling_response_timeout_millis);
}
+ private long getWaitForCellularModemOffTimeoutMillis() {
+ return mContext.getResources().getInteger(
+ R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis);
+ }
+
+ private void startWaitForCellularModemOffTimer() {
+ synchronized (mIsRadioOnLock) {
+ if (hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT)) {
+ plogd("startWaitForCellularModemOffTimer: the timer was already started");
+ return;
+ }
+ long timeoutMillis = getWaitForCellularModemOffTimeoutMillis();
+ plogd("Start timer to wait for cellular modem OFF state, timeoutMillis="
+ + timeoutMillis);
+ sendMessageDelayed(obtainMessage(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT),
+ timeoutMillis);
+ }
+ }
+
+ private void stopWaitForCellularModemOffTimer() {
+ synchronized (mSatelliteEnabledRequestLock) {
+ plogd("Stop timer to wait for cellular modem OFF state");
+ removeMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT);
+ }
+ }
+
private void startWaitForSatelliteEnablingResponseTimer(
@NonNull RequestSatelliteEnabledArgument argument) {
synchronized (mSatelliteEnabledRequestLock) {
@@ -5500,14 +5600,20 @@
// The subscriberId for ntnOnly SIMs is the Iccid, whereas for ESOS supported SIMs, the
// subscriberId is the Imsi prefix 6 digit + phone number.
- private @NonNull String getSubscriberId(SubscriptionInfo info) {
+ private Pair<String, Integer> getSubscriberIdAndType(SubscriptionInfo info) {
+ String subscriberId = "";
+ @SatelliteSubscriberInfo.SubscriberIdType int subscriberIdType =
+ SatelliteSubscriberInfo.ICCID;
if (info.isSatelliteESOSSupported()) {
- return getPhoneNumberBasedCarrier(info.getSubscriptionId());
+ subscriberId = getPhoneNumberBasedCarrier(info.getSubscriptionId());
+ subscriberIdType = SatelliteSubscriberInfo.IMSI_MSISDN;
}
if (info.isOnlyNonTerrestrialNetwork()) {
- return info.getIccId();
+ subscriberId = info.getIccId();
}
- return "";
+ logd("getSubscriberIdAndType: subscriberId=" + subscriberId + ", subscriberIdType="
+ + subscriberIdType);
+ return new Pair<>(subscriberId, subscriberIdType);
}
private String getPhoneNumberBasedCarrier(int subId) {
@@ -5516,7 +5622,6 @@
SubscriptionManager subscriptionManager = mContext.getSystemService(
SubscriptionManager.class);
String phoneNumber = subscriptionManager.getPhoneNumber(subId);
-
if (phoneNumber == null) {
logd("getPhoneNumberBasedCarrier: phoneNumber null");
return "";
@@ -5579,75 +5684,59 @@
* @param result The result receiver, which returns the list of prioritized satellite tokens
* to be used for provision if the request is successful or an error code if the request failed.
*/
- public void requestProvisionSubscriberIds(@NonNull ResultReceiver result) {
+ public void requestSatelliteSubscriberProvisionStatus(@NonNull ResultReceiver result) {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
return;
}
- List<ProvisionSubscriberId> list = new ArrayList<>();
+ 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("requestProvisionSubscriberIds: no exist this priority " + priority);
+ logd("requestSatelliteSubscriberProvisionStatus: no exist this priority "
+ + priority);
continue;
}
for (SubscriptionInfo info : infoList) {
- String subscriberId = getSubscriberId(info);
+ Pair<String, Integer> subscriberIdPair = getSubscriberIdAndType(info);
+ String subscriberId = subscriberIdPair.first;
int carrierId = info.getCarrierId();
- logd("requestProvisionSubscriberIds: subscriberId:" + subscriberId
- + " , carrierId=" + carrierId);
+ String apn = getConfigForSubId(info.getSubscriptionId())
+ .getString(KEY_SATELLITE_NIDD_APN_NAME_STRING);
+ logd("requestSatelliteSubscriberProvisionStatus: subscriberId:"
+ + subscriberId + " , carrierId=" + carrierId + " , apn=" + apn);
if (subscriberId.isEmpty()) {
- logd("requestProvisionSubscriberIds: getSubscriberId failed skip this "
- + "subscriberId.");
+ logd("requestSatelliteSubscriberProvisionStatus: getSubscriberId "
+ + "failed skip this subscriberId.");
continue;
}
- list.add(new ProvisionSubscriberId(subscriberId, carrierId, ""));
+ SatelliteSubscriberInfo satelliteSubscriberInfo =
+ new SatelliteSubscriberInfo.Builder().setSubscriberId(subscriberId)
+ .setCarrierId(carrierId).setNiddApn(apn)
+ .setSubId(info.getSubscriptionId())
+ .setSubscriberIdType(subscriberIdPair.second)
+ .build();
+ boolean provisioned = mProvisionedSubscriberId.getOrDefault(
+ subscriberId, false);
+ logd("requestSatelliteSubscriberProvisionStatus: satelliteSubscriberInfo="
+ + satelliteSubscriberInfo + ", provisioned=" + provisioned);
+ list.add(new SatelliteSubscriberProvisionStatus.Builder()
+ .setSatelliteSubscriberInfo(satelliteSubscriberInfo)
+ .setProvisionStatus(provisioned).build());
mSubscriberIdPerSub.put(subscriberId, info.getSubscriptionId());
}
}
}
- logd("requestProvisionSubscriberIds: " + list);
+ logd("requestSatelliteSubscriberProvisionStatus: " + list);
final Bundle bundle = new Bundle();
bundle.putParcelableList(SatelliteManager.KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN, list);
result.send(SATELLITE_RESULT_SUCCESS, bundle);
}
- /**
- * Request to get provisioned status for given a satellite subscriber id.
- *
- * @param satelliteSubscriberId Satellite subscriber id requiring provisioned status check.
- * @param result The result receiver, which returns the provisioned status of the token if the
- * request is successful or an error code if the request failed.
- */
- public void requestIsProvisioned(@NonNull String satelliteSubscriberId,
- @NonNull ResultReceiver result) {
- if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
- result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
- return;
- }
- if (satelliteSubscriberId.isEmpty()) {
- result.send(SATELLITE_RESULT_INVALID_ARGUMENTS, null);
- return;
- }
-
- boolean isProvisioned = false;
- synchronized (mSatelliteTokenProvisionedLock) {
- if (mProvisionedSubscriberId.getOrDefault(satelliteSubscriberId, false)) {
- isProvisioned = true;
- }
- }
-
- logd("requestIsProvisioned: satelliteSubscriberId=" + satelliteSubscriberId
- + " , isProvisioned=" + isProvisioned);
- final Bundle bundle = new Bundle();
- bundle.putBoolean(SatelliteManager.KEY_IS_SATELLITE_PROVISIONED, isProvisioned);
- result.send(SATELLITE_RESULT_SUCCESS, bundle);
- }
-
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected boolean isSubscriptionProvisioned(int subId) {
plogd("isSubscriptionProvisioned: subId=" + subId);
@@ -5656,8 +5745,8 @@
return false;
}
- String subscriberId = getSubscriberId(
- mSubscriptionManagerService.getSubscriptionInfo(subId));
+ String subscriberId = getSubscriberIdAndType(
+ mSubscriptionManagerService.getSubscriptionInfo(subId)).first;
if (subscriberId.isEmpty()) {
plogd("isSubscriptionProvisioned: subId=" + subId + " subscriberId is empty.");
return false;
@@ -5674,7 +5763,7 @@
* @param list List of provisioned satellite subscriber ids.
* @param result The result receiver that returns whether deliver success or fail.
*/
- public void provisionSatellite(@NonNull List<ProvisionSubscriberId> list,
+ public void provisionSatellite(@NonNull List<SatelliteSubscriberInfo> list,
@NonNull ResultReceiver result) {
if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
@@ -5686,12 +5775,6 @@
}
logd("provisionSatellite:" + list);
- for (ProvisionSubscriberId subscriberId : list) {
- synchronized (mSatelliteTokenProvisionedLock) {
- mProvisionedSubscriberId.put(subscriberId.getSubscriberId(), true);
- }
- }
-
RequestProvisionSatelliteArgument request = new RequestProvisionSatelliteArgument(list,
result);
sendRequestAsync(CMD_PROVISION_SATELLITE_TOKEN_UPDATED, request, null);
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index f0a96c2..849004a 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -86,8 +86,6 @@
private boolean mIsBinding;
@Nullable private PersistentLogger mPersistentLogger = null;
- @NonNull private final RegistrantList mSatelliteProvisionStateChangedRegistrants =
- new RegistrantList();
@NonNull private final RegistrantList mSatellitePositionInfoChangedRegistrants =
new RegistrantList();
@NonNull private final RegistrantList mDatagramTransferStateChangedRegistrants =
@@ -113,11 +111,6 @@
}
@Override
- public void onSatelliteProvisionStateChanged(boolean provisioned) {
- mSatelliteProvisionStateChangedRegistrants.notifyResult(provisioned);
- }
-
- @Override
public void onSatelliteDatagramReceived(
android.telephony.satellite.stub.SatelliteDatagram datagram, int pendingCount) {
if (notifyResultIfExpectedListener()) {
@@ -403,27 +396,6 @@
}
/**
- * Registers for the satellite provision state changed.
- *
- * @param h Handler for notification message.
- * @param what User-defined message code.
- * @param obj User object.
- */
- public void registerForSatelliteProvisionStateChanged(
- @NonNull Handler h, int what, @Nullable Object obj) {
- mSatelliteProvisionStateChangedRegistrants.add(h, what, obj);
- }
-
- /**
- * Unregisters for the satellite provision state changed.
- *
- * @param h Handler to be removed from the registrant list.
- */
- public void unregisterForSatelliteProvisionStateChanged(@NonNull Handler h) {
- mSatelliteProvisionStateChangedRegistrants.remove(h);
- }
-
- /**
* Registers for satellite position info changed from satellite modem.
*
* @param h Handler for notification message.
@@ -889,113 +861,6 @@
}
/**
- * Provision the device with a satellite provider.
- * This is needed if the provider allows dynamic registration.
- * Once provisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report true.
- *
- * @param token The token to be used as a unique identifier for provisioning with satellite
- * gateway.
- * @param provisionData Data from the provisioning app that can be used by provisioning server
- * @param message The Message to send to result of the operation to.
- */
- public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
- @NonNull Message message) {
- if (mSatelliteService != null) {
- try {
- mSatelliteService.provisionSatelliteService(token, provisionData,
- new IIntegerConsumer.Stub() {
- @Override
- public void accept(int result) {
- int error = SatelliteServiceUtils.fromSatelliteError(result);
- plogd("provisionSatelliteService: " + error);
- Binder.withCleanCallingIdentity(() ->
- sendMessageWithResult(message, null, error));
- }
- });
- } catch (RemoteException e) {
- ploge("provisionSatelliteService: RemoteException " + e);
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
- }
- } else {
- ploge("provisionSatelliteService: Satellite service is unavailable.");
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
- }
- }
-
- /**
- * Deprovision the device with the satellite provider.
- * This is needed if the provider allows dynamic registration.
- * Once deprovisioned, ISatelliteListener#onSatelliteProvisionStateChanged should report false.
- *
- * @param token The token of the device/subscription to be deprovisioned.
- * @param message The Message to send to result of the operation to.
- */
- public void deprovisionSatelliteService(@NonNull String token, @NonNull Message message) {
- if (mSatelliteService != null) {
- try {
- mSatelliteService.deprovisionSatelliteService(token, new IIntegerConsumer.Stub() {
- @Override
- public void accept(int result) {
- int error = SatelliteServiceUtils.fromSatelliteError(result);
- plogd("deprovisionSatelliteService: " + error);
- Binder.withCleanCallingIdentity(() ->
- sendMessageWithResult(message, null, error));
- }
- });
- } catch (RemoteException e) {
- ploge("deprovisionSatelliteService: RemoteException " + e);
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
- }
- } else {
- ploge("deprovisionSatelliteService: Satellite service is unavailable.");
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
- }
- }
-
- /**
- * Request to get whether this device is provisioned with a satellite provider.
- *
- * @param message The Message to send to result of the operation to.
- */
- public void requestIsSatelliteProvisioned(@NonNull Message message) {
- if (mSatelliteService != null) {
- try {
- mSatelliteService.requestIsSatelliteProvisioned(new IIntegerConsumer.Stub() {
- @Override
- public void accept(int result) {
- int error = SatelliteServiceUtils.fromSatelliteError(result);
- plogd("requestIsSatelliteProvisioned: " + error);
- Binder.withCleanCallingIdentity(() ->
- sendMessageWithResult(message, null, error));
- }
- }, new IBooleanConsumer.Stub() {
- @Override
- public void accept(boolean result) {
- // Convert for compatibility with SatelliteResponse
- // TODO: This should just report result instead.
- int[] provisioned = new int[] {result ? 1 : 0};
- plogd("requestIsSatelliteProvisioned: " + Arrays.toString(provisioned));
- Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
- message, provisioned, SatelliteManager.SATELLITE_RESULT_SUCCESS));
- }
- });
- } catch (RemoteException e) {
- ploge("requestIsSatelliteProvisioned: RemoteException " + e);
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
- }
- } else {
- ploge("requestIsSatelliteProvisioned: Satellite service is unavailable.");
- sendMessageWithResult(message, null,
- SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
- }
- }
-
- /**
* Poll the pending datagrams to be received over satellite.
* The satellite service should check if there are any pending datagrams to be received over
* satellite and report them via ISatelliteListener#onSatelliteDatagramsReceived.
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 26362b3..f24d484 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -56,6 +56,7 @@
import android.telephony.ims.RegistrationManager;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.text.TextUtils;
import android.util.Pair;
import android.util.SparseArray;
@@ -68,8 +69,10 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SmsApplication;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.metrics.SatelliteStats;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -157,6 +160,13 @@
plogd("onSatelliteProvisionStateChanged: provisioned=" + provisioned);
sendMessage(obtainMessage(EVENT_SATELLITE_PROVISIONED_STATE_CHANGED, provisioned));
}
+
+ @Override
+ public void onSatelliteSubscriptionProvisionStateChanged(
+ List<SatelliteSubscriberProvisionStatus> satelliteSubscriberProvisionStatus) {
+ plogd("onSatelliteSubscriptionProvisionStateChanged: "
+ + satelliteSubscriberProvisionStatus);
+ }
};
}
@@ -658,7 +668,7 @@
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
}
Bundle activityOptions = ActivityOptions.makeBasic()
- .setPendingIntentBackgroundActivityStartMode(
+ .setPendingIntentCreatorBackgroundActivityStartMode(
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
.toBundle();
intent.setComponent(new ComponentName(packageName, className));
@@ -702,8 +712,19 @@
return telephonyManager.isMultiSimEnabled();
}
- private int getEmergencyCallToSatelliteHandoverType() {
- if (isSatelliteViaCarrierAvailable()) {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ public int getEmergencyCallToSatelliteHandoverType() {
+ if (Flags.carrierRoamingNbIotNtn() && isSatelliteViaOemAvailable()
+ && isSatelliteViaCarrierAvailable()) {
+ Phone satellitePhone = mSatelliteController.getSatellitePhone();
+ if (satellitePhone == null) {
+ ploge("getEmergencyCallToSatelliteHandoverType: satellitePhone is null");
+ return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
+ }
+ int satelliteSubId = satellitePhone.getSubId();
+ return mSatelliteController.getCarrierRoamingNtnEmergencyCallToSatelliteHandoverType(
+ satelliteSubId);
+ } else if (isSatelliteViaCarrierAvailable()) {
return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
} else {
return EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
index 33bdfaa..405cf59 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -33,6 +33,7 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.satellite.AntennaPosition;
import android.telephony.satellite.NtnSignalStrength;
@@ -305,6 +306,26 @@
}
/**
+ * Get the subscription ID which supports OEM based NTN satellite service.
+ *
+ * @return ID of the subscription that supports OEM-based satellite if any,
+ * return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
+ */
+ public static int getOemBasedNonTerrestrialSubscriptionId(@NonNull Context context) {
+ List<SubscriptionInfo> infoList =
+ SubscriptionManagerService.getInstance().getAllSubInfoList(
+ context.getOpPackageName(), null);
+
+ int subId = infoList.stream()
+ .filter(info -> info.isOnlyNonTerrestrialNetwork())
+ .mapToInt(SubscriptionInfo::getSubscriptionId)
+ .findFirst()
+ .orElse(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ logd("getOemBasedNonTerrestrialSubscriptionId: subId=" + subId);
+ return subId;
+ }
+
+ /**
* Expected format of the input dictionary bundle is:
* <ul>
* <li>Key: PLMN string.</li>
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
index cd6e6aa..d835f2d 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
@@ -296,7 +296,10 @@
SubscriptionInfoInternal::getSatelliteEntitlementPlmns),
new AbstractMap.SimpleImmutableEntry<>(
SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED,
- SubscriptionInfoInternal::getSatelliteESOSSupported)
+ SubscriptionInfoInternal::getSatelliteESOSSupported),
+ new AbstractMap.SimpleImmutableEntry<>(
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM,
+ SubscriptionInfoInternal::getIsSatelliteProvisionedForNonIpDatagram)
);
/**
@@ -439,7 +442,10 @@
SubscriptionDatabaseManager::setSatelliteEntitlementStatus),
new AbstractMap.SimpleImmutableEntry<>(
SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED,
- SubscriptionDatabaseManager::setSatelliteESOSSupported)
+ SubscriptionDatabaseManager::setSatelliteESOSSupported),
+ new AbstractMap.SimpleImmutableEntry<>(
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM,
+ SubscriptionDatabaseManager::setIsSatelliteProvisionedForNonIpDatagram)
);
/**
@@ -2185,6 +2191,24 @@
}
/**
+ * Set whether the subscription is provisioned for OEM-enabled or carrier roaming NB-IOT
+ * satellite service.
+ *
+ * @param subId Subscription ID.
+ * @param isSatelliteProvisionedForNonIpDatagram {@code 1} if it is provisioned for OEM-enabled
+ * or carrier roaming NB-IOT satellite service. {@code 0} otherwise.
+ *
+ * @throws IllegalArgumentException if the subscription does not exist.
+ */
+ public void setIsSatelliteProvisionedForNonIpDatagram(int subId,
+ int isSatelliteProvisionedForNonIpDatagram) {
+ writeDatabaseAndCacheHelper(subId,
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM,
+ isSatelliteProvisionedForNonIpDatagram,
+ SubscriptionInfoInternal.Builder::setIsSatelliteProvisionedForNonIpDatagram);
+ }
+
+ /**
* Reload the database from content provider to the cache. This must be a synchronous operation
* to prevent cache/database out-of-sync. Callers should be cautious to call this method because
* it might take longer time to complete.
@@ -2422,7 +2446,10 @@
SimInfo.COLUMN_SATELLITE_ENTITLEMENT_STATUS)))
.setSatelliteEntitlementPlmns(cursor.getString(
cursor.getColumnIndexOrThrow(
- SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS)));
+ SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS)))
+ .setIsSatelliteProvisionedForNonIpDatagram(cursor.getInt(
+ cursor.getColumnIndexOrThrow(
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM)));
if (mFeatureFlags.oemEnabledSatelliteFlag()) {
builder.setOnlyNonTerrestrialNetwork(cursor.getInt(cursor.getColumnIndexOrThrow(
SimInfo.COLUMN_IS_ONLY_NTN)));
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
index 7684864..92e112d 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionInfoInternal.java
@@ -498,6 +498,13 @@
private final int mIsSatelliteESOSSupported;
/**
+ * Whether this subscription is provisioned for OEM-enabled or carrier roaming NB-IOT satellite
+ * service or not.
+ * By default, its disabled. It is intended to use integer to fit the database format.
+ */
+ private final int mIsSatelliteProvisionedForNonIpDatagram;
+
+ /**
* Constructor from builder.
*
* @param builder Builder of {@link SubscriptionInfoInternal}.
@@ -577,6 +584,8 @@
this.mIsSatelliteEntitlementStatus = builder.mIsSatelliteEntitlementStatus;
this.mSatelliteEntitlementPlmns = builder.mSatelliteEntitlementPlmns;
this.mIsSatelliteESOSSupported = builder.mIsSatelliteESOSSupported;
+ this.mIsSatelliteProvisionedForNonIpDatagram =
+ builder.mIsSatelliteProvisionedForNonIpDatagram;
}
/**
@@ -1280,6 +1289,16 @@
return mIsSatelliteESOSSupported;
}
+ /**
+ * Return whether the subscription is provisioned for oem satellite service or not.
+ *
+ * @return {@code 1} if the subscription is provisioned for oem stellite service. {@code 0}
+ * otherwise.
+ */
+ public int getIsSatelliteProvisionedForNonIpDatagram() {
+ return mIsSatelliteProvisionedForNonIpDatagram;
+ }
+
/** @return converted {@link SubscriptionInfo}. */
@NonNull
public SubscriptionInfo toSubscriptionInfo() {
@@ -1384,6 +1403,8 @@
+ " satelliteEntitlementStatus=" + mIsSatelliteEntitlementStatus
+ " satelliteEntitlementPlmns=" + mSatelliteEntitlementPlmns
+ " isSatelliteESOSSupported=" + mIsSatelliteESOSSupported
+ + " isSatelliteProvisionedForNonIpDatagram="
+ + mIsSatelliteProvisionedForNonIpDatagram
+ "]";
}
@@ -1447,7 +1468,9 @@
&& mTransferStatus == that.mTransferStatus
&& mIsSatelliteEntitlementStatus == that.mIsSatelliteEntitlementStatus
&& mSatelliteEntitlementPlmns.equals(that.mSatelliteEntitlementPlmns)
- && mIsSatelliteESOSSupported == that.mIsSatelliteESOSSupported;
+ && mIsSatelliteESOSSupported == that.mIsSatelliteESOSSupported
+ && mIsSatelliteProvisionedForNonIpDatagram
+ == that.mIsSatelliteProvisionedForNonIpDatagram;
}
@Override
@@ -1480,7 +1503,8 @@
mIsSatelliteEnabled, mCardId, mIsGroupDisabled,
mIsSatelliteAttachEnabledForCarrier, mIsOnlyNonTerrestrialNetwork,
mServiceCapabilities, mTransferStatus, mIsSatelliteEntitlementStatus,
- mSatelliteEntitlementPlmns, mIsSatelliteESOSSupported);
+ mSatelliteEntitlementPlmns, mIsSatelliteESOSSupported,
+ mIsSatelliteProvisionedForNonIpDatagram);
result = 31 * result + Arrays.hashCode(mNativeAccessRules);
result = 31 * result + Arrays.hashCode(mCarrierConfigAccessRules);
result = 31 * result + Arrays.hashCode(mRcsConfig);
@@ -1894,6 +1918,11 @@
private int mIsSatelliteESOSSupported = 0;
/**
+ * Whether this subscription is provisioned for oem satellite service or not.
+ */
+ private int mIsSatelliteProvisionedForNonIpDatagram = 0;
+
+ /**
* Default constructor.
*/
public Builder() {
@@ -1976,6 +2005,7 @@
mIsSatelliteEntitlementStatus = info.mIsSatelliteEntitlementStatus;
mSatelliteEntitlementPlmns = info.mSatelliteEntitlementPlmns;
mIsSatelliteESOSSupported = info.mIsSatelliteESOSSupported;
+ mIsSatelliteProvisionedForNonIpDatagram = info.mIsSatelliteProvisionedForNonIpDatagram;
}
/**
@@ -2959,6 +2989,20 @@
}
/**
+ * Set whether the subscription is provisioned for oem satellite service or not.
+ *
+ * @param isSatelliteProvisionedForNonIpDatagram {@code 1} if the subscription is for NTN,
+ * {@code 0} otherwise.
+ * @return The builder.
+ */
+ @NonNull
+ public Builder setIsSatelliteProvisionedForNonIpDatagram(
+ int isSatelliteProvisionedForNonIpDatagram) {
+ mIsSatelliteProvisionedForNonIpDatagram = isSatelliteProvisionedForNonIpDatagram;
+ return this;
+ }
+
+ /**
* Build the {@link SubscriptionInfoInternal}.
*
* @return The {@link SubscriptionInfoInternal} instance.
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index ecd546a..6ef7328 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -196,7 +196,8 @@
SimInfo.COLUMN_IS_ONLY_NTN,
SimInfo.COLUMN_SATELLITE_ENTITLEMENT_STATUS,
SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS,
- SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED
+ SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED,
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM
);
/**
@@ -457,6 +458,13 @@
* @param subId The subscription id.
*/
public void onUiccApplicationsEnabledChanged(int subId) {}
+
+ /**
+ * Called when {@link #getDefaultDataSubId()} changed.
+ *
+ * @param subId The subscription id.
+ */
+ public void onDefaultDataSubscriptionChanged(int subId) {}
}
/**
@@ -592,6 +600,13 @@
// Broadcast sub Id on service initialized.
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
getDefaultDataSubId());
+ if (mFeatureFlags.ddsCallback()) {
+ mSubscriptionManagerServiceCallbacks.forEach(
+ callback -> callback.invokeFromExecutor(
+ () -> callback.onDefaultDataSubscriptionChanged(
+ getDefaultDataSubId())));
+ }
+
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED,
getDefaultVoiceSubId());
broadcastSubId(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED,
@@ -912,6 +927,8 @@
* @param subId The subscription id.
*/
public void setCountryIso(int subId, @NonNull String iso) {
+ logl("setCountryIso: subId=" + subId + ", iso=" + iso);
+
// This can throw IllegalArgumentException if the subscription does not exist.
try {
mSubscriptionDatabaseManager.setCountryIso(subId, iso);
@@ -928,6 +945,8 @@
* @param carrierName The carrier name.
*/
public void setCarrierName(int subId, @NonNull String carrierName) {
+ logl("setCarrierName: subId=" + subId + ", carrierName=" + carrierName);
+
// This can throw IllegalArgumentException if the subscription does not exist.
try {
mSubscriptionDatabaseManager.setCarrierName(subId, carrierName);
@@ -999,6 +1018,9 @@
* @param numberFromIms The phone number retrieved from IMS.
*/
public void setNumberFromIms(int subId, @NonNull String numberFromIms) {
+ logl("setNumberFromIms: subId=" + subId + ", number="
+ + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, numberFromIms));
+
// This can throw IllegalArgumentException if the subscription does not exist.
try {
mSubscriptionDatabaseManager.setNumberFromIms(subId, numberFromIms);
@@ -1893,7 +1915,10 @@
+ "carrier privilege");
}
- enforceTelephonyFeatureWithException(callingPackage, "getAllSubInfoList");
+ if (!mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_force_phone_globals_creation)) {
+ enforceTelephonyFeatureWithException(callingPackage, "getAllSubInfoList");
+ }
return getSubscriptionInfoStreamAsUser(BINDER_WRAPPER.getCallingUserHandle())
// callers have READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE can get a full
@@ -3166,6 +3191,11 @@
broadcastSubId(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,
subId);
+ if (mFeatureFlags.ddsCallback()) {
+ mSubscriptionManagerServiceCallbacks.forEach(
+ callback -> callback.invokeFromExecutor(
+ () -> callback.onDefaultDataSubscriptionChanged(subId)));
+ }
updateDefaultSubId();
}
@@ -3895,10 +3925,20 @@
switch(source) {
case SubscriptionManager.PHONE_NUMBER_SOURCE_UICC:
final Phone phone = PhoneFactory.getPhone(getSlotIndex(subId));
- if (phone != null) {
- return TextUtils.emptyIfNull(phone.getLine1Number());
- } else {
+ if (mFeatureFlags.uiccPhoneNumberFix()) {
+ if (phone != null) {
+ String number = phone.getLine1Number();
+ if (!TextUtils.isEmpty(number)) {
+ return number;
+ }
+ }
return subInfo.getNumber();
+ } else {
+ if (phone != null) {
+ return TextUtils.emptyIfNull(phone.getLine1Number());
+ } else {
+ return subInfo.getNumber();
+ }
}
case SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER:
return subInfo.getNumberFromCarrier();
@@ -4006,6 +4046,9 @@
@RequiresPermission("carrier privileges")
public void setPhoneNumber(int subId, @PhoneNumberSource int source, @NonNull String number,
@NonNull String callingPackage, @Nullable String callingFeatureId) {
+ logl("setPhoneNumber: subId=" + subId + ", number="
+ + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, number)
+ + ", calling package=" + callingPackage);
if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
throw new SecurityException("setPhoneNumber for CARRIER needs carrier privilege.");
}
@@ -4636,6 +4679,24 @@
}
/**
+ * Set whether the subscription is provisioned for OEM-enabled or carrier roaming NB-IOT
+ * satellite service or not.
+ *
+ * @param subId subscription id.
+ * @param isSatelliteProvisionedForNonIpDatagram {@code true} if subId is provisioned.
+ * {@code false} otherwise.
+ */
+ public void setIsSatelliteProvisionedForNonIpDatagram(int subId,
+ boolean isSatelliteProvisionedForNonIpDatagram) {
+ try {
+ mSubscriptionDatabaseManager.setIsSatelliteProvisionedForNonIpDatagram(
+ subId, (isSatelliteProvisionedForNonIpDatagram ? 1 : 0));
+ } catch (IllegalArgumentException e) {
+ loge("setIsSatelliteProvisionedForNonIpDatagram: invalid subId=" + subId);
+ }
+ }
+
+ /**
* Get the satellite ESOS supported value in the subscription database.
*
* @param subId subscription id.
@@ -4655,6 +4716,20 @@
}
/**
+ * Get whether the subscription is provisioned for OEM-enabled or carrier roaming NB-IOT
+ * satellite service or not.
+ *
+ * @param subId subscription id.
+ * @return {@code true} if it is provisioned for oem satellite service. {@code false} otherwise.
+ */
+ public boolean isSatelliteProvisionedForNonIpDatagram(int subId) {
+ SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternal(
+ subId);
+
+ return subInfo.getIsSatelliteProvisionedForNonIpDatagram() == 1;
+ }
+
+ /**
* checks whether esim bootstrap is activated for any of the available active subscription info
* list.
*
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index a97b00b..34b412f 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -48,6 +48,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* {@hide}
@@ -1278,15 +1279,22 @@
case EVENT_GET_FPLMN_SIZE_DONE:
ar = (AsyncResult) msg.obj;
+ int key = msg.arg2;
+
+ Message response;
+ Pair<Message, Object> transaction = null;
+ if (ar.exception != null && ar.userObj != null) {
+ response = (Message) ar.userObj;
+ } else {
+ transaction = retrievePendingTransaction(key);
+ response = Objects.requireNonNull(transaction.first);
+ }
+
if (ar.exception != null) {
- Message response = (Message) ar.userObj;
AsyncResult.forMessage(response).exception = ar.exception;
response.sendToTarget();
break;
}
- int key = msg.arg2;
- Pair<Message, Object> transaction = retrievePendingTransaction(key);
- Message response = transaction.first;
List<String> fplmns = (List<String>) transaction.second;
int dataLength = (int) ar.result;
if (dataLength < 0 || dataLength % FPLMN_BYTE_SIZE != 0) {
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
index f42d5a2..97fb9ca 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
@@ -18,7 +18,7 @@
import android.annotation.Nullable;
import android.content.Context;
-import android.content.SharedPreferences;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
@@ -34,7 +34,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
-import java.util.NoSuchElementException;
/**
* This class sends a list of APDU commands to an AID on a UICC. A logical channel will be opened
@@ -58,7 +57,7 @@
private static final int WAIT_TIME_MS = 2000;
private static final String CHANNEL_ID_PRE = "esim-channel";
- private static final String ISD_R_AID = "A0000005591010FFFFFFFF8900000100";
+ static final String ISD_R_AID = "A0000005591010FFFFFFFF8900000100";
private static final String CHANNEL_RESPONSE_ID_PRE = "esim-res-id";
private static void logv(String msg) {
@@ -88,6 +87,9 @@
*/
public ApduSender(Context context, int phoneId, CommandsInterface ci, String aid,
boolean supportExtendedApdu) {
+ if (!aid.equals(ISD_R_AID) && !"user".equals(Build.TYPE)) {
+ throw new IllegalArgumentException("Only ISD-R AID is supported.");
+ }
mAid = aid;
mContext = context;
mSupportExtendedApdu = supportExtendedApdu;
@@ -146,8 +148,7 @@
int channel = openChannelResponse.getChannel();
int status = openChannelResponse.getStatus();
byte[] selectResponse = openChannelResponse.getSelectResponse();
- if (mAid.equals(ISD_R_AID)
- && status == IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT) {
+ if (status == IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT) {
channel = PreferenceManager.getDefaultSharedPreferences(mContext)
.getInt(mChannelKey, IccOpenLogicalChannelResponse.INVALID_CHANNEL);
if (channel != IccOpenLogicalChannelResponse.INVALID_CHANNEL) {
@@ -173,13 +174,11 @@
RequestBuilder builder = new RequestBuilder(channel, mSupportExtendedApdu);
Throwable requestException = null;
- if (mAid.equals(ISD_R_AID)) {
- PreferenceManager.getDefaultSharedPreferences(mContext)
- .edit().putInt(mChannelKey, channel).apply();
- PreferenceManager.getDefaultSharedPreferences(mContext)
+ PreferenceManager.getDefaultSharedPreferences(mContext)
+ .edit().putInt(mChannelKey, channel).apply();
+ PreferenceManager.getDefaultSharedPreferences(mContext)
.edit().putString(mChannelResponseKey,
- Base64.encodeToString(selectResponse, Base64.DEFAULT)).apply();
- }
+ Base64.encodeToString(selectResponse, Base64.DEFAULT)).apply();
try {
requestProvider.buildRequest(selectResponse, builder);
} catch (Throwable e) {
@@ -304,12 +303,10 @@
@Override
public void onResult(Boolean aBoolean) {
synchronized (mChannelLock) {
- if (mAid.equals(ISD_R_AID)) {
- PreferenceManager.getDefaultSharedPreferences(mContext)
- .edit().remove(mChannelKey).apply();
- PreferenceManager.getDefaultSharedPreferences(mContext)
- .edit().remove(mChannelResponseKey).apply();
- }
+ PreferenceManager.getDefaultSharedPreferences(mContext)
+ .edit().remove(mChannelKey).apply();
+ PreferenceManager.getDefaultSharedPreferences(mContext)
+ .edit().remove(mChannelResponseKey).apply();
mChannelOpened = false;
mChannelLock.notify();
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index 4af6f7e..c923f69 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -136,7 +136,9 @@
+ Telephony.SimInfo.COLUMN_TRANSFER_STATUS + " INTEGER DEFAULT 0,"
+ Telephony.SimInfo.COLUMN_SATELLITE_ENTITLEMENT_STATUS + " INTEGER DEFAULT 0,"
+ Telephony.SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS + " TEXT,"
- + Telephony.SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED + " INTEGER DEFAULT 0"
+ + Telephony.SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED + " INTEGER DEFAULT 0,"
+ + Telephony.SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM
+ + " INTEGER DEFAULT 0"
+ ");";
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index b9fac4a..1465176 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -26,6 +26,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.nullable;
@@ -594,7 +595,7 @@
sst.setRadioPowerForReason(false, false, false, false, reason);
assertTrue(sst.getRadioPowerOffReasons().contains(reason));
assertTrue(sst.getRadioPowerOffReasons().size() == 1);
- verify(mSatelliteController).onCellularRadioPowerOffRequested();
+ verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false));
clearInvocations(mSatelliteController);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
@@ -602,7 +603,7 @@
TelephonyManager.RADIO_POWER_REASON_USER);
assertTrue(sst.getRadioPowerOffReasons().contains(reason));
assertTrue(sst.getRadioPowerOffReasons().size() == 1);
- verify(mSatelliteController, never()).onCellularRadioPowerOffRequested();
+ verify(mSatelliteController, never()).onSetCellularRadioPowerStateRequested(anyBoolean());
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_OFF);
@@ -610,7 +611,7 @@
// had been turned off for.
sst.setRadioPowerForReason(true, false, false, false, reason);
assertTrue(sst.getRadioPowerOffReasons().isEmpty());
- verify(mSatelliteController, never()).onCellularRadioPowerOffRequested();
+ verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(true));
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
@@ -1928,6 +1929,8 @@
sst.setRadioPower(false);
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertTrue(mSimulatedCommands.getRadioState() == TelephonyManager.RADIO_POWER_ON);
+ verify(mSatelliteController).onSetCellularRadioPowerStateRequested(eq(false));
+ verify(mSatelliteController).onPowerOffCellularRadioFailed();
sst.requestShutdown();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
assertFalse(mSimulatedCommands.getRadioState()
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 38b4f77..36ac992 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -580,6 +580,7 @@
mNullCipherNotifier = Mockito.mock(NullCipherNotifier.class);
doReturn(true).when(mFeatureFlags).minimalTelephonyCdmCheck();
+ doReturn(true).when(mFeatureFlags).supportNetworkProvider();
TelephonyManager.disableServiceHandleCaching();
PropertyInvalidatedCache.disableForTestMode();
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 499c1f5..0c2faa1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -159,7 +159,6 @@
private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23;
// Mocked classes
- private PhoneSwitcher mMockedPhoneSwitcher;
protected ISub mMockedIsub;
private DataNetworkControllerCallback mMockedDataNetworkControllerCallback;
private DataRetryManagerCallback mMockedDataRetryManagerCallback;
@@ -855,7 +854,6 @@
public void setUp() throws Exception {
logd("DataNetworkControllerTest +Setup!");
super.setUp(getClass().getSimpleName());
- mMockedPhoneSwitcher = Mockito.mock(PhoneSwitcher.class);
mMockedIsub = Mockito.mock(ISub.class);
mMockedImsManager = mContext.getSystemService(ImsManager.class);
mMockedImsMmTelManager = Mockito.mock(ImsMmTelManager.class);
@@ -878,7 +876,6 @@
mMockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
mMockedWlanDataServiceManager);
- replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mMockedPhoneSwitcher);
doReturn(1).when(mMockedIsub).getDefaultDataSubId();
doReturn(mMockedIsub).when(mIBinder).queryLocalInterface(anyString());
doReturn(mPhone).when(mPhone).getImsPhone();
@@ -4908,14 +4905,10 @@
NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
ConnectivityManager.TYPE_MOBILE, 0, NetworkRequest.Type.REQUEST);
-
- mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
- nativeNetworkRequest, mPhone, mFeatureFlags));
- processAllMessages();
-
- // Intentionally create a new telephony request with the original native network request.
TelephonyNetworkRequest request = new TelephonyNetworkRequest(
nativeNetworkRequest, mPhone, mFeatureFlags);
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
mDataNetworkControllerUT.removeNetworkRequest(request);
processAllFutureMessages();
@@ -4936,7 +4929,7 @@
processAllMessages();
// this slot is 0, modem preferred on slot 1
- doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
+ doReturn(1).when(mPhoneSwitcher).getPreferredDataPhoneId();
// Simulate telephony network factory remove request due to switch.
mDataNetworkControllerUT.removeNetworkRequest(request);
@@ -4949,7 +4942,7 @@
@Test
public void testSetupDataOnNonDds() throws Exception {
// this slot is 0, modem preferred on slot 1
- doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
+ doReturn(1).when(mPhoneSwitcher).getPreferredDataPhoneId();
TelephonyNetworkRequest request = createNetworkRequest(
NetworkCapabilities.NET_CAPABILITY_MMS);
@@ -5475,4 +5468,18 @@
assertThat(mDataNetworkControllerUT.getInternetEvaluation(true/*ignoreExistingNetworks*/)
.containsDisallowedReasons()).isTrue();
}
+
+ @Test
+ public void testRemoveNetworkRequestClearState() throws Exception {
+ TelephonyNetworkRequest request = createNetworkRequest(
+ NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
+ verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ assertThat(request.getState()).isEqualTo(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
+
+ mDataNetworkControllerUT.removeNetworkRequest(request);
+ processAllMessages();
+ assertThat(request.getState()).isEqualTo(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index 8be0f8b..6539ca9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -25,6 +25,7 @@
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -86,6 +87,7 @@
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
+import com.android.internal.telephony.data.PhoneSwitcher.PhoneSwitcherCallback;
import com.android.internal.telephony.metrics.DataCallSessionStats;
import com.android.internal.telephony.test.SimulatedCommands;
@@ -238,14 +240,14 @@
// Mocked classes
private DataNetworkCallback mDataNetworkCallback;
private DataCallSessionStats mDataCallSessionStats;
- private PhoneSwitcher mMockedPhoneSwitcher;
-
private final NetworkRegistrationInfo mIwlanNetworkRegistrationInfo =
new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
+ private PhoneSwitcherCallback mPhoneSwitcherCallback;
+
private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid) {
setSuccessfulSetupDataResponse(dsm, cid, Collections.emptyList(), null);
}
@@ -379,14 +381,13 @@
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
+ doReturn(1).when(mPhone).getSubId();
doReturn(mImsPhone).when(mPhone).getImsPhone();
doReturn(mImsCT).when(mImsPhone).getCallTracker();
doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
mDataNetworkCallback = Mockito.mock(DataNetworkCallback.class);
mDataCallSessionStats = Mockito.mock(DataCallSessionStats.class);
- mMockedPhoneSwitcher = Mockito.mock(PhoneSwitcher.class);
- replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mMockedPhoneSwitcher);
doAnswer(invocation -> {
((Runnable) invocation.getArguments()[0]).run();
return null;
@@ -2662,4 +2663,35 @@
assertThat(mDataNetworkUT.getNetworkCapabilities()
.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
}
+
+ @Test
+ public void testPrimaryTransport() throws Exception {
+ doReturn(0).when(mPhoneSwitcher).getPreferredDataPhoneId();
+ setupDataNetwork();
+ TelephonyNetworkAgent mockNetworkAgent = Mockito.mock(TelephonyNetworkAgent.class);
+ replaceInstance(DataNetwork.class, "mNetworkAgent",
+ mDataNetworkUT, mockNetworkAgent);
+
+ ArgumentCaptor<PhoneSwitcherCallback> callbackCaptor =
+ ArgumentCaptor.forClass(PhoneSwitcherCallback.class);
+ verify(mPhoneSwitcher).registerCallback(callbackCaptor.capture());
+ mPhoneSwitcherCallback = callbackCaptor.getValue();
+
+ // Switch the preferred data subscription to another.
+ mPhoneSwitcherCallback.onPreferredDataPhoneIdChanged(1);
+ processAllMessages();
+
+ ArgumentCaptor<NetworkScore> networkScoreCaptor =
+ ArgumentCaptor.forClass(NetworkScore.class);
+ verify(mockNetworkAgent).sendNetworkScore(networkScoreCaptor.capture());
+ assertThat(networkScoreCaptor.getValue().isTransportPrimary()).isFalse();
+ clearInvocations(mockNetworkAgent);
+
+ // Switch back
+ mPhoneSwitcherCallback.onPreferredDataPhoneIdChanged(0);
+ processAllMessages();
+
+ verify(mockNetworkAgent).sendNetworkScore(networkScoreCaptor.capture());
+ assertThat(networkScoreCaptor.getValue().isTransportPrimary()).isTrue();
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index acfa16d..89cdc47 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -882,6 +882,40 @@
}
@Test
+ public void testTrafficDescriptorRequestRetry() {
+ DataSetupRetryRule retryRule = new DataSetupRetryRule(
+ "capabilities=PRIORITIZE_BANDWIDTH, retry_interval=200, maximum_retries=2");
+ doReturn(Collections.singletonList(retryRule)).when(mDataConfigManager)
+ .getDataSetupRetryRules();
+ mDataConfigManagerCallback.onCarrierConfigChanged();
+ processAllMessages();
+
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
+ .build();
+ TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone, mFeatureFlags);
+ DataNetworkController.NetworkRequestList
+ networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
+
+ // failed and retry.
+ mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
+ DataCallResponse.RETRY_DURATION_UNDEFINED);
+ processAllFutureMessages();
+
+ tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ .build(), mPhone, mFeatureFlags);
+ assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isTrue();
+ assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isFalse();
+ }
+
+
+ @Test
public void testRilCrashedReset() {
testDataSetupRetryNetworkSuggestedNeverRetry();
Mockito.clearInvocations(mDataRetryManagerCallbackMock, mDataProfileManager);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
index 3f18a3a..620cf39 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataSettingsManagerTest.java
@@ -42,6 +42,7 @@
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.After;
import org.junit.Before;
@@ -184,6 +185,49 @@
}
@Test
+ public void testUpdateDataEnabledAndNotifyOverrideDdsChange() throws Exception {
+ // Mock 2nd phone the DDS phone.
+ int phone2Id = 1;
+ int phone2SubId = 2;
+ doReturn(phone2SubId).when(mSubscriptionManagerService).getDefaultDataSubId();
+ Phone phone2 = Mockito.mock(Phone.class);
+ doReturn(phone2Id).when(phone2).getPhoneId();
+ doReturn(phone2SubId).when(phone2).getSubId();
+ doReturn(phone2Id).when(mSubscriptionManagerService).getPhoneId(phone2SubId);
+ DataSettingsManager dataSettingsManager2 = Mockito.mock(DataSettingsManager.class);
+ doReturn(dataSettingsManager2).when(phone2).getDataSettingsManager();
+ doReturn(true).when(phone2).isUserDataEnabled();
+
+ mPhones = new Phone[] {mPhone, phone2};
+ replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+ ArgumentCaptor<SubscriptionManagerService.SubscriptionManagerServiceCallback>
+ callbackArgumentCaptor = ArgumentCaptor
+ .forClass(SubscriptionManagerService.SubscriptionManagerServiceCallback.class);
+
+ mDataSettingsManagerUT.sendEmptyMessage(11 /* EVENT_INITIALIZE */);
+ mDataSettingsManagerUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, false, "");
+ processAllMessages();
+
+ // Verify listening to DDS change callback
+ verify(mSubscriptionManagerService, times(2))
+ .registerCallback(callbackArgumentCaptor.capture());
+ SubscriptionManagerService.SubscriptionManagerServiceCallback callback =
+ callbackArgumentCaptor.getValue();
+
+ // Mock the phone as nonDDS auto switch override enabled.
+ clearInvocations(mPhones);
+ mDataSettingsManagerUT.setMobileDataPolicy(
+ TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, true);
+ processAllMessages();
+ verify(mPhone).notifyDataEnabled(true, TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
+
+ // The phone became DDS, data should be disabled
+ doReturn(mPhone.getSubId()).when(mSubscriptionManagerService).getDefaultDataSubId();
+ callback.onDefaultDataSubscriptionChanged(mPhone.getSubId());
+ verify(mPhone).notifyDataEnabled(false, TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
+ }
+
+ @Test
public void testNotifyDataEnabledFromNewValidSubId() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mDataSettingsManagerUT.registerCallback(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index 2a1fedb..f7990b9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -52,18 +52,15 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
-import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.Messenger;
import android.telephony.AccessNetworkConstants;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneCapability;
@@ -75,8 +72,6 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import androidx.test.filters.SmallTest;
-
import com.android.ims.ImsException;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CommandException;
@@ -87,11 +82,11 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
+import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
import org.junit.After;
import org.junit.Before;
@@ -140,9 +135,6 @@
private PhoneSwitcher mPhoneSwitcherUT;
private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener;
- private ConnectivityManager mConnectivityManager;
- // The messenger of PhoneSwitcher used to receive network requests.
- private Messenger mNetworkProviderMessenger = null;
private Map<Integer, DataSettingsManager.DataSettingsManagerCallback>
mDataSettingsManagerCallbacks;
private int mDefaultDataSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -155,6 +147,7 @@
private TelephonyDisplayInfo mTelephonyDisplayInfo = new TelephonyDisplayInfo(
TelephonyManager.NETWORK_TYPE_NR,
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false);
+ private SubscriptionManagerServiceCallback mSubscriptionManagerServiceCallback;
@Before
public void setUp() throws Exception {
@@ -203,14 +196,13 @@
mServiceManagerMockedServices.put("isub", mIBinder);
doReturn(mTelephonyDisplayInfo).when(mDisplayInfoController).getTelephonyDisplayInfo();
+ doReturn(true).when(mFeatureFlags).ddsCallback();
}
@After
public void tearDown() throws Exception {
mPhoneSwitcherUT = null;
mSubChangedListener = null;
- mConnectivityManager = null;
- mNetworkProviderMessenger = null;
mTelephonyDisplayInfo = null;
super.tearDown();
}
@@ -219,7 +211,6 @@
* Test that a single phone case results in our phone being active and the RIL called
*/
@Test
- @SmallTest
public void testRegister() throws Exception {
initialize();
@@ -466,7 +457,6 @@
}
@Test
- @SmallTest
public void testAutoDataSwitch_exemptPingTest() throws Exception {
initialize();
@@ -504,7 +494,6 @@
* - don't switch phones when in emergency mode
*/
@Test
- @SmallTest
public void testPrioritization() throws Exception {
initialize();
@@ -539,7 +528,6 @@
* wins (ie, switch to wifi).
*/
@Test
- @SmallTest
public void testHigherPriorityDefault() throws Exception {
initialize();
@@ -572,7 +560,6 @@
* active one.
*/
@Test
- @SmallTest
public void testSetPreferredData() throws Exception {
initialize();
@@ -618,7 +605,6 @@
* 3. CBRS requests OR Auto switch requests - only one case applies at a time
*/
@Test
- @SmallTest
public void testSetPreferredDataCasePriority_CbrsWaitsForVoiceCall() throws Exception {
initialize();
setAllPhonesInactive();
@@ -672,7 +658,6 @@
}
@Test
- @SmallTest
public void testSetPreferredData_NoAutoSwitchWhenCbrs() throws Exception {
initialize();
setAllPhonesInactive();
@@ -726,7 +711,6 @@
}
@Test
- @SmallTest
public void testSetPreferredDataModemCommand() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -825,7 +809,6 @@
}
@Test
- @SmallTest
public void testSetPreferredDataWithValidation() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -886,7 +869,6 @@
}
@Test
- @SmallTest
public void testNonDefaultDataPhoneInCall_ImsCallOnLte_shouldSwitchDds() throws Exception {
initialize();
setAllPhonesInactive();
@@ -914,7 +896,6 @@
}
@Test
- @SmallTest
public void testNonDefaultDataPhoneInCall_ImsCallDialingOnLte_shouldSwitchDds()
throws Exception {
initialize();
@@ -948,7 +929,6 @@
assertEquals(1, mPhoneSwitcherUT.getPreferredDataPhoneId());
}
@Test
- @SmallTest
public void testNonDefaultDataPhoneInCall_ImsCallIncomingOnLte_shouldSwitchDds()
throws Exception {
initialize();
@@ -977,7 +957,6 @@
}
@Test
- @SmallTest
public void testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds() throws Exception {
initialize();
setAllPhonesInactive();
@@ -1004,7 +983,6 @@
}
@Test
- @SmallTest
public void testNonDefaultDataPhoneInCall_ImsCallOnCrossSIM_HandoverToLTE() throws Exception {
initialize();
setAllPhonesInactive();
@@ -1167,7 +1145,6 @@
}
@Test
- @SmallTest
public void testNetworkRequestOnNonDefaultData() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1192,7 +1169,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideSuccessBeforeCallStarts() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1213,7 +1189,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideNoDdsChange() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1233,7 +1208,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideEndSuccess() throws Exception {
PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500;
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1271,7 +1245,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideEcbmStartEnd() throws Exception {
PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500;
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1321,7 +1294,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideNoCallStart() throws Exception {
PhoneSwitcher.DEFAULT_DATA_OVERRIDE_TIMEOUT_MS = 500;
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1353,7 +1325,6 @@
}
@Test
- @SmallTest
public void testEmergencyOverrideMultipleOverrideRequests() throws Exception {
PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS = 500;
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
@@ -1404,7 +1375,6 @@
}
@Test
- @SmallTest
public void testSetPreferredDataCallback() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1579,7 +1549,6 @@
}
@Test
- @SmallTest
public void testMultiSimConfigChange() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
mActiveModemCount = 1;
@@ -1607,7 +1576,6 @@
}
@Test
- @SmallTest
public void testValidationOffSwitch_shouldSwitchOnNetworkAvailable() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1648,7 +1616,6 @@
}
@Test
- @SmallTest
public void testValidationOffSwitch_shouldSwitchOnTimeOut() throws Exception {
doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
initialize();
@@ -1771,7 +1738,6 @@
}
@Test
- @SmallTest
public void testRegisterForImsRegistrationCallback() throws Exception {
initialize();
setAllPhonesInactive();
@@ -1799,7 +1765,6 @@
}
@Test
- @SmallTest
public void testReceivingImsRegistrationTech() throws Exception {
doReturn(true).when(mFeatureFlags).changeMethodOfObtainingImsRegistrationRadioTech();
@@ -1880,9 +1845,6 @@
doReturn(true).when(mPhone2).isDataAllowed();
doReturn(true).when(mDataSettingsManager2).isDataEnabled();
- // 3.1 No default network
- doReturn(null).when(mConnectivityManager).getNetworkCapabilities(any());
-
mPhoneSwitcherUT.sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
}
@@ -2032,19 +1994,12 @@
}
}
- private void sendDefaultDataSubChanged() {
- final Intent intent = new Intent(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
- mContext.sendBroadcast(intent);
- processAllMessages();
- }
-
private void initialize() throws Exception {
setNumPhones(mActiveModemCount, mSupportedModemCount);
initializeSubControllerMock();
initializeCommandInterfacesMock();
initializeTelRegistryMock();
- initializeConnManagerMock();
initializeConfigMock();
mPhoneSwitcherUT = new PhoneSwitcher(mMaxDataAttachModemCount, mContext, Looper.myLooper(),
@@ -2066,6 +2021,11 @@
processAllMessages();
verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any());
+
+ ArgumentCaptor<SubscriptionManagerServiceCallback> callbackCaptor =
+ ArgumentCaptor.forClass(SubscriptionManagerServiceCallback.class);
+ verify(mSubscriptionManagerService).registerCallback(callbackCaptor.capture());
+ mSubscriptionManagerServiceCallback = callbackCaptor.getValue();
}
/**
@@ -2153,21 +2113,6 @@
* Capture mNetworkProviderMessenger so that testing can request or release
* network requests on PhoneSwitcher.
*/
- private void initializeConnManagerMock() {
- mConnectivityManager = (ConnectivityManager)
- mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- doAnswer(invocation -> {
- mNetworkProviderMessenger =
- ((NetworkProvider) invocation.getArgument(0)).getMessenger();
- return null;
- }).when(mConnectivityManager).registerNetworkProvider(any());
- }
-
- /**
- * Capture mNetworkProviderMessenger so that testing can request or release
- * network requests on PhoneSwitcher.
- */
private void initializeSubControllerMock() throws Exception {
doReturn(mDefaultDataSub).when(mSubscriptionManagerService).getDefaultDataSubId();
doReturn(mDefaultDataSub).when(mMockedIsub).getDefaultDataSubId();
@@ -2231,7 +2176,8 @@
doAnswer(invocation -> phone.getSubId() == mDefaultDataSub)
.when(phone).isUserDataEnabled();
}
- sendDefaultDataSubChanged();
+ mSubscriptionManagerServiceCallback.onDefaultDataSubscriptionChanged(defaultDataSub);
+ processAllMessages();
}
private void setSlotIndexToSubId(int slotId, int subId) {
@@ -2263,13 +2209,7 @@
NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE,
0, NetworkRequest.Type.REQUEST);
- Message message = Message.obtain();
- message.what = android.net.NetworkProvider.CMD_REQUEST_NETWORK;
- message.arg1 = score;
- message.obj = networkRequest;
- mNetworkProviderMessenger.send(message);
- processAllMessages();
-
+ mPhoneSwitcherUT.onRequestNetwork(networkRequest);
return networkRequest;
}
@@ -2287,14 +2227,7 @@
}
NetworkRequest networkRequest = new NetworkRequest(netCap, ConnectivityManager.TYPE_NONE,
1, NetworkRequest.Type.REQUEST);
-
- Message message = Message.obtain();
- message.what = android.net.NetworkProvider.CMD_REQUEST_NETWORK;
- message.arg1 = 50; // Score
- message.obj = networkRequest;
- mNetworkProviderMessenger.send(message);
- processAllMessages();
-
+ mPhoneSwitcherUT.onRequestNetwork(networkRequest);
return networkRequest;
}
@@ -2302,10 +2235,6 @@
* Tell PhoneSwitcher to release a network request.
*/
private void releaseNetworkRequest(NetworkRequest networkRequest) throws Exception {
- Message message = Message.obtain();
- message.what = android.net.NetworkProvider.CMD_CANCEL_REQUEST;
- message.obj = networkRequest;
- mNetworkProviderMessenger.send(message);
- processAllMessages();
+ mPhoneSwitcherUT.onReleaseNetwork(networkRequest);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkProviderTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkProviderTest.java
new file mode 100644
index 0000000..2fdf9e6
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkProviderTest.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.data;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.NonNull;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkCapabilities;
+import android.net.NetworkProvider;
+import android.net.NetworkRequest;
+import android.net.NetworkScore;
+import android.net.TelephonyNetworkSpecifier;
+import android.net.connectivity.android.net.INetworkOfferCallback;
+import android.os.Looper;
+import android.telephony.Annotation.NetCapability;
+import android.telephony.SubscriptionManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.data.PhoneSwitcher.PhoneSwitcherCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Arrays;
+import java.util.Set;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class TelephonyNetworkProviderTest extends TelephonyTest {
+
+ private TelephonyNetworkProvider mTelephonyNetworkProvider;
+
+ private PhoneSwitcherCallback mPhoneSwitcherCallback;
+
+ // Mocked classes
+ private DataNetworkController mDataNetworkController2;
+
+
+ /**
+ * Set the preferred data phone, which is supposed to take the network request.
+ *
+ * @param phoneId The phone id
+ */
+ private void setPreferredDataPhone(int phoneId) {
+ doAnswer(invocation -> {
+ TelephonyNetworkRequest request = (TelephonyNetworkRequest)
+ invocation.getArguments()[0];
+ int id = (int) invocation.getArguments()[1];
+
+ logd("shouldApplyNetworkRequest: request phone id=" + id
+ + ", preferred data phone id=" + phoneId);
+
+ TelephonyNetworkSpecifier specifier = (TelephonyNetworkSpecifier)
+ request.getNetworkSpecifier();
+ if (specifier != null) {
+ int subId = specifier.getSubscriptionId();
+ logd("shouldApplyNetworkRequest: requested on sub " + subId);
+ if (subId == 1 && mPhone.getPhoneId() == id) {
+ logd("shouldApplyNetworkRequest: matched phone 0");
+ return true;
+ }
+ if (subId == 2 && mPhone2.getPhoneId() == id) {
+ logd("shouldApplyNetworkRequest: matched phone 1");
+ return true;
+ }
+ return false;
+ }
+
+ if (request.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) return true;
+ return id == phoneId;
+ }).when(mPhoneSwitcher).shouldApplyNetworkRequest(any(TelephonyNetworkRequest.class),
+ anyInt());
+ }
+
+ /**
+ * Create a simple network request with internet capability.
+ *
+ * @return The network request
+ */
+ @NonNull
+ private NetworkRequest createNetworkRequest() {
+ return createNetworkRequestForSub(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ }
+
+ /**
+ * Create a network request with specified network capabilities.
+ *
+ * @param caps Network capabilities
+ *
+ * @return The network request
+ */
+ @NonNull
+ private NetworkRequest createNetworkRequest(@NetCapability int... caps) {
+ return createNetworkRequestForSub(SubscriptionManager.INVALID_SUBSCRIPTION_ID, caps);
+ }
+
+ /**
+ * Create a network request with subscription id specified.
+ *
+ * @param subId The subscription in for the network request
+ *
+ * @return The network request
+ */
+ @NonNull
+ private NetworkRequest createNetworkRequestForSub(int subId) {
+ return createNetworkRequestForSub(subId, NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ }
+
+ /**
+ * Create the network request.
+ *
+ * @param subId The subscription id. {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if no
+ * @param caps Network capabilities in the network request need to specify.
+ *
+ * @return The network request
+ */
+ @NonNull
+ private NetworkRequest createNetworkRequestForSub(int subId, @NetCapability int... caps) {
+ NetworkRequest.Builder builder = new NetworkRequest.Builder();
+ Arrays.stream(caps).boxed().toList().forEach(builder::addCapability);
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ builder.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId));
+ builder.setSubscriptionIds(Set.of(subId));
+ }
+
+ return builder.build();
+ }
+
+ /** Clear all invocations from all DataNetworkControllers. */
+ private void resetInvocations() {
+ clearInvocations(mDataNetworkController);
+ clearInvocations(mDataNetworkController2);
+ }
+
+ /**
+ * Verify the request was sent to the correct phone's DataNetworkController.
+ *
+ * @param phoneId The id of the phone that the request is supposed to send
+ * @param request The network request
+ */
+ private void verifyRequestSentOnPhone(int phoneId, @NonNull NetworkRequest request) {
+ ArgumentCaptor<TelephonyNetworkRequest> requestCaptor =
+ ArgumentCaptor.forClass(TelephonyNetworkRequest.class);
+
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (phone.getPhoneId() == phoneId) {
+ verify(phone.getDataNetworkController(), times(1)
+ .description("Did not request on phone " + phoneId))
+ .addNetworkRequest(requestCaptor.capture());
+ assertThat(requestCaptor.getValue().getNativeNetworkRequest()).isEqualTo(request);
+ } else {
+ verifyNoRequestSentOnPhone(phone.getPhoneId());
+ }
+ }
+ }
+
+ /**
+ * Verify the request was released on the specified phone's DataNetworkController.
+ *
+ * @param phoneId The id of the phone that the request is supposed to send
+ * @param request The network request
+ */
+ private void verifyRequestReleasedOnPhone(int phoneId, @NonNull NetworkRequest request) {
+ ArgumentCaptor<TelephonyNetworkRequest> requestCaptor =
+ ArgumentCaptor.forClass(TelephonyNetworkRequest.class);
+
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (phone.getPhoneId() == phoneId) {
+ verify(phone.getDataNetworkController(), times(1)
+ .description("Did not remove on phone " + phoneId))
+ .removeNetworkRequest(requestCaptor.capture());
+ assertThat(requestCaptor.getValue().getNativeNetworkRequest()).isEqualTo(request);
+ } else {
+ verifyNoRequestReleasedOnPhone(phone.getPhoneId());
+ }
+ }
+ }
+
+ /**
+ * Verify there is no request sent on specified phone.
+ *
+ * @param phoneId The phone id
+ */
+ private void verifyNoRequestSentOnPhone(int phoneId) {
+ verify(PhoneFactory.getPhone(phoneId).getDataNetworkController(), never()
+ .description("Should not request on phone " + phoneId))
+ .addNetworkRequest(any(TelephonyNetworkRequest.class));
+ }
+
+ /**
+ * Verify there is no request released on specified phone.
+ *
+ * @param phoneId The phone id
+ */
+ private void verifyNoRequestReleasedOnPhone(int phoneId) {
+ verify(PhoneFactory.getPhone(phoneId).getDataNetworkController(), never()
+ .description("Should not release on phone " + phoneId))
+ .removeNetworkRequest(any(TelephonyNetworkRequest.class));
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ logd("TelephonyNetworkProviderTest +Setup!");
+ super.setUp(getClass().getSimpleName());
+ replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone2});
+
+ mDataNetworkController2 = mock(DataNetworkController.class);
+
+ doReturn(0).when(mPhone).getPhoneId();
+ doReturn(1).when(mPhone).getSubId();
+ doReturn(1).when(mPhone2).getPhoneId();
+ doReturn(2).when(mPhone2).getSubId();
+
+ doReturn(mDataNetworkController2).when(mPhone2).getDataNetworkController();
+
+ setPreferredDataPhone(0);
+
+ doAnswer(invocation -> {
+ NetworkProvider provider = (NetworkProvider) invocation.getArguments()[0];
+ provider.setProviderId(1);
+ return 1;
+ }).when(mConnectivityManager).registerNetworkProvider(any(NetworkProvider.class));
+
+ mTelephonyNetworkProvider = new TelephonyNetworkProvider(Looper.myLooper(),
+ mContext, mFeatureFlags);
+
+ ArgumentCaptor<PhoneSwitcherCallback> callbackCaptor =
+ ArgumentCaptor.forClass(PhoneSwitcherCallback.class);
+ verify(mPhoneSwitcher).registerCallback(callbackCaptor.capture());
+ mPhoneSwitcherCallback = callbackCaptor.getValue();
+
+ logd("TelephonyNetworkProviderTest -Setup!");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ logd("tearDown");
+ super.tearDown();
+ }
+
+ @Test
+ public void testRegisterProvider() {
+ verify(mConnectivityManager).registerNetworkProvider(any(TelephonyNetworkProvider.class));
+
+ ArgumentCaptor<NetworkCapabilities> capsCaptor =
+ ArgumentCaptor.forClass(NetworkCapabilities.class);
+ verify(mConnectivityManager).offerNetwork(anyInt(), any(NetworkScore.class),
+ capsCaptor.capture(), any(INetworkOfferCallback.class));
+
+ NetworkCapabilities caps = capsCaptor.getValue();
+
+ TelephonyNetworkRequest.getAllSupportedNetworkCapabilities().forEach(
+ (cap) -> assertThat(caps.hasCapability(cap)));
+ assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)).isTrue();
+ assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
+ assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
+ assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();
+ assertThat(caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).isTrue();
+ assertThat(caps.hasTransport(NetworkCapabilities.TRANSPORT_SATELLITE)).isTrue();
+
+ assertThat(caps.getNetworkSpecifier()).isInstanceOf(MatchAllNetworkSpecifier.class);
+ }
+
+ @Test
+ public void testRequestNetwork() {
+ NetworkRequest request = createNetworkRequest();
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 0
+ verifyRequestSentOnPhone(0, request);
+ }
+
+ @Test
+ public void testReleaseNetwork() {
+ NetworkRequest request = createNetworkRequest();
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 0
+ verifyRequestSentOnPhone(0, request);
+ resetInvocations();
+
+ // Now release the network request.
+ mTelephonyNetworkProvider.onNetworkUnneeded(request);
+ // Should release on phone 0
+ verifyRequestReleasedOnPhone(0, request);
+ resetInvocations();
+
+ // Release the same request again should not result in another remove
+ mTelephonyNetworkProvider.onNetworkUnneeded(request);
+ verifyNoRequestReleasedOnPhone(0);
+ verifyNoRequestReleasedOnPhone(1);
+ }
+
+ @Test
+ public void testRequestNetworkDuplicate() {
+ NetworkRequest request = createNetworkRequest();
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 0
+ verifyRequestSentOnPhone(0, request);
+
+ resetInvocations();
+ // send the same request again should be blocked.
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ verifyNoRequestSentOnPhone(0);
+ verifyNoRequestSentOnPhone(1);
+ }
+
+ @Test
+ public void testRequestNetworkPreferredPhone1() {
+ setPreferredDataPhone(1);
+
+ NetworkRequest request = createNetworkRequest();
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 1
+ verifyRequestSentOnPhone(1, request);
+ }
+
+ @Test
+ public void testRequestEmergencyNetwork() {
+ setPreferredDataPhone(1);
+
+ NetworkRequest request = createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_EIMS);
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 0
+ verifyRequestSentOnPhone(0, request);
+ }
+
+ @Test
+ public void testRequestNetworkOnSpecifiedSub() {
+ NetworkRequest request = createNetworkRequestForSub(1);
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ verifyRequestSentOnPhone(0, request);
+
+ resetInvocations();
+ request = createNetworkRequestForSub(2);
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 1
+ verifyRequestSentOnPhone(1, request);
+ }
+
+ @Test
+ public void testPreferredDataSwitch() {
+ NetworkRequest request = createNetworkRequest();
+ mTelephonyNetworkProvider.onNetworkNeeded(request);
+ // Should request on phone 0
+ verifyRequestSentOnPhone(0, request);
+ resetInvocations();
+
+ // Now switch from phone 0 to phone 1
+ setPreferredDataPhone(1);
+ mPhoneSwitcherCallback.onPreferredDataPhoneIdChanged(1);
+ verifyRequestReleasedOnPhone(0, request);
+ verifyRequestSentOnPhone(1, request);
+ resetInvocations();
+
+ // Now switch back to phone 0
+ setPreferredDataPhone(0);
+ mPhoneSwitcherCallback.onPreferredDataPhoneIdChanged(0);
+ verifyRequestReleasedOnPhone(1, request);
+ verifyRequestSentOnPhone(0, request);
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
index 9f11a3a..27c87e2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
@@ -189,7 +189,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
.build(), mPhone, mFeatureFlags);
- assertThat(request.getApnTypeNetworkCapability())
+ assertThat(request.getHighestPriorityApnTypeNetworkCapability())
.isEqualTo(NetworkCapabilities.NET_CAPABILITY_SUPL);
request = new TelephonyNetworkRequest(
@@ -198,7 +198,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
.build(), mPhone, mFeatureFlags);
- assertThat(request.getApnTypeNetworkCapability())
+ assertThat(request.getHighestPriorityApnTypeNetworkCapability())
.isEqualTo(NetworkCapabilities.NET_CAPABILITY_FOTA);
request = new TelephonyNetworkRequest(
@@ -207,7 +207,7 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
.build(), mPhone, mFeatureFlags);
- assertThat(request.getApnTypeNetworkCapability())
+ assertThat(request.getHighestPriorityApnTypeNetworkCapability())
.isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
index e374551..53e508b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -49,6 +49,7 @@
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
+import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserManager;
@@ -87,7 +88,12 @@
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Stubber;
@@ -106,6 +112,8 @@
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule
+ public MockitoRule rule = MockitoJUnit.rule();
private static final DownloadableSubscription SUBSCRIPTION =
DownloadableSubscription.forActivationCode("abcde");
@@ -145,8 +153,8 @@
private static final long AVAILABLE_MEMORY = 123L;
// Mocked classes
- private EuiccConnector mMockConnector;
- private UiccSlot mUiccSlot;
+ @Mock private EuiccConnector mMockConnector;
+ @Captor private ArgumentCaptor<Bundle> mBundleCaptor;
private TestEuiccController mController;
private int mSavedEuiccProvisionedValue;
@@ -218,8 +226,6 @@
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
- mMockConnector = Mockito.mock(EuiccConnector.class);
- mUiccSlot = Mockito.mock(UiccSlot.class);
mController = new TestEuiccController(mContext, mMockConnector, mFeatureFlags);
PackageInfo pi = new PackageInfo();
@@ -580,8 +586,15 @@
public void testDownloadSubscription_success() throws Exception {
setHasWriteEmbeddedPermission(true);
setUpUiccSlotData();
+
callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
EuiccService.RESULT_OK, 0 /* resolvableError */, "whatever" /* callingPackage */);
+
+ verify(mMockConnector).downloadSubscription(anyInt(), anyInt(),
+ any(), eq(true), anyBoolean(), mBundleCaptor.capture(), any());
+ assertEquals(
+ "whatever",
+ mBundleCaptor.getValue().getString(EuiccService.EXTRA_PACKAGE_NAME));
verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
// switchAfterDownload = true so no refresh should occur.
assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult);
@@ -591,8 +604,15 @@
@DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
public void testDownloadSubscription_noSwitch_success() throws Exception {
setHasWriteEmbeddedPermission(true);
+
callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
EuiccService.RESULT_OK, 0 /* resolvableError */, "whatever" /* callingPackage */);
+
+ verify(mMockConnector).downloadSubscription(anyInt(), anyInt(),
+ any(), eq(false), anyBoolean(), mBundleCaptor.capture(), any());
+ assertEquals(
+ "whatever",
+ mBundleCaptor.getValue().getString(EuiccService.EXTRA_PACKAGE_NAME));
verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index ed19fd3..e542a41 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -173,6 +173,7 @@
UserManager userManager = (UserManager)mContext.getSystemService(Context.USER_SERVICE);
doReturn(true).when(userManager).isUserUnlocked();
+ doReturn(true).when(userManager).isUserUnlocked(any(UserHandle.class));
doReturn(true).when(userManager).isUserRunning(any(UserHandle.class));
List<UserHandle> userHandles = new ArrayList();
@@ -384,6 +385,7 @@
// user locked
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
doReturn(false).when(userManager).isUserUnlocked();
+ doReturn(false).when(userManager).isUserUnlocked(any(UserHandle.class));
transitionFromStartupToIdle();
@@ -398,10 +400,19 @@
// New message notification should be shown.
NotificationManager notificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- verify(notificationManager).notify(
- eq(InboundSmsHandler.NOTIFICATION_TAG),
- eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
- any(Notification.class));
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ verify(notificationManager).notifyAsUser(
+ eq(InboundSmsHandler.NOTIFICATION_TAG),
+ eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
+ any(Notification.class),
+ eq(MOCKED_MAIN_USER));
+ } else {
+ verify(notificationManager).notify(
+ eq(InboundSmsHandler.NOTIFICATION_TAG),
+ eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
+ any(Notification.class));
+
+ }
}
@Test
@@ -413,6 +424,7 @@
// user locked
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
doReturn(false).when(userManager).isUserUnlocked();
+ doReturn(false).when(userManager).isUserUnlocked(any(UserHandle.class));
transitionFromStartupToIdle();
@@ -427,10 +439,19 @@
// No new message notification should be shown.
NotificationManager notificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- verify(notificationManager, never()).notify(
- eq(InboundSmsHandler.NOTIFICATION_TAG),
- eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
- any(Notification.class));
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ verify(notificationManager, never()).notifyAsUser(
+ eq(InboundSmsHandler.NOTIFICATION_TAG),
+ eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
+ any(Notification.class),
+ eq(MOCKED_MAIN_USER));
+ } else {
+ verify(notificationManager, never()).notify(
+ eq(InboundSmsHandler.NOTIFICATION_TAG),
+ eq(InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE),
+ any(Notification.class));
+
+ }
}
@Test
@@ -1076,14 +1097,21 @@
// user locked
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
doReturn(false).when(userManager).isUserUnlocked();
+ doReturn(false).when(userManager).isUserUnlocked(any(UserHandle.class));
- SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ SmsBroadcastUndelivered.initialize(
+ mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
- // verify that a broadcast receiver is registered for current user (user == null) based on
- // implementation in ContextFixture. registerReceiver may be called more than once (for
- // example by GsmInboundSmsHandler if TEST_MODE is true)
- verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class),
- any(IntentFilter.class));
+ if (mFeatureFlags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
+ verify(mContext).registerReceiverAsUser(any(BroadcastReceiver.class),
+ any(UserHandle.class), any(IntentFilter.class), any(), any());
+ } else {
+ // verify that a broadcast receiver is registered for current user (user == null) based
+ // on implementation in ContextFixture. registerReceiver may be called more than once
+ // (for example by GsmInboundSmsHandler if TEST_MODE is true)
+ verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class),
+ any(IntentFilter.class));
+ }
// wait for ScanRawTableThread
waitForMs(100);
@@ -1094,7 +1122,10 @@
// when user unlocks the device, the message in db should be broadcast
doReturn(true).when(userManager).isUserUnlocked();
- mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED));
+ doReturn(true).when(userManager).isUserUnlocked(any(UserHandle.class));
+ mContext.sendBroadcast(
+ new Intent(Intent.ACTION_USER_UNLOCKED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, MOCKED_MAIN_USER.getIdentifier()));
// wait for ScanRawTableThread
waitForMs(100);
processAllMessages();
@@ -1129,7 +1160,8 @@
// add a fake entry to db
mContentProvider.insert(sRawUri, mInboundSmsTracker.getContentValues());
- SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ SmsBroadcastUndelivered.initialize(
+ mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
// wait for ScanRawTableThread
waitForMs(100);
@@ -1144,7 +1176,8 @@
@MediumTest
public void testBroadcastUndeliveredDeleted() throws Exception {
replaceInstance(SmsBroadcastUndelivered.class, "instance", null, null);
- SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ SmsBroadcastUndelivered.initialize(
+ mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
mInboundSmsTracker = new InboundSmsTracker(
mContext,
mSmsPdu, /* pdu */
@@ -1170,7 +1203,9 @@
mContentProvider.insert(sRawUri, rawSms);
//when user unlocks the device, broadcast should not be sent for new message
- mContext.sendBroadcast(new Intent(Intent.ACTION_USER_UNLOCKED));
+ mContext.sendBroadcast(
+ new Intent(Intent.ACTION_USER_UNLOCKED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, MOCKED_MAIN_USER.getIdentifier()));
// wait for ScanRawTableThread
waitForMs(100);
processAllMessages();
@@ -1197,7 +1232,8 @@
when(mTelephonyComponentFactory).makeInboundSmsTracker(any(Context.class),
any(Cursor.class), anyBoolean());
- SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ SmsBroadcastUndelivered.initialize(
+ mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
// wait for ScanRawTableThread
waitForMs(100);
processAllMessages();
@@ -1215,7 +1251,8 @@
mContentProvider.insert(sRawUri, mInboundSmsTracker.getContentValues());
mContentProvider.insert(sRawUri, mInboundSmsTrackerSub1.getContentValues());
- SmsBroadcastUndelivered.initialize(mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler);
+ SmsBroadcastUndelivered.initialize(
+ mContext, mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
// wait for ScanRawTableThread
waitForMs(100);
processAllMessages();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index 8ee3a37..b62d9e1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -1182,12 +1182,12 @@
mSatelliteSession1 = new SatelliteSession();
mSatelliteSession1.satelliteServiceInitializationResult =
- SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteSession1.satelliteTechnology =
SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_PROPRIETARY;
mSatelliteSession1.count = 1;
mSatelliteSession1.satelliteServiceTerminationResult =
- SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteSession1.initializationProcessingTimeMillis = 100;
mSatelliteSession1.terminationProcessingTimeMillis = 200;
mSatelliteSession1.sessionDurationSeconds = 3;
@@ -1200,12 +1200,12 @@
mSatelliteSession2 = new SatelliteSession();
mSatelliteSession2.satelliteServiceInitializationResult =
- SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+ SatelliteProtoEnums.SATELLITE_RESULT_MODEM_ERROR;
mSatelliteSession2.satelliteTechnology =
SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_NB_IOT_NTN;
mSatelliteSession2.count = 1;
mSatelliteSession2.satelliteServiceTerminationResult =
- SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteSession2.initializationProcessingTimeMillis = 300;
mSatelliteSession2.terminationProcessingTimeMillis = 100;
mSatelliteSession2.sessionDurationSeconds = 10;
@@ -1222,13 +1222,13 @@
};
mSatelliteIncomingDatagram1 = new SatelliteIncomingDatagram();
- mSatelliteIncomingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ mSatelliteIncomingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteIncomingDatagram1.datagramSizeBytes = 1 * 1024;
mSatelliteIncomingDatagram1.datagramTransferTimeMillis = 3 * 1000;
mSatelliteIncomingDatagram1.isDemoMode = false;
mSatelliteIncomingDatagram2 = new SatelliteIncomingDatagram();
- mSatelliteIncomingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+ mSatelliteIncomingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_MODEM_ERROR;
mSatelliteIncomingDatagram2.datagramSizeBytes = 512;
mSatelliteIncomingDatagram2.datagramTransferTimeMillis = 1 * 1000;
mSatelliteIncomingDatagram1.isDemoMode = true;
@@ -1241,7 +1241,7 @@
mSatelliteOutgoingDatagram1 = new SatelliteOutgoingDatagram();
mSatelliteOutgoingDatagram1.datagramType =
SatelliteProtoEnums.DATAGRAM_TYPE_LOCATION_SHARING;
- mSatelliteOutgoingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ mSatelliteOutgoingDatagram1.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteOutgoingDatagram1.datagramSizeBytes = 1 * 1024;
mSatelliteOutgoingDatagram1.datagramTransferTimeMillis = 3 * 1000;
mSatelliteOutgoingDatagram1.isDemoMode = false;
@@ -1249,7 +1249,7 @@
mSatelliteOutgoingDatagram2 = new SatelliteOutgoingDatagram();
mSatelliteOutgoingDatagram2.datagramType =
SatelliteProtoEnums.DATAGRAM_TYPE_SOS_MESSAGE;
- mSatelliteOutgoingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_MODEM_ERROR;
+ mSatelliteOutgoingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_MODEM_ERROR;
mSatelliteOutgoingDatagram2.datagramSizeBytes = 512;
mSatelliteOutgoingDatagram2.datagramTransferTimeMillis = 1 * 1000;
mSatelliteOutgoingDatagram1.isDemoMode = true;
@@ -1260,14 +1260,14 @@
};
mSatelliteProvision1 = new SatelliteProvision();
- mSatelliteProvision1.resultCode = SatelliteProtoEnums.SATELLITE_ERROR_NONE;
+ mSatelliteProvision1.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS;
mSatelliteProvision1.provisioningTimeSec = 3 * 60;
mSatelliteProvision1.isProvisionRequest = true;
mSatelliteProvision1.isCanceled = false;
mSatelliteProvision2 = new SatelliteProvision();
mSatelliteProvision2.resultCode =
- SatelliteProtoEnums.SATELLITE_SERVICE_NOT_PROVISIONED;
+ SatelliteProtoEnums.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED;
mSatelliteProvision2.provisioningTimeSec = 0;
mSatelliteProvision2.isProvisionRequest = false;
mSatelliteProvision2.isCanceled = true;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
index cda96ef..97f7935 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
@@ -169,9 +169,9 @@
SatelliteStats.SatelliteSessionParams param =
new SatelliteStats.SatelliteSessionParams.Builder()
.setSatelliteServiceInitializationResult(
- SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+ SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS)
.setSatelliteTechnology(SatelliteProtoEnums.NT_RADIO_TECHNOLOGY_PROPRIETARY)
- .setTerminationResult(SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+ .setTerminationResult(SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS)
.setInitializationProcessingTime(100)
.setTerminationProcessingTime(200)
.setSessionDuration(3)
@@ -212,7 +212,7 @@
public void onSatelliteIncomingDatagramMetrics_withAtoms() throws Exception {
SatelliteStats.SatelliteIncomingDatagramParams param =
new SatelliteStats.SatelliteIncomingDatagramParams.Builder()
- .setResultCode(SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+ .setResultCode(SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS)
.setDatagramSizeBytes(1 * 1024)
.setDatagramTransferTimeMillis(3 * 1000)
.setIsDemoMode(true)
@@ -236,7 +236,7 @@
SatelliteStats.SatelliteOutgoingDatagramParams param =
new SatelliteStats.SatelliteOutgoingDatagramParams.Builder()
.setDatagramType(SatelliteProtoEnums.DATAGRAM_TYPE_LOCATION_SHARING)
- .setResultCode(SatelliteProtoEnums.SATELLITE_ERROR_NONE)
+ .setResultCode(SatelliteProtoEnums.SATELLITE_RESULT_SUCCESS)
.setDatagramSizeBytes(1 * 1024)
.setDatagramTransferTimeMillis(3 * 1000)
.setIsDemoMode(true)
@@ -261,7 +261,7 @@
SatelliteStats.SatelliteProvisionParams param =
new SatelliteStats.SatelliteProvisionParams.Builder()
.setResultCode(
- SatelliteProtoEnums.SATELLITE_SERVICE_PROVISION_IN_PROGRESS)
+ SatelliteProtoEnums.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS)
.setProvisioningTimeSec(5 * 1000)
.setIsProvisionRequest(true)
.setIsCanceled(false)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
index 04d140c..4347869 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -30,6 +30,10 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -268,6 +272,8 @@
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -319,6 +325,8 @@
expectedCall.setupDurationMillis = 200;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 2200L, 1L);
@@ -363,6 +371,8 @@
expectedCall.setupDurationMillis = 200;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 2200L, 1L);
@@ -411,6 +421,8 @@
expectedCall.disconnectExtraMessage = "normal call clearing";
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 100000L, 1L);
@@ -569,6 +581,8 @@
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -628,6 +642,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.isMultiSim = false; // DSDS with one active SIM profile should not count
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
mVoiceCallSessionStats0.setTimeMillis(2000L);
doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -860,6 +876,8 @@
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
mVoiceCallSessionStats0.setTimeMillis(2000L);
doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -918,6 +936,8 @@
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 4000L, 1L);
@@ -996,6 +1016,8 @@
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 4000L, 1L);
@@ -1130,7 +1152,8 @@
expectedCall.rttEnabled = true;
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
-
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
mVoiceCallSessionStats0.setTimeMillis(2000L);
doReturn(Call.State.INCOMING).when(mImsCall0).getState();
doReturn(Call.State.INCOMING).when(mImsConnection0).getState();
@@ -1187,6 +1210,8 @@
expectedCall0.ratAtEnd = TelephonyManager.NETWORK_TYPE_HSPA;
expectedCall0.bandAtEnd = 0;
expectedCall0.lastKnownRat = TelephonyManager.NETWORK_TYPE_HSPA;
+ expectedCall0.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
// call 1 starts later, MT
doReturn(true).when(mImsConnection1).isIncoming();
doReturn(60000L).when(mImsConnection1).getCreateTime();
@@ -1210,6 +1235,8 @@
expectedCall1.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall1.bandAtEnd = 0;
expectedCall1.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall1.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 80000L, 2L);
@@ -1319,6 +1346,8 @@
expectedCall0.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall0.bandAtEnd = 0;
expectedCall0.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall0.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
// call 1 starts later, MT
doReturn(true).when(mImsConnection1).isIncoming();
doReturn(60000L).when(mImsConnection1).getCreateTime();
@@ -1342,6 +1371,8 @@
expectedCall1.ratAtEnd = TelephonyManager.NETWORK_TYPE_HSPA;
expectedCall1.bandAtEnd = 0;
expectedCall1.lastKnownRat = TelephonyManager.NETWORK_TYPE_HSPA;
+ expectedCall1.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 80000L, 2L);
@@ -1449,6 +1480,8 @@
expectedCall0.ratSwitchCount = 0L;
expectedCall0.ratSwitchCountAfterConnected = 0L;
expectedCall0.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
+ expectedCall0.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
// call 1 starts later, MT
doReturn(true).when(mImsConnection1).isIncoming();
doReturn(60000L).when(mImsConnection1).getCreateTime();
@@ -1472,6 +1505,8 @@
expectedCall1.ratAtEnd = TelephonyManager.NETWORK_TYPE_HSPA;
expectedCall1.bandAtEnd = 0;
expectedCall1.lastKnownRat = TelephonyManager.NETWORK_TYPE_HSPA;
+ expectedCall1.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 80000L, 2L);
@@ -1571,6 +1606,8 @@
expectedCall.disconnectExtraMessage = "normal call clearing";
expectedCall.callDuration =
VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 100000L, 1L);
@@ -1631,6 +1668,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -1695,6 +1734,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_DISCONNECTED;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -1753,6 +1794,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -1818,6 +1861,8 @@
(1L << AudioCodec.AUDIO_CODEC_AMR) | (1L << AudioCodec.AUDIO_CODEC_AMR_WB);
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_UMTS, 2500L, 15000L, 1L);
@@ -1871,6 +1916,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.bandAtEnd = 0;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_UMTS, 2500L, 100000L, 1L);
@@ -1934,6 +1981,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 10000L, 1L);
@@ -2009,6 +2058,8 @@
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2087,6 +2138,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 7000L, 1L);
@@ -2185,6 +2238,8 @@
expectedCall0.srvccCompleted = true;
expectedCall0.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
expectedCall0.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall0.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
// call 1 starts later, MT
doReturn(true).when(mImsConnection1).isIncoming();
doReturn(60000L).when(mImsConnection1).getCreateTime();
@@ -2213,6 +2268,8 @@
expectedCall1.srvccCompleted = true;
expectedCall1.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
expectedCall1.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
+ expectedCall1.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 80000L, 2L);
@@ -2312,6 +2369,8 @@
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.lastKnownRat = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall.handoverInProgress = false;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsageLte =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -2386,6 +2445,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.handoverInProgress = true;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2440,6 +2501,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.handoverInProgress = true;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2498,6 +2561,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.handoverInProgress = false;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2562,6 +2627,8 @@
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.isEmergency = true;
expectedCall.handoverInProgress = true;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ACTIVE;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2627,6 +2694,8 @@
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
expectedCall.bandAtEnd = 0;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 8000L, 1L);
@@ -2677,6 +2746,8 @@
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
expectedCall.mainCodecQuality =
VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_UNKNOWN;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_IWLAN, 2000L, 8000L, 1L);
@@ -2730,6 +2801,8 @@
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
expectedCall.vonrEnabled = true;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -2826,6 +2899,8 @@
expectedCall.supportsBusinessCallComposer = true;
// 0 is defined as UNKNOWN, adding 1 to original value.
expectedCall.callComposerStatus = 3;
+ expectedCall.preciseCallStateOnSetup =
+ VOICE_CALL_SESSION__CALL_STATE_ON_SETUP__CALL_STATE_ALERTING;
VoiceCallRatUsage expectedRatUsage =
makeRatUsageProto(
CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
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 576864e..a3a189b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -46,13 +46,13 @@
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_ERROR;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT;
-import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_AUTHORIZED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NO_RESOURCES;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE;
@@ -92,6 +92,7 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
@@ -124,6 +125,7 @@
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteManager.SatelliteException;
+import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
@@ -182,6 +184,8 @@
private static final int[] ACTIVE_SUB_IDS = {SUB_ID};
private static final int TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS =
(int) TimeUnit.SECONDS.toMillis(60);
+ private static final int TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS =
+ (int) TimeUnit.SECONDS.toMillis(60);
private static final String SATELLITE_PLMN = "00103";
private List<Pair<Executor, CarrierConfigManager.CarrierConfigChangeListener>>
@@ -516,6 +520,9 @@
mContextFixture.putIntResource(
R.integer.config_wait_for_satellite_enabling_response_timeout_millis,
TEST_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMEOUT_MILLIS);
+ mContextFixture.putIntResource(
+ R.integer.config_satellite_wait_for_cellular_modem_off_timeout_millis,
+ TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS);
doReturn(ACTIVE_SUB_IDS).when(mMockSubscriptionManagerService).getActiveSubIdList(true);
mCarrierConfigBundle = mContextFixture.getCarrierConfigBundle();
@@ -580,10 +587,6 @@
Context.NOTIFICATION_SERVICE);
mSatelliteControllerUT =
new TestSatelliteController(mContext, Looper.myLooper(), mFeatureFlags);
- verify(mMockSatelliteModemInterface).registerForSatelliteProvisionStateChanged(
- any(Handler.class),
- eq(26) /* EVENT_SATELLITE_PROVISION_STATE_CHANGED */,
- eq(null));
verify(mMockSatelliteModemInterface).registerForPendingDatagrams(
any(Handler.class),
eq(27) /* EVENT_PENDING_DATAGRAMS */,
@@ -632,7 +635,7 @@
mSatelliteVisibilityTimeReceiver);
processAllMessages();
assertTrue(waitForRequestTimeForNextSatelliteVisibilityResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
+ assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
mQueriedSatelliteVisibilityTimeResultCode);
resetSatelliteControllerUT();
@@ -730,6 +733,87 @@
processAllMessages();
verify(mMockSatelliteModemInterface, times(5))
.requestIsSatelliteSupported(any(Message.class));
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // Radio is off during TN -> NTN image switch, SatelliteController should not set radio
+ // state to OFF
+ setRadioPower(false);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // Turn on radio
+ setRadioPower(true);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // APM is triggered
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertTrue(mSatelliteControllerUT.isRadioOffRequested());
+ assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // SatelliteController should set the radio state to OFF
+ setRadioPower(false);
+ processAllMessages();
+ assertFalse(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // Turn on radio
+ setRadioPower(true);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // APM is triggered
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertTrue(mSatelliteControllerUT.isRadioOffRequested());
+ assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // Modem fails to power off radio. APM is disabled
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(true);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // APM is triggered
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertTrue(mSatelliteControllerUT.isRadioOffRequested());
+ assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // The timer WaitForCellularModemOff time out
+ moveTimeForward(TEST_WAIT_FOR_CELLULAR_MODEM_OFF_TIMEOUT_MILLIS);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // APM is triggered
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertTrue(mSatelliteControllerUT.isRadioOffRequested());
+ assertTrue(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
+
+ // Modem failed to power off the radio
+ mSatelliteControllerUT.onPowerOffCellularRadioFailed();
+ processAllMessages();
+ assertTrue(mSatelliteControllerUT.isRadioOn());
+ assertFalse(mSatelliteControllerUT.isRadioOffRequested());
+ assertFalse(mSatelliteControllerUT.isWaitForCellularModemOffTimerStarted());
}
@Test
@@ -803,10 +887,25 @@
assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
(long) mIIntegerConsumerResults.get(0));
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ // Fail to enable satellite when the emergency call is in progress
+ mIIntegerConsumerResults.clear();
+ mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
+ mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
+ setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
+ doReturn(true).when(mTelecomManager).isInEmergencyCall();
+ mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false,
+ mIIntegerConsumer);
+ mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
+ processAllMessages();
+ assertTrue(waitForIIntegerConsumerResult(1));
+ assertEquals(SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS,
+ (long) mIIntegerConsumerResults.get(0));
+ doReturn(false).when(mTelecomManager).isInEmergencyCall();
+
// Successfully enable satellite
mIIntegerConsumerResults.clear();
mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
@@ -835,7 +934,7 @@
mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
setRadioPower(false);
- mSatelliteControllerUT.onCellularRadioPowerOffRequested();
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
processAllMessages();
sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_OFF, null);
processAllMessages();
@@ -963,7 +1062,13 @@
assertEquals(SATELLITE_RESULT_REQUEST_IN_PROGRESS, (long) mIIntegerConsumerResults.get(0));
mIIntegerConsumerResults.clear();
- resetSatelliteControllerUTToSupportedAndProvisionedState();
+ resetSatelliteControllerUT();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setProvisionedState(false);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setProvisionedState(true);
+ processAllMessages();
+ verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
// Should receive callback for the above request when satellite modem is turned off.
assertTrue(waitForIIntegerConsumerResult(1));
assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
@@ -989,13 +1094,13 @@
assertTrue(waitForIIntegerConsumerResult(1));
assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
- verify(mMockSessionMetricsStats, times(15)).setInitializationResult(anyInt());
- verify(mMockSessionMetricsStats, times(15)).setSatelliteTechnology(anyInt());
+ verify(mMockSessionMetricsStats, times(17)).setInitializationResult(anyInt());
+ verify(mMockSessionMetricsStats, times(17)).setSatelliteTechnology(anyInt());
verify(mMockSessionMetricsStats, times(3)).setInitializationProcessingTime(anyLong());
verify(mMockSessionMetricsStats, times(2)).setTerminationResult(anyInt());
verify(mMockSessionMetricsStats, times(2)).setTerminationProcessingTime(anyLong());
verify(mMockSessionMetricsStats, times(2)).setSessionDurationSec(anyInt());
- verify(mMockSessionMetricsStats, times(15)).reportSessionMetrics();
+ verify(mMockSessionMetricsStats, times(17)).reportSessionMetrics();
/**
* Make areAllRadiosDisabled return false and move mWaitingForRadioDisabled to true, which
@@ -1043,12 +1148,49 @@
resetSatelliteControllerUTToOnAndProvisionedState();
when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(false);
- mSatelliteControllerUT.onCellularRadioPowerOffRequested();
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
processAllMessages();
// Satellite should not be powered off since the feature flag oemEnabledSatelliteFlag is
// disabled
when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
+
+ // Successfully disable satellite.
+ when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ mIIntegerConsumerResults.clear();
+ setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, false, false, false,
+ mIIntegerConsumer);
+ processAllMessages();
+ assertTrue(waitForIIntegerConsumerResult(1));
+ assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+ verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
+
+ // Fail to enable satellite when radio is being powered off.
+ mIIntegerConsumerResults.clear();
+ setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
+ mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false,
+ mIIntegerConsumer);
+ processAllMessages();
+ assertTrue(waitForIIntegerConsumerResult(1));
+ // Radio is being powered off, can not enable satellite
+ assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+
+ // Modem failed to power off
+ mSatelliteControllerUT.onPowerOffCellularRadioFailed();
+
+ // Successfully enable satellite when radio is on.
+ mIIntegerConsumerResults.clear();
+ mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
+ mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
+ setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
+ mSatelliteControllerUT.requestSatelliteEnabled(SUB_ID, true, false, false,
+ mIIntegerConsumer);
+ processAllMessages();
+ assertTrue(waitForIIntegerConsumerResult(1));
+ assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+ verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
}
@Test
@@ -1062,7 +1204,7 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
// Set provisioned state
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
@@ -1165,7 +1307,7 @@
mStartTransmissionUpdateCallback);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
+ assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
(long) mIIntegerConsumerResults.get(0));
resetSatelliteControllerUT();
@@ -1239,7 +1381,7 @@
mStopTransmissionUpdateCallback);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
+ assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
(long) mIIntegerConsumerResults.get(0));
resetSatelliteControllerUT();
@@ -1303,7 +1445,7 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.requestIsDemoModeEnabled(SUB_ID, mIsDemoModeEnabledReceiver);
assertTrue(waitForRequestIsDemoModeEnabledResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE, mQueriedIsDemoModeEnabledResultCode);
+ assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED, mQueriedIsDemoModeEnabledResultCode);
assertFalse(mQueriedIsDemoModeEnabled);
resetSatelliteControllerUT();
@@ -1349,7 +1491,6 @@
public void testOnSatelliteServiceConnected() {
verifySatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
verifySatelliteEnabled(false, SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
- verifySatelliteProvisioned(false, SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
@@ -1361,7 +1502,7 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
- verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
}
@Test
@@ -1430,6 +1571,12 @@
+ "semaphore, ex=" + ex);
}
}
+
+ @Override
+ public void onSatelliteSubscriptionProvisionStateChanged(
+ List<SatelliteSubscriberProvisionStatus> status) {
+ logd("onSatelliteSubscriptionProvisionStateChanged: " + status);
+ }
};
int errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(
SUB_ID, callback);
@@ -1446,15 +1593,27 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
errorCode = mSatelliteControllerUT.registerForSatelliteProvisionStateChanged(
SUB_ID, callback);
+ processAllMessages();
+ assertTrue(waitForForEvents(
+ semaphore, 1, "testRegisterForSatelliteProvisionStateChanged"));
assertEquals(SATELLITE_RESULT_SUCCESS, errorCode);
- sendProvisionedStateChangedEvent(true, null);
+ String mText = "This is test provision data.";
+ byte[] testProvisionData = mText.getBytes();
+ CancellationSignal cancellationSignal = new CancellationSignal();
+ ICancellationSignal cancelRemote = null;
+ mIIntegerConsumerResults.clear();
+ cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+ TEST_SATELLITE_TOKEN,
+ testProvisionData, mIIntegerConsumer);
processAllMessages();
assertTrue(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteProvisionStateChanged"));
mSatelliteControllerUT.unregisterForSatelliteProvisionStateChanged(SUB_ID, callback);
- sendProvisionedStateChangedEvent(true, null);
+ cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
+ TEST_SATELLITE_TOKEN,
+ testProvisionData, mIIntegerConsumer);
processAllMessages();
assertFalse(waitForForEvents(
semaphore, 1, "testRegisterForSatelliteProvisionStateChanged"));
@@ -1523,7 +1682,7 @@
mIIntegerConsumerResults.clear();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(false, null);
+ setProvisionedState(false);
processAllMessages();
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.sendDatagram(SUB_ID, datagramType, datagram, true,
@@ -1536,7 +1695,7 @@
eq(datagramType), eq(datagram), eq(true), any());
mIIntegerConsumerResults.clear();
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.sendDatagram(SUB_ID, datagramType, datagram, true,
@@ -1563,7 +1722,7 @@
mIIntegerConsumerResults.clear();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(false, null);
+ setProvisionedState(false);
processAllMessages();
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.pollPendingDatagrams(SUB_ID, mIIntegerConsumer);
@@ -1574,7 +1733,7 @@
verify(mMockDatagramController, never()).pollPendingSatelliteDatagrams(anyInt(), any());
mIIntegerConsumerResults.clear();
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.pollPendingDatagrams(SUB_ID, mIIntegerConsumer);
@@ -1617,8 +1776,6 @@
setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_SUCCESS);
cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN,
testProvisionData, mIIntegerConsumer);
@@ -1637,61 +1794,12 @@
assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
assertNull(cancelRemote);
- // Vendor service does not support the request requestIsSatelliteProvisioned. Telephony will
- // make decision itself
- resetSatelliteControllerUT();
- mIIntegerConsumerResults.clear();
- setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- setUpResponseForRequestIsSatelliteProvisioned(
- false, SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
- verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
-
- // Vendor service does not support the requests requestIsSatelliteProvisioned and
- // provisionSatelliteService. Telephony will make decision itself
- deprovisionSatelliteService();
- resetSatelliteControllerUT();
- mIIntegerConsumerResults.clear();
- setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- setUpResponseForRequestIsSatelliteProvisioned(
- false, SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
- verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
- cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
- TEST_SATELLITE_TOKEN,
- testProvisionData, mIIntegerConsumer);
- processAllMessages();
- assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
- assertNotNull(cancelRemote);
- verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
-
- resetSatelliteControllerUT();
- mIIntegerConsumerResults.clear();
- setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_NOT_AUTHORIZED);
- cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
- TEST_SATELLITE_TOKEN,
- testProvisionData, mIIntegerConsumer);
- processAllMessages();
- assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_NOT_AUTHORIZED, (long) mIIntegerConsumerResults.get(0));
- assertNotNull(cancelRemote);
-
resetSatelliteControllerUT();
mIIntegerConsumerResults.clear();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForProvisionSatelliteService(TEST_NEXT_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_SUCCESS);
cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
TEST_NEXT_SATELLITE_TOKEN, testProvisionData, mIIntegerConsumer);
cancellationSignal.setRemote(cancelRemote);
@@ -1699,8 +1807,6 @@
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
- verify(mMockSatelliteModemInterface).deprovisionSatelliteService(
- eq(TEST_NEXT_SATELLITE_TOKEN), any(Message.class));
resetSatelliteControllerUT();
mIIntegerConsumerResults.clear();
@@ -1708,9 +1814,6 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpNoResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN);
- setUpResponseForProvisionSatelliteService(TEST_NEXT_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_SUCCESS);
cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN,
testProvisionData, mIIntegerConsumer);
@@ -1748,13 +1851,11 @@
mIIntegerConsumerResults.clear();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN, mIIntegerConsumer);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
- (long) mIIntegerConsumerResults.get(0));
+ assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
resetSatelliteControllerUT();
mIIntegerConsumerResults.clear();
@@ -1762,7 +1863,6 @@
setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN, mIIntegerConsumer);
processAllMessages();
@@ -1772,20 +1872,6 @@
resetSatelliteControllerUT();
provisionSatelliteService();
mIIntegerConsumerResults.clear();
- setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_RESULT_SUCCESS);
- mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
- TEST_SATELLITE_TOKEN, mIIntegerConsumer);
- processAllMessages();
- assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
- verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
-
- // Vendor service does not support deprovisionSatelliteService
- resetSatelliteControllerUT();
- provisionSatelliteService();
- mIIntegerConsumerResults.clear();
- setUpResponseForDeprovisionSatelliteService(
- TEST_SATELLITE_TOKEN, SATELLITE_RESULT_REQUEST_NOT_SUPPORTED);
mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN, mIIntegerConsumer);
processAllMessages();
@@ -1794,16 +1880,16 @@
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
resetSatelliteControllerUT();
- provisionSatelliteService();
+ setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setProvisionedState(null);
mIIntegerConsumerResults.clear();
- setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN,
- SATELLITE_RESULT_INVALID_MODEM_STATE);
mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN, mIIntegerConsumer);
processAllMessages();
assertTrue(waitForIIntegerConsumerResult(1));
- assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
- verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
+ assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+ verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
}
@Test
@@ -3436,7 +3522,7 @@
mIIntegerConsumerResults.clear();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
@@ -3533,9 +3619,9 @@
doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
setUpResponseForRequestIsSatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
@@ -3677,7 +3763,7 @@
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
// Successfully enable satellite
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
mIIntegerConsumerResults.clear();
@@ -3996,12 +4082,13 @@
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
doNothing().when(mMockSatelliteModemInterface)
.setSatelliteServicePackageName(anyString());
- mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService");
+ mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService", null);
processAllMessages();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+ setProvisionedState(false);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
}
@@ -4016,7 +4103,7 @@
setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
doNothing().when(mMockSatelliteModemInterface)
.setSatelliteServicePackageName(anyString());
- mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService");
+ mSatelliteControllerUT.setSatelliteServicePackageName("TestSatelliteService", null);
processAllMessages();
}
@@ -4024,7 +4111,7 @@
resetSatelliteControllerUT();
setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
- sendProvisionedStateChangedEvent(true, null);
+ setProvisionedState(true);
processAllMessages();
verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
}
@@ -4105,15 +4192,7 @@
private void setUpResponseForRequestIsSatelliteProvisioned(
boolean isSatelliteProvisioned, @SatelliteManager.SatelliteResult int error) {
- SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
- ? null : new SatelliteException(error);
- int[] provisioned = new int[]{isSatelliteProvisioned ? 1 : 0};
- doAnswer(invocation -> {
- Message message = (Message) invocation.getArguments()[0];
- AsyncResult.forMessage(message, provisioned, exception);
- message.sendToTarget();
- return null;
- }).when(mMockSatelliteModemInterface).requestIsSatelliteProvisioned(any(Message.class));
+ mSatelliteControllerUT.setSatelliteProvisioned(isSatelliteProvisioned);
}
private void setUpResponseForRequestSatelliteEnabled(
@@ -4154,37 +4233,6 @@
any(Message.class));
}
- private void setUpResponseForProvisionSatelliteService(
- String token, byte[] provisionData, @SatelliteManager.SatelliteResult int error) {
- SatelliteException exception = (error == SATELLITE_RESULT_SUCCESS)
- ? null : new SatelliteException(error);
- doAnswer(invocation -> {
- Message message = (Message) invocation.getArguments()[2];
- AsyncResult.forMessage(message, null, exception);
- message.sendToTarget();
- return null;
- }).when(mMockSatelliteModemInterface)
- .provisionSatelliteService(eq(token), any(byte[].class), any(Message.class));
- }
-
- private void setUpNoResponseForProvisionSatelliteService(String token) {
- doNothing().when(mMockSatelliteModemInterface)
- .provisionSatelliteService(eq(token), any(), any(Message.class));
- }
-
- private void setUpResponseForDeprovisionSatelliteService(String token,
- @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)
- .deprovisionSatelliteService(eq(token), any(Message.class));
- }
-
private void setUpResponseForRequestSatelliteCapabilities(
SatelliteCapabilities satelliteCapabilities,
@SatelliteManager.SatelliteResult int error) {
@@ -4460,11 +4508,8 @@
assertEquals(signalStrengthLevel, mQueriedNtnSignalStrengthLevel);
}
- private void sendProvisionedStateChangedEvent(boolean provisioned, Throwable exception) {
- Message msg = mSatelliteControllerUT.obtainMessage(
- 26 /* EVENT_SATELLITE_PROVISION_STATE_CHANGED */);
- msg.obj = new AsyncResult(null, provisioned, exception);
- msg.sendToTarget();
+ private void setProvisionedState(@Nullable Boolean provisioned) {
+ mSatelliteControllerUT.setSatelliteProvisioned(provisioned);
}
private void sendSatelliteModemStateChangedEvent(int state, Throwable exception) {
@@ -4550,8 +4595,6 @@
setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
- setUpResponseForProvisionSatelliteService(TEST_SATELLITE_TOKEN, testProvisionData,
- SATELLITE_RESULT_SUCCESS);
cancelRemote = mSatelliteControllerUT.provisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN,
testProvisionData, mIIntegerConsumer);
@@ -4564,7 +4607,6 @@
private void deprovisionSatelliteService() {
mIIntegerConsumerResults.clear();
- setUpResponseForDeprovisionSatelliteService(TEST_SATELLITE_TOKEN, SATELLITE_RESULT_SUCCESS);
mSatelliteControllerUT.deprovisionSatelliteService(SUB_ID,
TEST_SATELLITE_TOKEN, mIIntegerConsumer);
processAllMessages();
@@ -4794,5 +4836,27 @@
}
return false;
}
+
+ void setSatelliteProvisioned(@Nullable Boolean isProvisioned) {
+ synchronized (mSatelliteViaOemProvisionLock) {
+ mIsSatelliteViaOemProvisioned = isProvisioned;
+ }
+ }
+
+ public boolean isRadioOn() {
+ synchronized (mIsRadioOnLock) {
+ return mIsRadioOn;
+ }
+ }
+
+ public boolean isRadioOffRequested() {
+ synchronized (mIsRadioOnLock) {
+ return mRadioOffRequested;
+ }
+ }
+
+ public boolean isWaitForCellularModemOffTimerStarted() {
+ return hasMessages(EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT);
+ }
}
}
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 f4fa48e..77a7c0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommenderTest.java
@@ -44,6 +44,7 @@
import android.os.Looper;
import android.os.OutcomeReceiver;
import android.os.RemoteException;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.telecom.Connection;
import android.telecom.TelecomManager;
import android.telephony.BinderCacheManager;
@@ -65,9 +66,11 @@
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.Flags;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -108,6 +111,8 @@
private ImsManager.MmTelFeatureConnectionFactory mMmTelFeatureConnectionFactory;
@Mock
private FeatureFlags mFeatureFlags;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private TestConnection mTestConnection;
private Uri mTestConnectionAddress = Uri.parse("tel:1234");
private TestSOSMessageRecommender mTestSOSMessageRecommender;
@@ -127,6 +132,7 @@
R.integer.config_emergency_call_wait_for_connection_timeout_millis))
.thenReturn(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
+ when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
mTestSatelliteController = new TestSatelliteController(mContext,
Looper.myLooper(), mFeatureFlags);
mTestImsManager = new TestImsManager(
@@ -552,6 +558,51 @@
assertEquals(carrierTimeoutMillis, mTestSOSMessageRecommender.getTimeOutMillis());
}
+ @Test
+ public void testGetEmergencyCallToSatelliteHandoverType_SatelliteViaCarrierAndOemAvailable() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
+ mTestSatelliteController.mIsSatelliteViaOemProvisioned = true;
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ assertEquals(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
+ mTestSOSMessageRecommender.getEmergencyCallToSatelliteHandoverType());
+
+ mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+ }
+
+ @Test
+ public void testGetEmergencyCallToSatelliteHandoverType_OnlySatelliteViaCarrierAvailable() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
+ mTestSatelliteController.mIsSatelliteViaOemProvisioned = false;
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ assertEquals(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
+ mTestSOSMessageRecommender.getEmergencyCallToSatelliteHandoverType());
+
+ mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+ }
+
+ @Test
+ public void testGetEmergencyCallToSatelliteHandoverType_OemAndCarrierNotAvailable() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ mTestSatelliteController.mIsSatelliteViaOemProvisioned = true;
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ assertEquals(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS,
+ mTestSOSMessageRecommender.getEmergencyCallToSatelliteHandoverType());
+
+ mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
+ mTestSatelliteController.mIsSatelliteViaOemProvisioned = false;
+ mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
+ assertEquals(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS,
+ mTestSOSMessageRecommender.getEmergencyCallToSatelliteHandoverType());
+
+ mSetFlagsRule.disableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+ }
+
private void testStopTrackingCallBeforeTimeout(
@Connection.ConnectionState int connectionState) {
mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
index 5a0d0d8..4b1b4a5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionDatabaseManagerTest.java
@@ -143,6 +143,9 @@
static final int FAKE_TRANSFER_STATUS_TRANSFERRED_OUT = 1;
static final int FAKE_TRANSFER_STATUS_CONVERTED = 2;
+ static final int FAKE_SATELLITE_PROVISIONED = 1;
+ static final int FAKE_SATELLITE_NOT_PROVISIONED = 0;
+
static final SubscriptionInfoInternal FAKE_SUBSCRIPTION_INFO1 =
new SubscriptionInfoInternal.Builder()
.setId(1)
@@ -217,6 +220,7 @@
.setSatelliteEntitlementStatus(FAKE_SATELLITE_ENTITLEMENT_STATUS_DISABLED)
.setSatelliteEntitlementPlmns(FAKE_SATELLITE_ENTITLEMENT_PLMNS2)
.setSatelliteESOSSupported(FAKE_SATELLITE_ESOS_SUPPORTED_DISABLED)
+ .setIsSatelliteProvisionedForNonIpDatagram(FAKE_SATELLITE_NOT_PROVISIONED)
.build();
static final SubscriptionInfoInternal FAKE_SUBSCRIPTION_INFO2 =
@@ -293,6 +297,7 @@
.setSatelliteEntitlementStatus(FAKE_SATELLITE_ENTITLEMENT_STATUS_ENABLED)
.setSatelliteEntitlementPlmns(FAKE_SATELLITE_ENTITLEMENT_PLMNS1)
.setSatelliteESOSSupported(FAKE_SATELLITE_ESOS_SUPPORTED_ENABLED)
+ .setIsSatelliteProvisionedForNonIpDatagram(FAKE_SATELLITE_PROVISIONED)
.build();
private SubscriptionDatabaseManager mDatabaseManagerUT;
@@ -2393,4 +2398,38 @@
FAKE_SUBSCRIPTION_INFO1.getSubscriptionId())
.getSatelliteESOSSupported()).isEqualTo(FAKE_SATELLITE_ESOS_SUPPORTED_DISABLED);
}
+
+ @Test
+ public void testUpdateSatelliteProvisionedStatus() throws Exception {
+ // exception is expected if there is nothing in the database.
+ assertThrows(IllegalArgumentException.class,
+ () -> mDatabaseManagerUT.setIsSatelliteProvisionedForNonIpDatagram(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(),
+ FAKE_SATELLITE_PROVISIONED));
+
+ SubscriptionInfoInternal subInfo = insertSubscriptionAndVerify(FAKE_SUBSCRIPTION_INFO1);
+ mDatabaseManagerUT.setIsSatelliteProvisionedForNonIpDatagram(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(),
+ FAKE_SATELLITE_PROVISIONED);
+ processAllMessages();
+
+ subInfo = new SubscriptionInfoInternal.Builder(subInfo)
+ .setIsSatelliteProvisionedForNonIpDatagram(FAKE_SATELLITE_PROVISIONED)
+ .build();
+ verifySubscription(subInfo);
+ verify(mSubscriptionDatabaseManagerCallback, times(2)).onSubscriptionChanged(eq(1));
+
+ assertThat(mDatabaseManagerUT.getSubscriptionProperty(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(),
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM))
+ .isEqualTo(FAKE_SATELLITE_PROVISIONED);
+
+ mDatabaseManagerUT.setSubscriptionProperty(FAKE_SUBSCRIPTION_INFO1.getSubscriptionId(),
+ SimInfo.COLUMN_IS_SATELLITE_PROVISIONED_FOR_NON_IP_DATAGRAM,
+ FAKE_SATELLITE_NOT_PROVISIONED);
+ assertThat(mDatabaseManagerUT.getSubscriptionInfoInternal(
+ FAKE_SUBSCRIPTION_INFO1.getSubscriptionId())
+ .getIsSatelliteProvisionedForNonIpDatagram())
+ .isEqualTo(FAKE_SATELLITE_NOT_PROVISIONED);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
index 30a4d8e..925cf71 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionInfoInternalTest.java
@@ -124,6 +124,8 @@
.FAKE_SATELLITE_ENTITLEMENT_PLMNS1)
.setSatelliteESOSSupported(
SubscriptionDatabaseManagerTest.FAKE_SATELLITE_ESOS_SUPPORTED_ENABLED)
+ .setIsSatelliteProvisionedForNonIpDatagram(
+ SubscriptionDatabaseManagerTest.FAKE_SATELLITE_PROVISIONED)
.build();
private final SubscriptionInfoInternal mSubInfoNull =
@@ -256,6 +258,8 @@
.FAKE_SATELLITE_ENTITLEMENT_PLMNS1);
assertThat(mSubInfo.getSatelliteESOSSupported())
.isEqualTo(SubscriptionDatabaseManagerTest.FAKE_SATELLITE_ESOS_SUPPORTED_ENABLED);
+ assertThat(mSubInfo.getIsSatelliteProvisionedForNonIpDatagram())
+ .isEqualTo(SubscriptionDatabaseManagerTest.FAKE_SATELLITE_PROVISIONED);
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
index acbf29b..65790f8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -109,8 +109,6 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.euicc.EuiccController;
-import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.subscription.SubscriptionDatabaseManager.SubscriptionDatabaseManagerCallback;
import com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.SubscriptionProvider;
import com.android.internal.telephony.subscription.SubscriptionManagerService.BinderWrapper;
import com.android.internal.telephony.subscription.SubscriptionManagerService.SubscriptionManagerServiceCallback;
@@ -164,7 +162,6 @@
// mocked
private SubscriptionManagerServiceCallback mMockedSubscriptionManagerServiceCallback;
private EuiccController mEuiccController;
- private FeatureFlags mFlags;
private BinderWrapper mBinder;
private Set<Integer> mActiveSubs = new ArraySet<>();
@@ -215,9 +212,13 @@
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mSubscriptionProvider);
- mFlags = Mockito.mock(FeatureFlags.class);
+ doReturn(true).when(mFeatureFlags).saferGetPhoneNumber();
+ doReturn(true).when(mFeatureFlags).uiccPhoneNumberFix();
+ doReturn(true).when(mFeatureFlags).ddsCallback();
+ doReturn(true).when(mFeatureFlags).oemEnabledSatelliteFlag();
+
mSubscriptionManagerServiceUT = new SubscriptionManagerService(mContext, Looper.myLooper(),
- mFlags);
+ mFeatureFlags);
monitorTestableLooper(new TestableLooper(getBackgroundHandler().getLooper()));
monitorTestableLooper(new TestableLooper(getSubscriptionDatabaseManager().getLooper()));
@@ -240,8 +241,6 @@
doReturn(true).when(mUserManager)
.isManagedProfile(eq(FAKE_MANAGED_PROFILE_USER_HANDLE.getIdentifier()));
- // Due to affect exist implementation, bypass feature flag.
- doReturn(false).when(mFlags).enforceTelephonyFeatureMappingForPublicApis();
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
logd("SubscriptionManagerServiceTest -Setup!");
@@ -275,12 +274,6 @@
return (SubscriptionDatabaseManager) field.get(mSubscriptionManagerServiceUT);
}
- private SubscriptionDatabaseManagerCallback getSubscriptionDatabaseCallback() throws Exception {
- Field field = SubscriptionDatabaseManager.class.getDeclaredField("mCallback");
- field.setAccessible(true);
- return (SubscriptionDatabaseManagerCallback) field.get(getSubscriptionDatabaseManager());
- }
-
/**
* Insert the subscription info to the database. This is an instant insertion method. For real
* insertion sequence please use {@link #testInsertNewSim()}.
@@ -457,7 +450,7 @@
@Test
@DisableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
public void testSetPhoneNumber() {
- doReturn(false).when(mFlags).enforceTelephonyFeatureMapping();
+ doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMapping();
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
@@ -517,7 +510,7 @@
mSubscriptionManagerServiceUT, vendorApiLevel);
// Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined
- doReturn(true).when(mFlags).enforceTelephonyFeatureMappingForPublicApis();
+ doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
doReturn(true).when(mPackageManager).hasSystemFeature(
eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
try {
@@ -786,6 +779,8 @@
assertThat(b.containsKey(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX)).isTrue();
assertThat(b.getInt(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX)).isEqualTo(1);
+
+ verify(mMockedSubscriptionManagerServiceCallback).onDefaultDataSubscriptionChanged(eq(1));
}
@Test
@@ -1281,8 +1276,8 @@
@EnableCompatChanges({SubscriptionManagerService.REQUIRE_DEVICE_IDENTIFIERS_FOR_GROUP_UUID,
SubscriptionManagerService.FILTER_ACCESSIBLE_SUBS_BY_USER})
public void testIsSubscriptionAssociatedWithUserMultiSubs() {
- doReturn(true).when(mFlags).workProfileApiSplit();
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
insertSubscription(FAKE_SUBSCRIPTION_INFO1);
@@ -1344,8 +1339,8 @@
public void testSubscriptionAssociationWorkProfileCallerVisibility() {
// Split mode is defined as when a profile owns a dedicated sub, it loses the visibility to
// the unassociated sub.
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
- doReturn(true).when(mFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
// Sub 1 is associated with work profile; Sub 2 is unassociated.
@@ -1480,8 +1475,8 @@
public void testSubscriptionAssociationPersonalCallerVisibility() {
// Split mode is defined as when a profile owns a dedicated sub, it loses the visibility to
// the unassociated sub.
- doReturn(true).when(mFlags).enforceSubscriptionUserFilter();
- doReturn(true).when(mFlags).workProfileApiSplit();
+ doReturn(true).when(mFeatureFlags).enforceSubscriptionUserFilter();
+ doReturn(true).when(mFeatureFlags).workProfileApiSplit();
mContextFixture.addCallingOrSelfPermission(
Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION);
// Sub 1 is unassociated; Sub 2 is associated with work profile.
@@ -1832,7 +1827,7 @@
multiNumberSubInfo =
new SubscriptionInfoInternal.Builder(multiNumberSubInfo)
.setNumberFromCarrier("")
- .setNumber(phoneNumberFromUicc)
+ .setNumber("")
.setNumberFromIms(phoneNumberFromIms)
.build();
subId = insertSubscription(multiNumberSubInfo);
@@ -2524,6 +2519,23 @@
}
@Test
+ public void testGetPhoneNumberFromUicc() {
+ mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+ testSetPhoneNumber();
+ // Number from line1Number should be FAKE_PHONE_NUMBER1 instead of FAKE_PHONE_NUMBER2
+ assertThat(mSubscriptionManagerServiceUT.getPhoneNumber(1,
+ SubscriptionManager.PHONE_NUMBER_SOURCE_UICC, CALLING_PACKAGE, CALLING_FEATURE))
+ .isEqualTo(FAKE_PHONE_NUMBER1);
+
+ doReturn("").when(mPhone).getLine1Number();
+
+ // If getLine1Number is empty, then the number should be from the sub info.
+ assertThat(mSubscriptionManagerServiceUT.getPhoneNumber(1,
+ SubscriptionManager.PHONE_NUMBER_SOURCE_UICC, CALLING_PACKAGE, CALLING_FEATURE))
+ .isEqualTo(FAKE_PHONE_NUMBER2);
+ }
+
+ @Test
public void testGetPhoneNumberFromInactiveSubscription() {
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
testInactiveSimRemoval();
@@ -2543,8 +2555,6 @@
@Test
public void testGetPhoneNumberFromDefaultSubscription() {
- doReturn(true).when(mFlags).saferGetPhoneNumber();
-
mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
int subId = insertSubscription(FAKE_SUBSCRIPTION_INFO1);
@@ -3192,7 +3202,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3222,14 +3231,12 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
public void testIsSatelliteSpnWithEmptySpn() {
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier, ""); // Empty
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3285,7 +3292,6 @@
.isEqualTo(FAKE_SATELLITE_IS_ONLY_NTN_DISABLED);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
@@ -3293,7 +3299,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3322,7 +3327,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
@@ -3330,7 +3334,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "true");
- doReturn(true).when(mFlags).oemEnabledSatelliteFlag();
EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
.setIccid(FAKE_ICCID1)
@@ -3360,7 +3363,6 @@
mContextFixture.putResource(R.string.config_satellite_sim_spn_identifier,
FAKE_CARRIER_NAME1);
System.setProperty("persist.radio.allow_mock_modem", "false");
- doReturn(false).when(mFlags).oemEnabledSatelliteFlag();
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
index cf3f900..cffab68 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -33,11 +34,12 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.InstrumentationRegistry;
+
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.uicc.IccIoResult;
import com.android.internal.telephony.uicc.IccUtils;
-import androidx.test.InstrumentationRegistry;
import org.junit.After;
import org.junit.Before;
@@ -83,7 +85,6 @@
private Handler mHandler;
private ResponseCaptor mResponseCaptor;
private byte[] mSelectResponse;
- private static final String AID = "B2C3D4";
private ApduSender mSender;
@Before
@@ -95,7 +96,7 @@
mSelectResponse = null;
mSender = new ApduSender(InstrumentationRegistry.getContext(), 0 /* phoneId= */,
- mMockCi, AID, false /* supportExtendedApdu */);
+ mMockCi, ApduSender.ISD_R_AID, false /* supportExtendedApdu */);
mLooper = TestableLooper.get(this);
}
@@ -110,6 +111,16 @@
}
@Test
+ public void testWrongAid_throwsIllegalArgumentException() {
+ String wrongAid = "-1";
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ new ApduSender(InstrumentationRegistry.getContext(), 0 /* phoneId= */,
+ mMockCi, wrongAid, false /* supportExtendedApdu */);
+ });
+ }
+
+ @Test
public void testSendEmptyCommands() throws InterruptedException {
int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "A1A1A19000");
LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
@@ -121,7 +132,7 @@
assertEquals("A1A1A19000", IccUtils.bytesToHexString(mSelectResponse));
assertNull(mResponseCaptor.response);
assertNull(mResponseCaptor.exception);
- verify(mMockCi).iccOpenLogicalChannel(eq(AID), anyInt(), any());
+ verify(mMockCi).iccOpenLogicalChannel(eq(ApduSender.ISD_R_AID), anyInt(), any());
verify(mMockCi).iccCloseLogicalChannel(eq(channel), eq(true /*isEs10*/), any());
}
@@ -137,7 +148,7 @@
assertNull("Request provider should not be called when failed to open channel.",
mSelectResponse);
assertTrue(mResponseCaptor.exception instanceof ApduException);
- verify(mMockCi).iccOpenLogicalChannel(eq(AID), anyInt(), any());
+ verify(mMockCi).iccOpenLogicalChannel(eq(ApduSender.ISD_R_AID), anyInt(), any());
}
@Test
@@ -341,6 +352,6 @@
assertNull("Should not open channel when another one is already opened.", mSelectResponse);
assertTrue(mResponseCaptor.exception instanceof ApduException);
- verify(mMockCi, times(1)).iccOpenLogicalChannel(eq(AID), anyInt(), any());
+ verify(mMockCi, times(1)).iccOpenLogicalChannel(eq(ApduSender.ISD_R_AID), anyInt(), any());
}
}