Merge "Fix issues associated with hold failure"
diff --git a/Android.bp b/Android.bp
index 4925d51..7530b7a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,6 @@
static_libs: [
"telephony-protos",
"ecc-protos-lite",
- "android-support-annotations",
],
product_variables: {
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index 14e2e12..28e1355 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -50,6 +50,9 @@
// Hardware revision (EVT, DVT, PVT etc.)
optional string hardware_revision = 9;
+
+ // The last active subscription info for each slot.
+ repeated ActiveSubscriptionInfo last_active_subscription_info = 10;
}
// The time information
@@ -276,9 +279,6 @@
// Current data radio technology
optional RadioAccessTechnology data_rat = 6 [default = UNKNOWN];
-
- // All the active subscription information.
- repeated ActiveSubscriptionInfo active_subscription_info = 7;
}
// Radio access families
@@ -619,9 +619,6 @@
// The network interface name e.g. wlan0, rmnet_data0.
optional string iframe = 3;
-
- // All the active subscription information.
- repeated ActiveSubscriptionInfo active_subscription_info = 4;
}
message TelephonyEvent {
@@ -675,73 +672,99 @@
// Carrier Key Change event.
CARRIER_KEY_CHANGED = 14;
- // Phone status change event.
- PHONE_STATUS_CHANGED = 15;
-
// Data switch event.
- DATA_SWITCH = 16;
+ DATA_SWITCH = 15;
// Network validate event.
- NETWORK_VALIDATE = 17;
+ NETWORK_VALIDATE = 16;
// On deman data switch event.
- ON_DEMAND_DATA_SWITCH = 18;
+ ON_DEMAND_DATA_SWITCH = 17;
+
+ // SIM state change event.
+ SIM_STATE_CHANGED = 18;
+
+ // Active subscription info change event.
+ ACTIVE_SUBSCRIPTION_INFO_CHANGED = 19;
+
+ // Enabled modem change event.
+ ENABLED_MODEM_CHANGED = 20;
}
enum ApnType {
- DEFAULT = 0;
- MMS = 1;
- SUPL = 2;
- DUN = 3;
- HIPRI = 4;
- FOTA = 5;
- IMS = 6;
- CBS = 7;
- IA = 8;
- EMERGENCY = 9;
+ APN_TYPE_UNKNOWN = 0;
+
+ APN_TYPE_DEFAULT = 1;
+
+ APN_TYPE_MMS = 2;
+
+ APN_TYPE_SUPL = 3;
+
+ APN_TYPE_DUN = 4;
+
+ APN_TYPE_HIPRI = 5;
+
+ APN_TYPE_FOTA = 6;
+
+ APN_TYPE_IMS = 7;
+
+ APN_TYPE_CBS = 8;
+
+ APN_TYPE_IA = 9;
+
+ APN_TYPE_EMERGENCY = 10;
}
enum EventState {
- START = 0;
- END = 1;
+ EVENT_STATE_UNKNOWN = 0;
+
+ EVENT_STATE_START = 1;
+
+ EVENT_STATE_END = 2;
}
enum NetworkValidationState {
- /** The network under validation is initial established. */
- AVAILABLE = 0;
+ /** The network validation state is unknown. */
+ NETWORK_VALIDATION_STATE_UNKNOWN = 0;
- /** The validation is failed. */
- FAILED = 1;
+ /** The network under validation is initial established. */
+ NETWORK_VALIDATION_STATE_AVAILABLE = 1;
- /** The validation is passed. */
- PASSED = 2;
+ /** The validation is failed. */
+ NETWORK_VALIDATION_STATE_FAILED = 2;
+
+ /** The validation is passed. */
+ NETWORK_VALIDATION_STATE_PASSED = 3;
}
message DataSwitch {
- enum Reason {
- /** Data switch caused by user's manual switch. */
- MANUAL = 0;
+ enum Reason {
+ /** Data switch caused by unknown reason. */
+ DATA_SWITCH_REASON_UNKNOWN = 0;
- /** Data switch caused by incoming/outgoing call. */
- IN_CALL = 1;
+ /** Data switch caused by user's manual switch. */
+ DATA_SWITCH_REASON_MANUAL = 1;
- /** Data switch caused by CBRS switch. */
- CBRS = 2;
- }
+ /** Data switch caused by incoming/outgoing call. */
+ DATA_SWITCH_REASON_IN_CALL = 2;
- /** The reason for data switch. */
- optional Reason reason = 1;
+ /** Data switch caused by CBRS switch. */
+ DATA_SWITCH_REASON_CBRS = 3;
+ }
- /** Current state of the data switch event. */
- optional EventState state = 2;
+ /** The reason for data switch. */
+ optional Reason reason = 1;
+
+ /** Current state of the data switch event. */
+ optional EventState state = 2;
}
message OnDemandDataSwitch {
- /** The apn associated with this event. */
- optional ApnType apn = 1;
+ /** The apn associated with this event. */
+ optional ApnType apn = 1;
- /** Current state of the on demand data switch event. */
- optional EventState state = 2;
+ /** Current state of the on demand data switch event. */
+ optional EventState state = 2;
}
// Setup a packet data connection
@@ -1536,17 +1559,6 @@
optional string mccmnc = 3;
}
- message PhoneStatus {
- /** The sim state of each active slot. */
- repeated SimState sim_state = 1;
-
- /**
- * The modem state represent by a bitmap, the i-th bit(LSB) indicates the i-th modem
- * state(0 - disabled, 1 - enabled).
- */
- optional int32 enabled_modem_bitmap = 2;
- }
-
// Time when event happened on device, in milliseconds since epoch
optional int64 timestamp_millis = 1;
@@ -1598,9 +1610,6 @@
// Carrier key change
optional CarrierKeyChange carrier_key_change = 17;
- // Phone status
- optional PhoneStatus phone_status = 18;
-
// Data switch event
optional DataSwitch data_switch = 19;
@@ -1609,31 +1618,41 @@
// On demand data switch event
optional OnDemandDataSwitch on_demand_data_switch = 21;
+
+ // Sim state for each slot.
+ repeated SimState sim_state = 22;
+
+ // The active subscription info for a specific slot.
+ optional ActiveSubscriptionInfo active_subscription_info = 23;
+
+ // The modem state represent by a bitmap, the i-th bit(LSB) indicates the i-th modem
+ // state (0 - disabled, 1 - enabled).
+ optional int32 enabled_modem_bitmap = 24;
}
message ActiveSubscriptionInfo {
- /** The slot index which this subscription associated with. */
- optional int32 slot_index = 1;
+ /** The slot index which this subscription is associated with. */
+ optional int32 slot_index = 1;
- /** The Carrier id of this subscription. */
- optional int32 carrier_id = 2;
+ /** The Carrier id of this subscription. -1 indicates unknown value. */
+ optional int32 carrier_id = 2;
- /** whether subscription is opportunistic. */
- optional bool is_opportunistic = 3;
+ /** whether subscription is opportunistic (0 - false, 1 - true, -1 - unknown). */
+ optional int32 is_opportunistic = 3;
};
enum SimState {
- /**
- * SIM card is inserted, but the state is unknown. Typically happened when the SIM is inserted
- * but not loaded.
- */
- SIM_STATE_UNKNOWN = 0;
+ /**
+ * SIM card is inserted, but the state is unknown. Typically happened when the SIM is inserted
+ * but not loaded.
+ */
+ SIM_STATE_UNKNOWN = 0;
- /** No SIM card is inserted in the slot. */
- SIM_STATE_ABSENT = 1;
+ /** No SIM card is inserted in the slot. */
+ SIM_STATE_ABSENT = 1;
- /** SIM card applications have been loaded. */
- SIM_STATE_LOADED = 2;
+ /** SIM card applications have been loaded. */
+ SIM_STATE_LOADED = 2;
};
enum TimeInterval {
@@ -2001,12 +2020,6 @@
// Indicating some call events are dropped
optional bool events_dropped = 4;
-
- // SIM state of the active slots
- repeated SimState sim_states = 5;
-
- // All the active subscription information.
- repeated ActiveSubscriptionInfo active_subscription_info = 6;
}
message SmsSession {
@@ -2221,12 +2234,6 @@
// Indicating some sms session events are dropped
optional bool events_dropped = 4;
-
- // SIM state of the active slots.
- repeated SimState sim_state = 5;
-
- // All the active subscription information.
- repeated ActiveSubscriptionInfo active_subscription_info = 6;
}
// Power stats for modem
diff --git a/src/java/com/android/internal/telephony/CarrierResolver.java b/src/java/com/android/internal/telephony/CarrierResolver.java
index 9f96c67..60233f9 100644
--- a/src/java/com/android/internal/telephony/CarrierResolver.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -45,7 +45,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* CarrierResolver identifies the subscription carrier and returns a canonical carrier Id
@@ -71,15 +70,15 @@
private List<CarrierMatchingRule> mCarrierMatchingRulesOnMccMnc = new ArrayList<>();
// cached carrier Id
private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
- // cached precise carrier Id
- private int mPreciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+ // cached specific carrier Id
+ private int mSpecificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
// cached MNO carrier Id. mno carrier shares the same mccmnc as cid and can be solely
// identified by mccmnc only. If there is no such mno carrier, mno carrier id equals to
// the cid.
private int mMnoCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
// cached carrier name
private String mCarrierName;
- private String mPreciseCarrierName;
+ private String mSpecificCarrierName;
// cached preferapn name
private String mPreferApn;
// cached service provider name. telephonyManager API returns empty string as default value.
@@ -350,7 +349,7 @@
}
private void updateCarrierIdAndName(int cid, String name,
- int preciseCarrierId, String preciseCarrierName,
+ int specificCarrierId, String specificCarrierName,
int mnoCid) {
boolean update = false;
if (!equals(name, mCarrierName, true)) {
@@ -391,34 +390,34 @@
}
update = false;
- if (preciseCarrierId != mPreciseCarrierId) {
- logd("[updatePreciseCarrierId] from:" + mPreciseCarrierId + " to:"
- + preciseCarrierId);
- mPreciseCarrierId = preciseCarrierId;
+ if (specificCarrierId != mSpecificCarrierId) {
+ logd("[updateSpecificCarrierId] from:" + mSpecificCarrierId + " to:"
+ + specificCarrierId);
+ mSpecificCarrierId = specificCarrierId;
update = true;
}
- if (preciseCarrierName != mPreciseCarrierName) {
- logd("[updatePreciseCarrierName] from:" + mPreciseCarrierName + " to:"
- + preciseCarrierName);
- mPreciseCarrierName = preciseCarrierName;
+ if (specificCarrierName != mSpecificCarrierName) {
+ logd("[updateSpecificCarrierName] from:" + mSpecificCarrierName + " to:"
+ + specificCarrierName);
+ mSpecificCarrierName = specificCarrierName;
update = true;
}
if (update) {
- mCarrierIdLocalLog.log("[updatePreciseCarrierIdAndName] cid:" + mPreciseCarrierId
- + " name:" + mPreciseCarrierName);
+ mCarrierIdLocalLog.log("[updateSpecificCarrierIdAndName] cid:"
+ + mSpecificCarrierId + " name:" + mSpecificCarrierName);
final Intent intent = new Intent(TelephonyManager
- .ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED);
- intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_ID, mPreciseCarrierId);
- intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_NAME, mPreciseCarrierName);
+ .ACTION_SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID, mSpecificCarrierId);
+ intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_NAME, mSpecificCarrierName);
intent.putExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID, mPhone.getSubId());
mContext.sendBroadcast(intent);
- // notify content observers for precise carrier id change event.
+ // notify content observers for specific carrier id change event.
ContentValues cv = new ContentValues();
- cv.put(CarrierId.PRECISE_CARRIER_ID, mPreciseCarrierId);
- cv.put(CarrierId.PRECISE_CARRIER_ID_NAME, mPreciseCarrierName);
+ cv.put(CarrierId.SPECIFIC_CARRIER_ID, mSpecificCarrierId);
+ cv.put(CarrierId.SPECIFIC_CARRIER_ID_NAME, mSpecificCarrierName);
mContext.getContentResolver().update(
- Telephony.CarrierId.getPreciseCarrierIdUriForSubscriptionId(mPhone.getSubId()),
+ Telephony.CarrierId.getSpecificCarrierIdUriForSubscriptionId(mPhone.getSubId()),
cv, null, null);
}
}
@@ -742,8 +741,8 @@
maxRuleParent.mCid = maxRuleParent.mParentCid;
maxRuleParent.mName = getCarrierNameFromId(maxRuleParent.mCid);
}
- logd("[matchSubscriptionCarrier] precise cid: " + maxRule.mCid + " precise name: "
- + maxRule.mName +" cid: " + maxRuleParent.mCid
+ logd("[matchSubscriptionCarrier] specific cid: " + maxRule.mCid
+ + " specific name: " + maxRule.mName +" cid: " + maxRuleParent.mCid
+ " name: " + maxRuleParent.mName);
updateCarrierIdAndName(maxRuleParent.mCid, maxRuleParent.mName,
maxRule.mCid, maxRule.mName,
@@ -783,25 +782,29 @@
}
/**
* Returns fine-grained carrier id of the current subscription. Carrier ids with a valid parent
- * id are precise carrier ids.
- * The precise carrier id can be used to further differentiate a carrier by different
- * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
- * carrier id but can have multiple precise carrier id. e.g,
- * {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
- * {@link #getPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
- * current underlying network.
+ * id are specific carrier ids.
+ *
+ * A specific carrier ID can represent the fact that a carrier may be in effect an aggregation
+ * of other carriers (ie in an MVNO type scenario) where each of these specific carriers which
+ * are used to make up the actual carrier service may have different carrier configurations.
+ * A specific carrier ID could also be used, for example, in a scenario where a carrier requires
+ * different carrier configuration for different service offering such as a prepaid plan.
+ * e.g, {@link #getCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
+ * {@link #getSpecificCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
+ * IMSI from the current subscription.
+ *
* For carriers without any fine-grained carrier ids, return {@link #getCarrierId()}
*/
- public int getPreciseCarrierId() {
- return mPreciseCarrierId;
+ public int getSpecificCarrierId() {
+ return mSpecificCarrierId;
}
public String getCarrierName() {
return mCarrierName;
}
- public String getPreciseCarrierName() {
- return mPreciseCarrierName;
+ public String getSpecificCarrierName() {
+ return mSpecificCarrierName;
}
public int getMnoCarrierId() {
@@ -963,10 +966,10 @@
ipw.decreaseIndent();
ipw.println("mCarrierId: " + mCarrierId);
- ipw.println("mPreciseCarrierId: " + mPreciseCarrierId);
+ ipw.println("mSpecificCarrierId: " + mSpecificCarrierId);
ipw.println("mMnoCarrierId: " + mMnoCarrierId);
ipw.println("mCarrierName: " + mCarrierName);
- ipw.println("mPreciseCarrierName: " + mPreciseCarrierName);
+ ipw.println("mSpecificCarrierName: " + mSpecificCarrierName);
ipw.println("carrier_list_version: " + getCarrierListVersion());
ipw.println("mCarrierMatchingRules on mccmnc: "
diff --git a/src/java/com/android/internal/telephony/CellularNetworkValidator.java b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
index 3e552fc..e88949b 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkValidator.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
@@ -25,6 +25,9 @@
import android.telephony.SubscriptionManager;
import android.util.Log;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
+
/**
* This class will validate whether cellular network verified by Connectivity's
* validation process. It listens request on a specific subId, sends a network request
@@ -186,6 +189,10 @@
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
mState = STATE_IDLE;
}
+
+ TelephonyMetrics.getInstance().writeNetworkValidate(passed
+ ? TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_PASSED
+ : TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_FAILED);
}
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -203,6 +210,10 @@
@Override
public void onAvailable(Network network) {
logd("network onAvailable " + network);
+ if (ConnectivityNetworkCallback.this.mSubId == CellularNetworkValidator.this.mSubId) {
+ TelephonyMetrics.getInstance().writeNetworkValidate(
+ TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_AVAILABLE);
+ }
}
@Override
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 6f139f6..d47e872 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -54,6 +54,7 @@
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Telephony;
+import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
@@ -268,6 +269,8 @@
mSettingsObserver.observe(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
+
+ loadTtyMode();
logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
}
@@ -275,8 +278,17 @@
@Override
public void onReceive(Context context, Intent intent) {
Rlog.d(LOG_TAG, "mBroadcastReceiver: action " + intent.getAction());
- if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+ String action = intent.getAction();
+ if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
sendMessage(obtainMessage(EVENT_CARRIER_CONFIG_CHANGED));
+ } else if (TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED.equals(action)) {
+ int ttyMode = intent.getIntExtra(
+ TelecomManager.EXTRA_CURRENT_TTY_MODE, TelecomManager.TTY_MODE_OFF);
+ updateTtyMode(ttyMode);
+ } else if (TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED.equals(action)) {
+ int newPreferredTtyMode = intent.getIntExtra(
+ TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
+ updateUiTtyMode(newPreferredTtyMode);
}
}
};
@@ -327,8 +339,12 @@
mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
mCi.registerForVoiceRadioTechChanged(this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
- mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(
- CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ IntentFilter filter = new IntentFilter(
+ CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
+ filter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+
mCDM = new CarrierKeyDownloadManager(this);
mCIM = new CarrierInfoManager();
}
@@ -1639,13 +1655,13 @@
}
@Override
- public int getPreciseCarrierId() {
- return mCarrierResolver.getPreciseCarrierId();
+ public int getSpecificCarrierId() {
+ return mCarrierResolver.getSpecificCarrierId();
}
@Override
- public String getPreciseCarrierName() {
- return mCarrierResolver.getPreciseCarrierName();
+ public String getSpecificCarrierName() {
+ return mCarrierResolver.getSpecificCarrierName();
}
@Override
@@ -3868,4 +3884,47 @@
}
return currentConfig;
}
+
+ private void updateTtyMode(int ttyMode) {
+ logi(String.format("updateTtyMode ttyMode=%d", ttyMode));
+ setTTYMode(telecomModeToPhoneMode(ttyMode), null);
+ }
+ private void updateUiTtyMode(int ttyMode) {
+ logi(String.format("updateUiTtyMode ttyMode=%d", ttyMode));
+ setUiTTYMode(telecomModeToPhoneMode(ttyMode), null);
+ }
+
+ /**
+ * Given a telecom TTY mode, convert to a Telephony mode equivalent.
+ * @param telecomMode Telecom TTY mode.
+ * @return Telephony phone TTY mode.
+ */
+ private static int telecomModeToPhoneMode(int telecomMode) {
+ switch (telecomMode) {
+ // AT command only has 0 and 1, so mapping VCO
+ // and HCO to FULL
+ case TelecomManager.TTY_MODE_FULL:
+ case TelecomManager.TTY_MODE_VCO:
+ case TelecomManager.TTY_MODE_HCO:
+ return Phone.TTY_MODE_FULL;
+ default:
+ return Phone.TTY_MODE_OFF;
+ }
+ }
+
+ /**
+ * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings.
+ */
+ private void loadTtyMode() {
+ int ttyMode = TelecomManager.TTY_MODE_OFF;
+ TelecomManager telecomManager = TelecomManager.from(mContext);
+ if (telecomManager != null) {
+ ttyMode = telecomManager.getCurrentTtyMode();
+ }
+ updateTtyMode(ttyMode);
+ //Get preferred TTY mode from settings as UI Tty mode is always user preferred Tty mode.
+ ttyMode = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF);
+ updateUiTtyMode(ttyMode);
+ }
}
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index 76af170..0c0044d 100644
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -17,24 +17,24 @@
package com.android.internal.telephony;
import android.content.ContentProvider;
-import android.content.UriMatcher;
import android.content.ContentValues;
+import android.content.UriMatcher;
import android.database.Cursor;
-import android.database.MergeCursor;
import android.database.MatrixCursor;
+import android.database.MergeCursor;
import android.net.Uri;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
-import android.telephony.Rlog;
-
-import java.util.List;
import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.IccConstants;
+import java.util.List;
+
/**
* {@hide}
@@ -121,7 +121,8 @@
private Cursor loadAllSimContacts(int efType) {
Cursor [] result;
- List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+ List<SubscriptionInfo> subInfoList = mSubscriptionManager
+ .getActiveSubscriptionInfoList(false);
if ((subInfoList == null) || (subInfoList.size() == 0)) {
result = new Cursor[0];
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index d64547e..8417121 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -3207,11 +3207,11 @@
return TelephonyManager.UNKNOWN_CARRIER_ID;
}
- public int getPreciseCarrierId() {
+ public int getSpecificCarrierId() {
return TelephonyManager.UNKNOWN_CARRIER_ID;
}
- public String getPreciseCarrierName() {
+ public String getSpecificCarrierName() {
return null;
}
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 616e9fe..a191c47 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -46,11 +46,11 @@
private static final int EVENT_SWITCH_DSDS_CONFIG_DONE = 100;
private static final int EVENT_GET_MODEM_STATUS = 101;
private static final int EVENT_GET_MODEM_STATUS_DONE = 102;
+ private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103;
private static PhoneConfigurationManager sInstance = null;
private final Context mContext;
private PhoneCapability mStaticCapability;
- private PhoneCapability mCurrentCapability;
private final RadioConfig mRadioConfig;
private final MainThreadHandler mHandler;
private final Phone[] mPhones;
@@ -79,8 +79,8 @@
mContext = context;
// TODO: send commands to modem once interface is ready.
TelephonyManager telephonyManager = new TelephonyManager(context);
- mStaticCapability = PhoneConfigurationModels.DSDS_CAPABILITY;
- mCurrentCapability = mStaticCapability;
+ //initialize with default, it'll get updated when RADIO is ON/AVAILABLE
+ mStaticCapability = getDefaultCapability();
mRadioConfig = RadioConfig.getInstance(mContext);
mHandler = new MainThreadHandler();
mPhoneStatusMap = new HashMap<>();
@@ -99,6 +99,14 @@
}
}
+ private PhoneCapability getDefaultCapability() {
+ if (getPhoneCount() > 1) {
+ return PhoneConfigurationModels.DSDS_CAPABILITY;
+ } else {
+ return PhoneConfigurationModels.SSSS_CAPABILITY;
+ }
+ }
+
/**
* Static method to get instance.
*/
@@ -131,6 +139,7 @@
} else {
updatePhoneStatus(phone);
}
+ getStaticPhoneCapability();
break;
case EVENT_SWITCH_DSDS_CONFIG_DONE:
ar = (AsyncResult) msg.obj;
@@ -152,6 +161,14 @@
log(msg.what + " failure. Not updating modem status." + ar.exception);
}
break;
+ case EVENT_GET_PHONE_CAPABILITY_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar != null && ar.exception == null) {
+ mStaticCapability = (PhoneCapability) ar.result;
+ notifyCapabilityChanged();
+ } else {
+ log(msg.what + " failure. Not getting phone capability." + ar.exception);
+ }
}
}
}
@@ -196,7 +213,7 @@
}
/**
- * method to call RIL getM
+ * method to call RIL getModemStatus
*/
private void updatePhoneStatus(Phone phone) {
Message callback = Message.obtain(
@@ -224,7 +241,13 @@
/**
* get static overall phone capabilities for all phones.
*/
- public PhoneCapability getStaticPhoneCapability() {
+ public synchronized PhoneCapability getStaticPhoneCapability() {
+ if (getDefaultCapability().equals(mStaticCapability)) {
+ log("getStaticPhoneCapability: sending the request for getting PhoneCapability");
+ Message callback = Message.obtain(
+ mHandler, EVENT_GET_PHONE_CAPABILITY_DONE);
+ mRadioConfig.getPhoneCapability(callback);
+ }
return mStaticCapability;
}
@@ -232,17 +255,17 @@
* get configuration related status of each phone.
*/
public PhoneCapability getCurrentPhoneCapability() {
- return mCurrentCapability;
+ return getStaticPhoneCapability();
}
public int getNumberOfModemsWithSimultaneousDataConnections() {
- return mCurrentCapability.maxActiveData;
+ return mStaticCapability.maxActiveData;
}
private void notifyCapabilityChanged() {
PhoneNotifier notifier = new DefaultPhoneNotifier();
- notifier.notifyPhoneCapabilityChanged(mCurrentCapability);
+ notifier.notifyPhoneCapabilityChanged(mStaticCapability);
}
/**
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationModels.java b/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
index fb8cc5e..aca4955 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationModels.java
@@ -40,7 +40,7 @@
List<ModemInfo> logicalModemList = new ArrayList<>();
logicalModemList.add(modemInfo1);
logicalModemList.add(modemInfo2);
- DSDS_CAPABILITY = new PhoneCapability(1, 2, 0, logicalModemList, false);
+ DSDS_CAPABILITY = new PhoneCapability(1, 2, 0, logicalModemList, true);
logicalModemList = new ArrayList<>();
logicalModemList.add(modemInfo1);
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 043de1c..065b201 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -27,7 +27,7 @@
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
-import android.telephony.DebugEventReporter;
+import android.telephony.AnomalyReporter;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -556,7 +556,7 @@
pw.println("DebugEvents:");
pw.increaseIndent();
try {
- DebugEventReporter.dump(fd, pw, args);
+ AnomalyReporter.dump(fd, pw, args);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index aca9074..c3fba00 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -16,17 +16,24 @@
package com.android.internal.telephony;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_PRECISE_CALL_STATE;
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_INVALID_PARAMETER;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS;
+import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.MatchAllNetworkSpecifier;
+import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
@@ -38,6 +45,7 @@
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.PreciseCallState;
@@ -48,6 +56,10 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.dataconnection.DcRequest;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -65,8 +77,10 @@
* the active phones. Note we don't wait for data attach (which may not happen anyway).
*/
public class PhoneSwitcher extends Handler {
- private final static String LOG_TAG = "PhoneSwitcher";
- private final static boolean VDBG = false;
+ private static final String LOG_TAG = "PhoneSwitcher";
+ private static final boolean VDBG = false;
+
+ private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000;
private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>();
private final RegistrantList mActivePhoneRegistrants;
@@ -103,16 +117,19 @@
private int mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX;
+ private ISetOpportunisticDataCallback mSetOpptSubCallback;
+
private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED = 101;
private static final int EVENT_SUBSCRIPTION_CHANGED = 102;
private static final int EVENT_REQUEST_NETWORK = 103;
private static final int EVENT_RELEASE_NETWORK = 104;
private static final int EVENT_EMERGENCY_TOGGLE = 105;
private static final int EVENT_RADIO_CAPABILITY_CHANGED = 106;
- private static final int EVENT_PREFERRED_SUBSCRIPTION_CHANGED = 107;
+ private static final int EVENT_CHANGE_PREFERRED_SUBSCRIPTION = 107;
private static final int EVENT_RADIO_AVAILABLE = 108;
private static final int EVENT_PHONE_IN_CALL_CHANGED = 109;
private static final int EVENT_NETWORK_VALIDATION_DONE = 110;
+ private static final int EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK = 111;
// Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's
// 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse
@@ -129,6 +146,24 @@
// Default timeout value of network validation in millisecond.
private final static int DEFAULT_VALIDATION_EXPIRATION_TIME = 2000;
+ private Boolean mHasRegisteredDefaultNetworkChangeCallback = false;
+
+ private ConnectivityManager mConnectivityManager;
+
+ private final ConnectivityManager.NetworkCallback mDefaultNetworkCallback =
+ new NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ if (mConnectivityManager.getNetworkCapabilities(network)
+ .hasTransport(TRANSPORT_CELLULAR)) {
+ logDataSwitchEvent(
+ TelephonyEvent.EventState.EVENT_STATE_END,
+ TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN);
+ }
+ removeDefaultNetworkChangeCallback();
+ }
+ };
+
/**
* Method to get singleton instance.
*/
@@ -150,6 +185,7 @@
return sPhoneSwitcher;
}
+ /** This constructor is only used for testing purpose. */
@VisibleForTesting
public PhoneSwitcher(int numPhones, Looper looper) {
super(looper);
@@ -241,11 +277,14 @@
} catch (RemoteException e) {
}
+ mConnectivityManager =
+ (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
mContext.registerReceiver(mDefaultDataChangedReceiver,
new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ netCap.addTransportType(TRANSPORT_CELLULAR);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
@@ -295,7 +334,10 @@
break;
}
case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: {
+ logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+ DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
onEvaluate(REQUESTS_UNCHANGED, "defaultChanged");
+ registerDefaultNetworkChangeCallback();
break;
}
case EVENT_REQUEST_NETWORK: {
@@ -314,8 +356,16 @@
resendRilCommands(msg);
break;
}
- case EVENT_PREFERRED_SUBSCRIPTION_CHANGED: {
- onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged");
+ case EVENT_CHANGE_PREFERRED_SUBSCRIPTION: {
+ int subId = msg.arg1;
+ boolean needValidation = (msg.arg2 == 1);
+ ISetOpportunisticDataCallback callback =
+ (ISetOpportunisticDataCallback) msg.obj;
+ if (SubscriptionManager.isUsableSubscriptionId(subId)) {
+ setOpportunisticDataSubscription(subId, needValidation, callback);
+ } else {
+ unsetOpportunisticDataSubscription(callback);
+ }
break;
}
case EVENT_RADIO_AVAILABLE: {
@@ -324,7 +374,10 @@
break;
}
case EVENT_PHONE_IN_CALL_CHANGED: {
+ logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+ DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED");
+ registerDefaultNetworkChangeCallback();
break;
}
case EVENT_NETWORK_VALIDATION_DONE: {
@@ -333,6 +386,10 @@
onValidationDone(subId, passed);
break;
}
+ case EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK: {
+ removeDefaultNetworkChangeCallback();
+ break;
+ }
}
}
@@ -371,7 +428,8 @@
private void onRequestNetwork(NetworkRequest networkRequest) {
final DcRequest dcRequest = new DcRequest(networkRequest, mContext);
- if (mPrioritizedDcRequests.contains(dcRequest) == false) {
+ if (!mPrioritizedDcRequests.contains(dcRequest)) {
+ collectRequestNetworkMetrics(networkRequest);
mPrioritizedDcRequests.add(dcRequest);
Collections.sort(mPrioritizedDcRequests);
onEvaluate(REQUESTS_CHANGED, "netRequest");
@@ -383,6 +441,53 @@
if (mPrioritizedDcRequests.remove(dcRequest)) {
onEvaluate(REQUESTS_CHANGED, "netReleased");
+ collectReleaseNetworkMetrics(networkRequest);
+ }
+ }
+
+ private void removeDefaultNetworkChangeCallback() {
+ synchronized (mHasRegisteredDefaultNetworkChangeCallback) {
+ if (mHasRegisteredDefaultNetworkChangeCallback) {
+ mHasRegisteredDefaultNetworkChangeCallback = false;
+ removeMessages(EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK);
+ mConnectivityManager.unregisterNetworkCallback(mDefaultNetworkCallback);
+ }
+ }
+ }
+
+ private void registerDefaultNetworkChangeCallback() {
+ removeDefaultNetworkChangeCallback();
+
+ synchronized (mHasRegisteredDefaultNetworkChangeCallback) {
+ mHasRegisteredDefaultNetworkChangeCallback = true;
+ mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback);
+ sendMessageDelayed(
+ obtainMessage(EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK),
+ DEFAULT_NETWORK_CHANGE_TIMEOUT_MS);
+ }
+ }
+
+ 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 (mNumPhones > 1 && networkRequest.networkCapabilities.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.
+ if (mNumPhones > 1 && networkRequest.networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_MMS)) {
+ OnDemandDataSwitch onDemandDataSwitch = new OnDemandDataSwitch();
+ onDemandDataSwitch.apn = TelephonyEvent.ApnType.APN_TYPE_MMS;
+ onDemandDataSwitch.state = TelephonyEvent.EventState.EVENT_STATE_END;
+ TelephonyMetrics.getInstance().writeOnDemandDataSwitch(onDemandDataSwitch);
}
}
@@ -494,6 +599,10 @@
activate(phoneId);
}
}
+
+ notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId(
+ mPreferredDataPhoneId));
+
// Notify all registrants.
mActivePhoneRegistrants.notifyRegistrants();
}
@@ -689,19 +798,35 @@
* subscription. It has to be an active subscription, and PhoneSwitcher will try to validate
* it first if needed.
*/
- public void setOpportunisticDataSubscription(int subId) {
+ private void setOpportunisticDataSubscription(int subId, boolean needValidation,
+ ISetOpportunisticDataCallback callback) {
if (!mSubscriptionController.isActiveSubId(subId)) {
log("Can't switch data to inactive subId " + subId);
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INVALID_PARAMETER);
+ return;
+ }
+
+ if (mValidator.isValidating()
+ && (!needValidation || subId != mValidator.getSubIdInValidation())) {
+ mValidator.stopValidation();
+ }
+
+ if (subId == mPreferredDataSubId) {
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
return;
}
// If validation feature is not supported, set it directly. Otherwise,
// start validation on the subscription first.
- if (!CellularNetworkValidator.isValidationFeatureSupported()) {
- setPreferredDataSubscriptionId(subId);
- } else {
+ if (CellularNetworkValidator.isValidationFeatureSupported() && needValidation) {
+ logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+ DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
+ mSetOpptSubCallback = callback;
mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME,
false, mValidationCallback);
+ } else {
+ setPreferredSubscription(subId);
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
}
}
@@ -709,32 +834,57 @@
* Unset opportunistic data subscription. It's an indication to switch Internet data back
* from opportunistic subscription to primary subscription.
*/
- public void unsetOpportunisticDataSubscription() {
- if (CellularNetworkValidator.isValidationFeatureSupported()
- && mValidator.isValidating()) {
+ private void unsetOpportunisticDataSubscription(ISetOpportunisticDataCallback callback) {
+ if (mValidator.isValidating()) {
mValidator.stopValidation();
}
// Set mPreferredDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger
// data switch to mDefaultDataSubId.
- setPreferredDataSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ setPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
+ }
+
+ private void sendSetOpptCallbackHelper(ISetOpportunisticDataCallback callback, int result) {
+ if (callback == null) return;
+ try {
+ callback.onComplete(result);
+ } catch (RemoteException exception) {
+ log("RemoteException " + exception);
+ }
+ }
+
+ /**
+ * Set opportunistic data subscription.
+ */
+ private void setPreferredSubscription(int subId) {
+ if (mPreferredDataSubId != subId) {
+ mPreferredDataSubId = subId;
+ logDataSwitchEvent(TelephonyEvent.EventState.EVENT_STATE_START,
+ DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
+ onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged");
+ registerDefaultNetworkChangeCallback();
+ }
}
private void onValidationDone(int subId, boolean passed) {
log("Network validation " + (passed ? "passed" : "failed")
+ " on subId " + subId);
- mValidator.stopValidation();
- if (passed) setPreferredDataSubscriptionId(subId);
+ if (passed) setPreferredSubscription(subId);
+
+ // Trigger callback if needed
+ sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS
+ : SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
+ mSetOpptSubCallback = null;
}
// TODO b/123598154: rename preferredDataSub to opportunisticSubId.
- private void setPreferredDataSubscriptionId(int subId) {
- if (mPreferredDataSubId != subId) {
- log("setPreferredDataSubscriptionId subId changed to " + subId);
- mPreferredDataSubId = subId;
- Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PREFERRED_SUBSCRIPTION_CHANGED);
- msg.sendToTarget();
- }
+ public void trySetPreferredSubscription(int subId, boolean needValidation,
+ ISetOpportunisticDataCallback callback) {
+ log("Try set preferred subscription to subId " + subId
+ + (needValidation ? " with " : " without ") + "validation");
+ PhoneSwitcher.this.obtainMessage(EVENT_CHANGE_PREFERRED_SUBSCRIPTION,
+ subId, needValidation ? 1 : 0, callback).sendToTarget();
}
private boolean isCallActive(Phone phone) {
@@ -751,11 +901,38 @@
? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
}
+ public int getPreferredDataSubscriptionId() {
+ return mPreferredDataSubId;
+ }
+
+ public int getPreferredDataPhoneId() {
+ return mPreferredDataPhoneId;
+ }
+
private void log(String l) {
Rlog.d(LOG_TAG, l);
mLocalLog.log(l);
}
+ private void logDataSwitchEvent(int state, int reason) {
+ DataSwitch dataSwitch = new DataSwitch();
+ dataSwitch.state = state;
+ dataSwitch.reason = reason;
+ TelephonyMetrics.getInstance().writeDataSwitch(dataSwitch);
+
+ }
+
+ private void notifyActiveDataSubIdChanged(int activeDataSubId) {
+ ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
+ "telephony.registry"));
+ try {
+ log("notifyActiveDataSubIdChanged to " + activeDataSubId);
+ tr.notifyActiveDataSubIdChanged(activeDataSubId);
+ } catch (RemoteException ex) {
+ // Should never happen because its always available.
+ }
+ }
+
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println("PhoneSwitcher:");
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 03cb8b1..e18e3c1 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -5658,7 +5658,9 @@
ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+ final long nanotime = SystemClock.elapsedRealtimeNanos();
for (android.hardware.radio.V1_0.CellInfo record : records) {
+ record.timeStamp = nanotime;
response.add(CellInfo.create(record));
}
@@ -5675,7 +5677,9 @@
ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+ final long nanotime = SystemClock.elapsedRealtimeNanos();
for (android.hardware.radio.V1_2.CellInfo record : records) {
+ record.timeStamp = nanotime;
response.add(CellInfo.create(record));
}
return response;
@@ -5691,8 +5695,9 @@
ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+ final long nanotime = SystemClock.elapsedRealtimeNanos();
for (android.hardware.radio.V1_4.CellInfo record : records) {
- response.add(CellInfo.create(record));
+ response.add(CellInfo.create(record, nanotime));
}
return response;
}
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index ab9afec..effab8f 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -324,7 +324,7 @@
* Wrapper function for IRadioConfig.getPhoneCapability().
*/
public void getPhoneCapability(Message result) {
- IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
+ IRadioConfig radioConfigProxy = getRadioConfigProxy(null);
if (radioConfigProxy == null || mRadioConfigVersion.less(RADIO_CONFIG_HAL_VERSION_1_1)) {
if (result != null) {
AsyncResult.forMessage(result, null,
@@ -393,12 +393,16 @@
static String requestToString(int request) {
switch (request) {
+ case RIL_REQUEST_GET_PHONE_CAPABILITY:
+ return "GET_PHONE_CAPABILITY";
case RIL_REQUEST_GET_SLOT_STATUS:
return "GET_SLOT_STATUS";
case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
+ case RIL_REQUEST_SET_PREFERRED_DATA_MODEM:
+ return "SET_PREFERRED_DATA_MODEM";
case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
- return "RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG";
+ return "SWITCH_DUAL_SIM_CONFIG";
default:
return "<unknown request>";
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
old mode 100644
new mode 100755
index fd0b011..562d2d7
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -422,6 +422,7 @@
public static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service
public static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service
public static final int CS_REJECT_CAUSE_ENABLED = 2001; // Notify MM rejection cause
+ public static final int CS_REJECT_CAUSE_DISABLED = 2002; // Cancel MM rejection cause
/** Notification id. */
public static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted
public static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted
@@ -3873,6 +3874,8 @@
Context context = mPhone.getContext();
+ boolean autoCancelCsRejectNotification = false;
+
CarrierConfigManager configManager = (CarrierConfigManager)
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager != null) {
@@ -3886,6 +3889,8 @@
if (DBG) log("Voice/emergency call barred notification disabled");
return;
}
+ autoCancelCsRejectNotification = bundle.getBoolean(
+ CarrierConfigManager.KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
}
}
@@ -3946,8 +3951,12 @@
notificationId = CS_REJECT_CAUSE_NOTIFICATION;
int resId = selectResourceForRejectCode(mRejectCode, multipleSubscriptions);
if (0 == resId) {
- loge("setNotification: mRejectCode=" + mRejectCode + " is not handled.");
- return;
+ if (autoCancelCsRejectNotification) {
+ notifyType = CS_REJECT_CAUSE_DISABLED;
+ } else {
+ loge("setNotification: mRejectCode=" + mRejectCode + " is not handled.");
+ return;
+ }
} else {
icon = com.android.internal.R.drawable.stat_notify_mmcc_indication_icn;
// if using the single SIM resource, simNumber will be ignored
@@ -3978,7 +3987,8 @@
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
- if (notifyType == PS_DISABLED || notifyType == CS_DISABLED) {
+ if (notifyType == PS_DISABLED || notifyType == CS_DISABLED
+ || notifyType == CS_REJECT_CAUSE_DISABLED) {
// cancel previous post notification
notificationManager.cancel(Integer.toString(mSubId), notificationId);
} else {
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index f89ba4d..f8b58ff 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -92,7 +92,7 @@
public class SubscriptionController extends ISub.Stub {
static final String LOG_TAG = "SubscriptionController";
static final boolean DBG = true;
- static final boolean VDBG = false;
+ static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
static final boolean DBG_CACHE = false;
static final int MAX_LOCAL_LOG_LINES = 500; // TODO: Reduce to 100 when 17678050 is fixed
private static final int DEPRECATED_SETTING = -1;
@@ -611,7 +611,7 @@
*/
@Override
public List<SubscriptionInfo> getAllSubInfoList(String callingPackage) {
- if (DBG) logd("[getAllSubInfoList]+");
+ if (VDBG) logd("[getAllSubInfoList]+");
// This API isn't public, so no need to provide a valid subscription ID - we're not worried
// about carrier-privileged callers not having access.
@@ -627,9 +627,9 @@
List<SubscriptionInfo> subList = null;
subList = getSubInfo(null, null);
if (subList != null) {
- if (DBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return");
+ if (VDBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return");
} else {
- if (DBG) logd("[getAllSubInfoList]- no info return");
+ if (VDBG) logd("[getAllSubInfoList]- no info return");
}
return subList;
} finally {
@@ -2268,12 +2268,30 @@
return allSubs;
}
+ private boolean isInvisibleSubscription(int subId) {
+ for (SubscriptionInfo info : mCacheOpportunisticSubInfoList) {
+ if (info.getSubscriptionId() == subId) {
+ return SubscriptionManager.isInvisibleSubscription(info);
+ }
+ }
+
+ return false;
+ }
+
+
/**
* @return the list of subId's that are active, is never null but the length maybe 0.
*/
@Override
- public int[] getActiveSubIdList() {
- ArrayList<Integer> allSubs = getActiveSubIdArrayList();
+ public int[] getActiveSubIdList(boolean visibleOnly) {
+ List<Integer> allSubs = getActiveSubIdArrayList();
+
+ if (visibleOnly) {
+ // Grouped opportunistic subscriptions should be hidden.
+ allSubs = allSubs.stream().filter(subId -> isInvisibleSubscription(subId))
+ .collect(Collectors.toList());
+ }
+
int[] subIdArr = new int[allSubs.size()];
int i = 0;
for (int sub : allSubs) {
@@ -2690,16 +2708,14 @@
}
@Override
- public void setPreferredDataSubscriptionId(int subId) {
+ public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
+ ISetOpportunisticDataCallback callback) {
enforceModifyPhoneState("setPreferredDataSubscriptionId");
final long token = Binder.clearCallingIdentity();
try {
- if (SubscriptionManager.isUsableSubscriptionId(subId)) {
- PhoneSwitcher.getInstance().setOpportunisticDataSubscription(subId);
- } else {
- PhoneSwitcher.getInstance().unsetOpportunisticDataSubscription();
- }
+ PhoneSwitcher.getInstance().trySetPreferredSubscription(
+ subId, needValidation, callback);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -2708,17 +2724,12 @@
@Override
public int getPreferredDataSubscriptionId() {
enforceReadPrivilegedPhoneState("getPreferredDataSubscriptionId");
- return mPreferredDataSubId;
- }
+ final long token = Binder.clearCallingIdentity();
- private void notifyPreferredDataSubIdChanged() {
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
try {
- if (DBG) logd("notifyPreferredDataSubIdChanged:");
- tr.notifyPreferredDataSubIdChanged(mPreferredDataSubId);
- } catch (RemoteException ex) {
- // Should never happen because its always available.
+ return PhoneSwitcher.getInstance().getPreferredDataSubscriptionId();
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -2778,6 +2789,8 @@
refreshCachedActiveSubscriptionInfoList();
+ notifySubscriptionInfoChanged();
+
return groupUUID;
} finally {
Binder.restoreCallingIdentity(identity);
@@ -2825,6 +2838,8 @@
refreshCachedActiveSubscriptionInfoList();
+ notifySubscriptionInfoChanged();
+
return result != 0;
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
index 96dabd4..77d8706 100644
--- a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
@@ -25,6 +25,7 @@
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
@@ -55,7 +56,7 @@
* It binds to the vendor's qualified networks service and actively monitors the qualified
* networks changes.
*/
-public class AccessNetworksManager {
+public class AccessNetworksManager extends Handler {
private static final String TAG = AccessNetworksManager.class.getSimpleName();
private static final boolean DBG = false;
@@ -69,6 +70,8 @@
ApnSetting.TYPE_EMERGENCY
};
+ private static final int EVENT_BIND_QUALIFIED_NETWORKS_SERVICE = 1;
+
private final Phone mPhone;
private final CarrierConfigManager mCarrierConfigManager;
@@ -77,8 +80,7 @@
private AccessNetworksManagerDeathRecipient mDeathRecipient;
- // The bound qualified networks service component name
- private ComponentName mBoundQualifiedNetworksServiceComponent;
+ private String mTargetBindingPackageName;
private QualifiedNetworksServiceConnection mServiceConnection;
@@ -94,10 +96,11 @@
if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
&& mPhone.getPhoneId() == intent.getIntExtra(
CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
- // When carrier config changes, we need to evaluate and see if we should unbind
- // the existing service and bind to a new one.
- if (DBG) log("Carrier config changed.");
- bindQualifiedNetworksService();
+ // We should wait for carrier config changed event because the target binding
+ // package name can come from the carrier config. Note that we still get this event
+ // even when SIM is absent.
+ if (DBG) log("Carrier config changed. Try to bind qualified network service.");
+ sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
}
}
};
@@ -107,7 +110,7 @@
*/
public static class QualifiedNetworks {
public final @ApnType int apnType;
- // The qualified netowrks in preferred order. Each network is a AccessNetworkType.
+ // The qualified networks in preferred order. Each network is a AccessNetworkType.
public final int[] qualifiedNetworks;
public QualifiedNetworks(@ApnType int apnType, int[] qualifiedNetworks) {
this.apnType = apnType;
@@ -134,15 +137,14 @@
@Override
public void binderDied() {
// TODO: try to rebind the service.
- loge("QualifiedNetworksService(" + mBoundQualifiedNetworksServiceComponent + ") died.");
+ loge("QualifiedNetworksService(" + mTargetBindingPackageName + ") died.");
}
}
private final class QualifiedNetworksServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- if (DBG) log("onServiceConnected");
- mBoundQualifiedNetworksServiceComponent = name;
+ if (DBG) log("onServiceConnected " + name);
mIQualifiedNetworksService = IQualifiedNetworksService.Stub.asInterface(service);
mDeathRecipient = new AccessNetworksManagerDeathRecipient();
@@ -157,8 +159,9 @@
}
@Override
public void onServiceDisconnected(ComponentName name) {
- if (DBG) log("onServiceDisconnected");
+ if (DBG) log("onServiceDisconnected " + name);
mIQualifiedNetworksService.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ mTargetBindingPackageName = null;
}
}
@@ -211,11 +214,22 @@
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL,
intentFilter, null, null);
+ sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
+ }
- // Only binds to qualified network service in AP-assisted mode. For legacy mode,
- // qualified networks service is not needed.
- if (phone.getTransportManager() != null && !phone.getTransportManager().isInLegacyMode()) {
- bindQualifiedNetworksService();
+ /**
+ * Handle message events
+ *
+ * @param msg The message to handle
+ */
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_BIND_QUALIFIED_NETWORKS_SERVICE:
+ bindQualifiedNetworksService();
+ break;
+ default:
+ loge("Unhandled event " + msg.what);
}
}
@@ -232,13 +246,13 @@
return;
}
+ if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
+ if (DBG) log("Service " + packageName + " already bound or being bound.");
+ return;
+ }
+
if (mIQualifiedNetworksService != null
&& mIQualifiedNetworksService.asBinder().isBinderAlive()) {
- if (mBoundQualifiedNetworksServiceComponent.getPackageName().equals(packageName)) {
- if (DBG) log("Service " + packageName + " already bound.");
- return;
- }
-
// Remove the network availability updater and then unbind the service.
try {
mIQualifiedNetworksService.removeNetworkAvailabilityUpdater(mPhone.getPhoneId());
@@ -258,7 +272,9 @@
mServiceConnection,
Context.BIND_AUTO_CREATE)) {
loge("Cannot bind to the qualified networks service.");
+ return;
}
+ mTargetBindingPackageName = packageName;
} catch (Exception e) {
loge("Cannot bind to the qualified networks service. Exception: " + e);
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index a751bbc..c2162f7 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -44,6 +44,7 @@
import android.provider.Telephony;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.DataFailCause;
+import android.telephony.NetworkRegistrationState;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -110,6 +111,9 @@
private static final String NETWORK_TYPE = "MOBILE";
+ private static final String RAT_NAME_5G = "nr";
+ private static final String RAT_NAME_EVDO = "evdo";
+
// The data connection providing default Internet connection will have a higher score of 50.
// Other connections will have a slightly lower score of 45. The intention is other connections
// will not cause ConnectivityService to tear down default internet connection. For example,
@@ -136,6 +140,8 @@
private String[] mPcscfAddr;
+ private final String mTagSuffix;
+
/**
* Used internally for saving connecting parameters.
*/
@@ -321,9 +327,9 @@
String transportType = (dataServiceManager.getTransportType() == TransportType.WWAN)
? "C" // Cellular
: "I"; // IWLAN
- DataConnection dc = new DataConnection(phone,
- "DC-" + transportType + "-" + mInstanceNumber.incrementAndGet(), id, dct,
- dataServiceManager, failBringUpAll, dcc);
+ DataConnection dc = new DataConnection(phone, transportType + "-"
+ + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
+ dcc);
dc.start();
if (DBG) dc.log("Made " + dc.getName());
return dc;
@@ -500,10 +506,11 @@
}
//***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
- private DataConnection(Phone phone, String name, int id,
+ private DataConnection(Phone phone, String tagSuffix, int id,
DcTracker dct, DataServiceManager dataServiceManager,
DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
- super(name, dcc.getHandler());
+ super("DC-" + tagSuffix, dcc.getHandler());
+ mTagSuffix = tagSuffix;
setLogRecSize(300);
setLogOnlyTransitions(true);
if (DBG) log("DataConnection created");
@@ -882,17 +889,25 @@
return true;
}
+ /**
+ * TCP buffer size config based on the ril technology. There are 6 parameters
+ * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer
+ * config string and they are separated by a comma. The unit of these parameters is byte.
+ */
private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000";
private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800";
private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576";
- private static final String TCP_BUFFER_SIZES_1XRTT= "16384,32768,131072,4096,16384,102400";
+ private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400";
private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144";
- private static final String TCP_BUFFER_SIZES_EHRPD= "131072,262144,1048576,4096,16384,524288";
- private static final String TCP_BUFFER_SIZES_HSDPA= "61167,367002,1101005,8738,52429,262114";
+ private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288";
+ private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114";
private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990";
- private static final String TCP_BUFFER_SIZES_LTE =
+ private static final String TCP_BUFFER_SIZES_LTE =
"524288,1048576,2097152,262144,524288,1048576";
- private static final String TCP_BUFFER_SIZES_HSPAP= "122334,734003,2202010,32040,192239,576717";
+ private static final String TCP_BUFFER_SIZES_HSPAP =
+ "122334,734003,2202010,32040,192239,576717";
+ private static final String TCP_BUFFER_SIZES_NR =
+ "2097152,6291456,16777216,512000,2097152,8388608";
private void updateTcpBufferSizes(int rilRat) {
String sizes = null;
@@ -907,7 +922,13 @@
if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A ||
rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) {
- ratName = "evdo";
+ ratName = RAT_NAME_EVDO;
+ }
+
+ // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this
+ // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
+ if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
+ ratName = RAT_NAME_5G;
}
// in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
@@ -955,7 +976,12 @@
break;
case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
- sizes = TCP_BUFFER_SIZES_LTE;
+ // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
+ if (isNRConnected()) {
+ sizes = TCP_BUFFER_SIZES_NR;
+ } else {
+ sizes = TCP_BUFFER_SIZES_LTE;
+ }
break;
case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
sizes = TCP_BUFFER_SIZES_HSPAP;
@@ -1853,6 +1879,8 @@
if (dc != null) {
mNetworkAgent = dc.getNetworkAgent();
if (mNetworkAgent != null) {
+ mNetworkAgent.setTransportType(mDataServiceManager.getTransportType());
+ log("Transfer the network agent from " + dc.getName() + " successfully.");
mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities());
mNetworkAgent.sendLinkProperties(mLinkProperties);
} else {
@@ -1864,8 +1892,8 @@
} else {
mScore = calculateScore();
mNetworkAgent = new DcNetworkAgent(getHandler().getLooper(), mPhone.getContext(),
- "DcNetworkAgent", mNetworkInfo, getNetworkCapabilities(), mLinkProperties,
- mScore, misc);
+ "DcNetworkAgent" + mTagSuffix, mNetworkInfo, getNetworkCapabilities(),
+ mLinkProperties, mScore, misc);
}
if (mDataServiceManager.getTransportType() == TransportType.WWAN) {
mPhone.mCi.registerForNattKeepaliveStatus(
@@ -1897,14 +1925,7 @@
mPhone.mCi.unregisterForLceInfo(getHandler());
}
if (mNetworkAgent != null) {
- // We do not want to update the network info if this is a handover. For all other
- // cases we need to update connectivity service with the latest network info.
- //
- // For handover, the network agent is transferred to the other data connection.
- if (mDisconnectParams == null
- || mDisconnectParams.mReleaseType != DcTracker.RELEASE_TYPE_HANDOVER) {
- mNetworkAgent.sendNetworkInfo(mNetworkInfo);
- }
+ mNetworkAgent.sendNetworkInfo(mNetworkInfo);
mNetworkAgent = null;
}
}
@@ -2305,6 +2326,8 @@
private class DcNetworkAgent extends NetworkAgent {
+ private final AtomicInteger mTransportType;
+
private NetworkCapabilities mNetworkCapabilities;
public final DcKeepaliveTracker keepaliveTracker = new DcKeepaliveTracker();
@@ -2314,6 +2337,11 @@
super(l, c, TAG, ni, nc, lp, score, misc);
mNetCapsLocalLog.log("New network agent created. capabilities=" + nc);
mNetworkCapabilities = nc;
+ mTransportType = new AtomicInteger(mDataServiceManager.getTransportType());
+ }
+
+ public void setTransportType(int transportType) {
+ mTransportType.set(transportType);
}
@Override
@@ -2357,6 +2385,11 @@
@Override
public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
+ if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+ log("sendNetworkCapabilities: Data connection has been handover to transport "
+ + TransportType.toString(mTransportType.get()));
+ return;
+ }
if (!networkCapabilities.equals(mNetworkCapabilities)) {
String logStr = "Changed from " + mNetworkCapabilities + " to "
+ networkCapabilities + ", Data RAT="
@@ -2370,6 +2403,36 @@
}
@Override
+ public void sendLinkProperties(LinkProperties linkProperties) {
+ if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+ log("sendLinkProperties: Data connection has been handover to transport "
+ + TransportType.toString(mTransportType.get()));
+ return;
+ }
+ super.sendLinkProperties(linkProperties);
+ }
+
+ @Override
+ public void sendNetworkScore(int score) {
+ if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+ log("sendNetworkScore: Data connection has been handover to transport "
+ + TransportType.toString(mTransportType.get()));
+ return;
+ }
+ super.sendNetworkScore(score);
+ }
+
+ @Override
+ public void sendNetworkInfo(NetworkInfo networkInfo) {
+ if (mTransportType.get() != mDataServiceManager.getTransportType()) {
+ log("sendNetworkScore: Data connection has been handover to transport "
+ + TransportType.toString(mTransportType.get()));
+ return;
+ }
+ super.sendNetworkInfo(networkInfo);
+ }
+
+ @Override
protected void startSocketKeepalive(Message msg) {
if (msg.obj instanceof NattKeepalivePacketData) {
DataConnection.this.obtainMessage(EVENT_KEEPALIVE_START_REQUEST,
@@ -2569,7 +2632,7 @@
*/
public void tearDownAll(String reason, @ReleaseNetworkType int releaseType,
Message onCompletedMsg) {
- if (DBG) log("tearDownAll: reason=" + reason + " onCompletedMsg=" + onCompletedMsg);
+ if (DBG) log("tearDownAll: reason=" + reason + ", releaseType=" + releaseType);
sendMessage(DataConnection.EVENT_DISCONNECT_ALL,
new DisconnectParams(null, reason, releaseType, onCompletedMsg));
}
@@ -2794,6 +2857,12 @@
return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}";
}
+ /** Check if the device is connected to NR 5G Non-Standalone network. */
+ private boolean isNRConnected() {
+ return mPhone.getServiceState().getNrStatus()
+ == NetworkRegistrationState.NR_STATUS_CONNECTED;
+ }
+
private void dumpToLog() {
dump(null, new PrintWriter(new StringWriter(0)) {
@Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index 72be25e..173f934 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -60,13 +60,14 @@
* Cellular data service, IWLAN data service).
*/
public class DataServiceManager {
- private static final String TAG = DataServiceManager.class.getSimpleName();
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
static final String DATA_CALL_RESPONSE = "data_call_response";
private final Phone mPhone;
+ private final String mTag;
+
private final CarrierConfigManager mCarrierConfigManager;
private final AppOpsManager mAppOps;
private final IPackageManager mPackageManager;
@@ -228,9 +229,11 @@
* @param phone The phone object
* @param transportType The transport type. Must be a
* {@link AccessNetworkConstants.TransportType}.
+ * @param tagSuffix Logging tag suffix
*/
- public DataServiceManager(Phone phone, int transportType) {
+ public DataServiceManager(Phone phone, int transportType, String tagSuffix) {
mPhone = phone;
+ mTag = "DSM" + tagSuffix;
mTransportType = transportType;
mBound = false;
mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
@@ -580,11 +583,11 @@
}
private void log(String s) {
- Rlog.d(TAG, s);
+ Rlog.d(mTag, s);
}
private void loge(String s) {
- Rlog.e(TAG, s);
+ Rlog.e(mTag, s);
}
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index f1790a3..391e264 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -121,9 +121,9 @@
}
public static DcController makeDcc(Phone phone, DcTracker dct,
- DataServiceManager dataServiceManager, Handler handler) {
- DcController dcc = new DcController("Dcc", phone, dct, dataServiceManager, handler);
- return dcc;
+ DataServiceManager dataServiceManager, Handler handler,
+ String tagSuffix) {
+ return new DcController("Dcc" + tagSuffix, phone, dct, dataServiceManager, handler);
}
void dispose() {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index db965f9..e900617 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -17,6 +17,9 @@
package com.android.internal.telephony.dataconnection;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE_CA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
import static com.android.internal.telephony.RILConstants.DATA_PROFILE_DEFAULT;
import static com.android.internal.telephony.RILConstants.DATA_PROFILE_INVALID;
@@ -75,6 +78,7 @@
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.data.ApnSetting;
+import android.telephony.data.ApnSetting.ApnType;
import android.telephony.data.DataProfile;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
@@ -92,6 +96,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneSwitcher;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.SettingsObserver;
import com.android.internal.telephony.TelephonyIntents;
@@ -129,6 +134,25 @@
private static final boolean VDBG_STALL = false; // STOPSHIP if true
private static final boolean RADIO_TESTS = false;
+ /**
+ * These constants exist here because ConnectivityManager.TYPE_xxx constants are deprecated and
+ * new ones will not be added (for instance NETWORK_TYPE_MCX below).
+ * For backward compatibility, the values here need to be the same as
+ * ConnectivityManager.TYPE_xxx because networkAttributes overlay uses those values.
+ */
+ private static final int NETWORK_TYPE_DEFAULT = ConnectivityManager.TYPE_MOBILE;
+ private static final int NETWORK_TYPE_MMS = ConnectivityManager.TYPE_MOBILE_MMS;
+ private static final int NETWORK_TYPE_SUPL = ConnectivityManager.TYPE_MOBILE_SUPL;
+ private static final int NETWORK_TYPE_DUN = ConnectivityManager.TYPE_MOBILE_DUN;
+ private static final int NETWORK_TYPE_HIPRI = ConnectivityManager.TYPE_MOBILE_HIPRI;
+ private static final int NETWORK_TYPE_FOTA = ConnectivityManager.TYPE_MOBILE_FOTA;
+ private static final int NETWORK_TYPE_IMS = ConnectivityManager.TYPE_MOBILE_IMS;
+ private static final int NETWORK_TYPE_CBS = ConnectivityManager.TYPE_MOBILE_CBS;
+ private static final int NETWORK_TYPE_IA = ConnectivityManager.TYPE_MOBILE_IA;
+ private static final int NETWORK_TYPE_EMERGENCY = ConnectivityManager.TYPE_MOBILE_EMERGENCY;
+ private static final int NETWORK_TYPE_MCX = 1001; // far away from ConnectivityManager.TYPE_xxx
+ // constants as MCX isn't defined there.
+
@IntDef(value = {
REQUEST_TYPE_NORMAL,
REQUEST_TYPE_HANDOVER,
@@ -559,7 +583,7 @@
// When false we will not auto attach and manually attaching is required.
private boolean mAutoAttachOnCreationConfig = false;
- private AtomicBoolean mAutoAttachOnCreation = new AtomicBoolean(false);
+ private AtomicBoolean mAutoAttachEnabled = new AtomicBoolean(false);
// State of screen
// (TODO: Reconsider tying directly to screen, maybe this is
@@ -651,14 +675,14 @@
.createForSubscriptionId(phone.getSubId());
// The 'C' in tag indicates cellular, and 'I' indicates IWLAN. This is to distinguish
// between two DcTrackers, one for each.
- String tag = "DCT-" + ((transportType == TransportType.WWAN) ? "C" : "I");
+ String tagSuffix = "-" + ((transportType == TransportType.WWAN) ? "C" : "I");
if (mTelephonyManager.getPhoneCount() > 1) {
- tag += "-" + mPhone.getPhoneId();
+ tagSuffix += "-" + mPhone.getPhoneId();
}
- mLogTag = tag;
+ mLogTag = "DCT" + tagSuffix;
mTransportType = transportType;
- mDataServiceManager = new DataServiceManager(phone, transportType);
+ mDataServiceManager = new DataServiceManager(phone, transportType, tagSuffix);
mResolver = mPhone.getContext().getContentResolver();
mUiccController = UiccController.getInstance();
@@ -683,7 +707,7 @@
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
- mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
+ mAutoAttachEnabled.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
@@ -691,7 +715,7 @@
HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
dcHandlerThread.start();
Handler dcHandler = new Handler(dcHandlerThread.getLooper());
- mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
+ mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler, tagSuffix);
mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
mDataConnectionTracker = this;
@@ -974,39 +998,42 @@
ApnContext apnContext;
switch (networkConfig.type) {
- case ConnectivityManager.TYPE_MOBILE:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_MMS:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_SUPL:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_DUN:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_HIPRI:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_FOTA:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_IMS:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_CBS:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_IA:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
- break;
- case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
- apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
- break;
- default:
- log("initApnContexts: skipping unknown type=" + networkConfig.type);
- continue;
+ case NETWORK_TYPE_DEFAULT:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_DEFAULT, networkConfig);
+ break;
+ case NETWORK_TYPE_MMS:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_MMS, networkConfig);
+ break;
+ case NETWORK_TYPE_SUPL:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_SUPL, networkConfig);
+ break;
+ case NETWORK_TYPE_DUN:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_DUN, networkConfig);
+ break;
+ case NETWORK_TYPE_HIPRI:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_HIPRI, networkConfig);
+ break;
+ case NETWORK_TYPE_FOTA:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_FOTA, networkConfig);
+ break;
+ case NETWORK_TYPE_IMS:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_IMS, networkConfig);
+ break;
+ case NETWORK_TYPE_CBS:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_CBS, networkConfig);
+ break;
+ case NETWORK_TYPE_IA:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_IA, networkConfig);
+ break;
+ case NETWORK_TYPE_EMERGENCY:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_EMERGENCY, networkConfig);
+ break;
+ case NETWORK_TYPE_MCX:
+ apnContext = addApnContext(PhoneConstants.APN_TYPE_MCX, networkConfig);
+ break;
+ default:
+ log("initApnContexts: skipping unknown type=" + networkConfig.type);
+ continue;
}
log("initApnContexts: apnContext=" + apnContext);
}
@@ -1178,7 +1205,7 @@
mPhone.notifyDataConnection();
}
if (mAutoAttachOnCreationConfig) {
- mAutoAttachOnCreation.set(true);
+ mAutoAttachEnabled.set(true);
}
setupDataOnConnectableApns(Phone.REASON_DATA_ATTACHED, RetryFailures.ALWAYS);
}
@@ -1277,7 +1304,7 @@
reasons.add(DataDisallowedReasonType.IN_ECBM);
}
- if (!(attachedState || mAutoAttachOnCreation.get())) {
+ if (!(attachedState || mAutoAttachEnabled.get())) {
reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
}
if (!recordsLoaded) {
@@ -2152,8 +2179,8 @@
}
}
- public boolean getAutoAttachOnCreation() {
- return mAutoAttachOnCreation.get();
+ public boolean getAutoAttachEnabled() {
+ return mAutoAttachEnabled.get();
}
private void onRecordsLoadedOrSubIdChanged() {
@@ -2175,7 +2202,7 @@
mAllApnSettings.clear();
mAutoAttachOnCreationConfig = false;
// Clear auto attach as modem is expected to do a new attach once SIM is ready
- mAutoAttachOnCreation.set(false);
+ mAutoAttachEnabled.set(false);
mOnSubscriptionsChangedListener.mPreviousSubId.set(
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
// In no-sim case, we should still send the emergency APN to the modem, if there is any.
@@ -2259,7 +2286,7 @@
}
private void addRequestNetworkCompleteMsg(Message onCompleteMsg,
- @ApnSetting.ApnType int apnType) {
+ @ApnType int apnType) {
if (onCompleteMsg != null) {
List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType);
if (messageList == null) messageList = new ArrayList<>();
@@ -2279,13 +2306,13 @@
message.sendToTarget();
}
- public void enableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType,
+ public void enableApn(@ApnType int apnType, @RequestNetworkType int requestType,
Message onCompleteMsg) {
sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType,
onCompleteMsg));
}
- private void onEnableApn(@ApnSetting.ApnType int apnType, @RequestNetworkType int requestType,
+ private void onEnableApn(@ApnType int apnType, @RequestNetworkType int requestType,
Message onCompleteMsg) {
ApnContext apnContext = mApnContextsByType.get(apnType);
if (apnContext == null) {
@@ -2359,11 +2386,11 @@
}
}
- public void disableApn(@ApnSetting.ApnType int apnType, @ReleaseNetworkType int releaseType) {
+ public void disableApn(@ApnType int apnType, @ReleaseNetworkType int releaseType) {
sendMessage(obtainMessage(DctConstants.EVENT_DISABLE_APN, apnType, releaseType));
}
- private void onDisableApn(@ApnSetting.ApnType int apnType,
+ private void onDisableApn(@ApnType int apnType,
@ReleaseNetworkType int releaseType) {
ApnContext apnContext = mApnContextsByType.get(apnType);
if (apnContext == null) {
@@ -2637,7 +2664,7 @@
mReregisterOnReconnectFailure = false;
// Clear auto attach as modem is expected to do a new attach
- mAutoAttachOnCreation.set(false);
+ mAutoAttachEnabled.set(false);
if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
@@ -2649,7 +2676,7 @@
}
}
- private void completeConnection(ApnContext apnContext) {
+ private void completeConnection(ApnContext apnContext, @RequestNetworkType int type) {
if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
@@ -2676,7 +2703,10 @@
mProvisioningSpinner));
}
- mPhone.notifyDataConnection(apnContext.getApnType());
+ // Notify data is connected except for handover case.
+ if (type != REQUEST_TYPE_HANDOVER) {
+ mPhone.notifyDataConnection(apnContext.getApnType());
+ }
startNetStatPoll();
startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
}
@@ -2780,7 +2810,7 @@
// Complete the connection normally notifying the world we're connected.
// We do this if this isn't a special provisioning apn or if we've been
// told its time to provision.
- completeConnection(apnContext);
+ completeConnection(apnContext, requestType);
} else {
// This is a provisioning APN that we're reporting as connected. Later
// when the user desires to upgrade this to a "default" connection,
@@ -3843,11 +3873,34 @@
log("update(): Active DDS, register for all events now!");
onUpdateIcc();
- mAutoAttachOnCreation.set(false);
+ updateAutoAttachOnCreation();
mPhone.updateCurrentCarrierInProvider();
}
+ /**
+ * For non DDS phone, mAutoAttachEnabled should be true because it may be detached
+ * automatically from network only because it's idle for too long. In this case, we should
+ * try setting up data call even if it's not attached for 2G or 3G networks. And doing so will
+ * trigger PS attach if possible.
+ */
+ public void updateAutoAttachOnCreation() {
+ PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
+ ServiceState serviceState = mPhone.getServiceState();
+ if (PhoneSwitcher.getInstance() == null || serviceState == null) {
+ mAutoAttachEnabled.set(false);
+ return;
+ }
+
+ // If it's non DDS phone, and voice is registered on 2G or 3G network, we set
+ // mAutoAttachEnabled to true.
+ mAutoAttachEnabled.set(mPhone.getPhoneId() != phoneSwitcher.getPreferredDataPhoneId()
+ && serviceState.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
+ && serviceState.getVoiceNetworkType() != NETWORK_TYPE_LTE
+ && serviceState.getVoiceNetworkType() != NETWORK_TYPE_LTE_CA
+ && serviceState.getVoiceNetworkType() != NETWORK_TYPE_NR);
+ }
+
private void notifyAllDataDisconnected() {
sEnableFailFastRefCounter = 0;
mFailFast = false;
@@ -3928,7 +3981,7 @@
pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
pw.println(" mResolver=" + mResolver);
pw.println(" mReconnectIntent=" + mReconnectIntent);
- pw.println(" mAutoAttachOnCreation=" + mAutoAttachOnCreation.get());
+ pw.println(" mAutoAttachEnabled=" + mAutoAttachEnabled.get());
pw.println(" mIsScreenOn=" + mIsScreenOn);
pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
pw.println(" mDataServiceBound=" + mDataServiceBound);
diff --git a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index cd64d1d..888c16a 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -219,6 +219,12 @@
// apply or revoke requests if our active-ness changes
private void onActivePhoneSwitch() {
+ // For non DDS phone, mAutoAttachOnCreation should be true because it may be detached
+ // automatically from network only because it's idle for too long. In this case, we should
+ // try setting up data call even if it's not attached. And doing so will trigger PS attach
+ // if possible.
+ mPhone.getDcTracker(TransportType.WWAN).updateAutoAttachOnCreation();
+
for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
NetworkRequest networkRequest = entry.getKey();
boolean applied = entry.getValue() != TransportType.INVALID;
@@ -310,11 +316,12 @@
log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType)
+ ", target transport=" + TransportType.toString(targetTransport));
if (mTransportManager.getCurrentTransport(apnType) == targetTransport) {
- log("apnType " + ApnSetting.getApnTypeString(apnType) + " is already on "
+ log("APN type " + ApnSetting.getApnTypeString(apnType) + " is already on "
+ TransportType.toString(targetTransport));
return;
}
+ boolean handoverPending = false;
for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
NetworkRequest networkRequest = entry.getKey();
int currentTransport = entry.getValue();
@@ -326,10 +333,20 @@
EVENT_DATA_HANDOVER_COMPLETED);
onCompleteMsg.getData().putParcelable(
DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST, networkRequest);
+ // TODO: Need to handle the case that the request is there, but there is no actual
+ // data connections established.
requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER,
targetTransport, onCompleteMsg);
+ handoverPending = true;
}
}
+
+ if (!handoverPending) {
+ log("No handover request pending. Update the transport type to "
+ + TransportType.toString(targetTransport) + " for APN type "
+ + ApnSetting.getApnTypeString(apnType));
+ mTransportManager.setCurrentTransport(apnType, targetTransport);
+ }
}
private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success,
diff --git a/src/java/com/android/internal/telephony/TransportManager.java b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
similarity index 97%
rename from src/java/com/android/internal/telephony/TransportManager.java
rename to src/java/com/android/internal/telephony/dataconnection/TransportManager.java
index aea1007..b04835b 100644
--- a/src/java/com/android/internal/telephony/TransportManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -104,7 +105,8 @@
/** The available transports. Must be one or more of AccessNetworkConstants.TransportType.XXX */
private final int[] mAvailableTransports;
- private final AccessNetworksManager mAccessNetworksManager;
+ @Nullable
+ private AccessNetworksManager mAccessNetworksManager;
/**
* Available networks. The key is the APN type, and the value is the available network list in
@@ -138,7 +140,6 @@
public TransportManager(Phone phone) {
mPhone = phone;
- mAccessNetworksManager = new AccessNetworksManager(phone);
mCurrentAvailableNetworks = new ConcurrentHashMap<>();
mCurrentTransports = new ConcurrentHashMap<>();
mHandoverNeededEventRegistrants = new RegistrantList();
@@ -148,6 +149,7 @@
// the IWLAN ones.
mAvailableTransports = new int[]{TransportType.WWAN};
} else {
+ mAccessNetworksManager = new AccessNetworksManager(phone);
mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
EVENT_QUALIFIED_NETWORKS_CHANGED);
mAvailableTransports = new int[]{TransportType.WWAN, TransportType.WLAN};
@@ -333,7 +335,9 @@
pw.println("mCurrentTransports=" + mCurrentTransports);
pw.println("isInLegacy=" + isInLegacyMode());
pw.println("IWLAN operation mode=" + mPhone.mCi.getIwlanOperationMode());
- mAccessNetworksManager.dump(fd, pw, args);
+ if (mAccessNetworksManager != null) {
+ mAccessNetworksManager.dump(fd, pw, args);
+ }
pw.decreaseIndent();
pw.flush();
}
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index 4d1edd0..083f9ee 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -578,6 +578,7 @@
try {
latch.await();
} catch (InterruptedException e) {
+ Log.e(TAG, "blockingGetEuiccInfoFromEuiccService got InterruptedException e: " + e);
Thread.currentThread().interrupt();
}
return resultRef.get();
@@ -1162,7 +1163,8 @@
// Checks whether the caller can manage the active embedded subscription on the SIM with the
// given cardId.
private boolean canManageActiveSubscriptionOnTargetSim(int cardId, String callingPackage) {
- List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+ List<SubscriptionInfo> subInfoList = mSubscriptionManager
+ .getActiveSubscriptionInfoList(/* userVisibleonly */false);
if (subInfoList == null || subInfoList.size() == 0) {
// No active subscription on any SIM.
return false;
@@ -1189,7 +1191,8 @@
// For a single-active subscription phone, checks whether the caller can manage any active
// embedded subscription.
private boolean canManageSubscriptionOnTargetSim(int cardId, String callingPackage) {
- List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
+ List<SubscriptionInfo> subInfoList = mSubscriptionManager
+ .getActiveSubscriptionInfoList(/* userVisibleonly */false);
// No active subscription on any SIM.
if (subInfoList == null || subInfoList.size() == 0) {
return false;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 477b77f..5cb0429 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -3276,6 +3276,7 @@
ImsPhoneConnection oldConnection = findConnection(callInfo.first);
if (oldConnection == null) {
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
+ break;
}
mForegroundCall.detach(oldConnection);
removeConnection(oldConnection);
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java b/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
index 56db4ba..8a97579 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyEventBuilder.java
@@ -19,6 +19,7 @@
import static com.android.internal.telephony.nano.TelephonyProto.ImsCapabilities;
import static com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
import static com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
+import static com.android.internal.telephony.nano.TelephonyProto.SimState;
import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatching;
import static com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierKeyChange;
@@ -30,10 +31,16 @@
import static com.android.internal.telephony.nano.TelephonyProto.TelephonySettings;
import android.os.SystemClock;
+import android.telephony.TelephonyManager;
+import android.util.SparseArray;
-import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.PhoneStatus;
+import com.android.internal.telephony.nano.TelephonyProto.ActiveSubscriptionInfo;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.Type;
+import java.util.Arrays;
+
public class TelephonyEventBuilder {
private final TelephonyEvent mEvent = new TelephonyEvent();
@@ -41,6 +48,11 @@
return mEvent;
}
+ /** The event is not related to any phone id. */
+ public TelephonyEventBuilder() {
+ this(-1 /* phoneId */);
+ }
+
public TelephonyEventBuilder(int phoneId) {
this(SystemClock.elapsedRealtime(), phoneId);
}
@@ -137,12 +149,53 @@
return this;
}
- /**
- * Set and build phone status changed event.
- */
- public TelephonyEventBuilder setPhoneStatusChange(PhoneStatus phoneStatus) {
- mEvent.type = Type.PHONE_STATUS_CHANGED;
- mEvent.phoneStatus = phoneStatus;
+ /** Set and build SIM state change event. */
+ public TelephonyEventBuilder setSimStateChange(SparseArray<Integer> simStates) {
+ int phoneCount = TelephonyManager.getDefault().getPhoneCount();
+ mEvent.simState = new int[phoneCount];
+ Arrays.fill(mEvent.simState, SimState.SIM_STATE_UNKNOWN);
+ mEvent.type = Type.SIM_STATE_CHANGED;
+ for (int i = 0; i < simStates.size(); i++) {
+ int key = simStates.keyAt(i);
+ if (0 <= key && key < phoneCount) {
+ mEvent.simState[key] = simStates.get(key);
+ }
+ }
+ return this;
+ }
+
+ /** Set and build subscription info change event. */
+ public TelephonyEventBuilder setActiveSubscriptionInfoChange(ActiveSubscriptionInfo info) {
+ mEvent.type = Type.ACTIVE_SUBSCRIPTION_INFO_CHANGED;
+ mEvent.activeSubscriptionInfo = info;
+ return this;
+ }
+
+ /** Set and build enabled modem bitmap change event. */
+ public TelephonyEventBuilder setEnabledModemBitmap(int enabledModemBitmap) {
+ mEvent.type = Type.ENABLED_MODEM_CHANGED;
+ mEvent.enabledModemBitmap = enabledModemBitmap;
+ return this;
+ }
+
+ /** Set and build data switch event. */
+ public TelephonyEventBuilder setDataSwitch(DataSwitch dataSwitch) {
+ mEvent.type = TelephonyEvent.Type.DATA_SWITCH;
+ mEvent.dataSwitch = dataSwitch;
+ return this;
+ }
+
+ /** Set and build network validation event. */
+ public TelephonyEventBuilder setNetworkValidate(int networkValidationState) {
+ mEvent.type = TelephonyEvent.Type.NETWORK_VALIDATE;
+ mEvent.networkValidationState = networkValidationState;
+ return this;
+ }
+
+ /** Set and build on demand data switch event. */
+ public TelephonyEventBuilder setOnDemandDataSwitch(OnDemandDataSwitch onDemandDataSwitch) {
+ mEvent.type = TelephonyEvent.Type.ON_DEMAND_DATA_SWITCH;
+ mEvent.onDemandDataSwitch = onDemandDataSwitch;
return this;
}
}
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index fa7f18c..9c103be 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -86,8 +86,9 @@
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatching;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierIdMatchingResult;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.CarrierKeyChange;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.ModemRestart;
-import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.PhoneStatus;
+import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilDeactivateDataCall;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilDeactivateDataCall.DeactivateReason;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.RilSetupDataCall;
@@ -97,6 +98,7 @@
import com.android.internal.telephony.nano.TelephonyProto.TelephonyServiceState;
import com.android.internal.telephony.nano.TelephonyProto.TelephonySettings;
import com.android.internal.telephony.nano.TelephonyProto.TimeInterval;
+import com.android.internal.telephony.protobuf.nano.MessageNano;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -598,7 +600,18 @@
addTelephonyEvent(event);
}
- writePhoneStatusChangedEvent();
+ for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+ final int key = mLastActiveSubscriptionInfos.keyAt(i);
+ TelephonyEvent event = new TelephonyEventBuilder(mStartElapsedTimeMs, key)
+ .setActiveSubscriptionInfoChange(mLastActiveSubscriptionInfos.get(key)).build();
+ addTelephonyEvent(event);
+ }
+
+ addTelephonyEvent(new TelephonyEventBuilder(mStartElapsedTimeMs, -1 /* phoneId */)
+ .setSimStateChange(mLastSimState).build());
+
+ addTelephonyEvent(new TelephonyEventBuilder(mStartElapsedTimeMs, -1 /* phoneId */)
+ .setEnabledModemBitmap(mLastEnabledModemBitmap).build());
}
/**
@@ -655,6 +668,22 @@
log.endTime = new TelephonyProto.Time();
log.endTime.systemTimestampMillis = System.currentTimeMillis();
log.endTime.elapsedTimestampMillis = SystemClock.elapsedRealtime();
+
+ // Log the last active subscription information.
+ int phoneCount = TelephonyManager.getDefault().getPhoneCount();
+ ActiveSubscriptionInfo[] activeSubscriptionInfo =
+ new ActiveSubscriptionInfo[phoneCount];
+ for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+ int key = mLastActiveSubscriptionInfos.keyAt(i);
+ activeSubscriptionInfo[key] = mLastActiveSubscriptionInfos.get(key);
+ }
+ for (int i = 0; i < phoneCount; i++) {
+ if (activeSubscriptionInfo[i] == null) {
+ activeSubscriptionInfo[i] = makeInvalidSubscriptionInfo(i);
+ }
+ }
+ log.lastActiveSubscriptionInfo = activeSubscriptionInfo;
+
return log;
}
@@ -664,19 +693,37 @@
Integer lastSimState = mLastSimState.get(phoneId);
if (lastSimState == null || !lastSimState.equals(state)) {
mLastSimState.put(phoneId, state);
- writePhoneStatusChangedEvent();
+ addTelephonyEvent(new TelephonyEventBuilder().setSimStateChange(mLastSimState).build());
}
}
/** Update active subscription info list. */
public void updateActiveSubscriptionInfoList(List<SubscriptionInfo> subInfos) {
- mLastActiveSubscriptionInfos.clear();
+ List<Integer> inActivePhoneList = new ArrayList<>();
+ for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+ inActivePhoneList.add(mLastActiveSubscriptionInfos.keyAt(i));
+ }
+
for (SubscriptionInfo info : subInfos) {
int phoneId = SubscriptionManager.getPhoneId(info.getSubscriptionId());
+ inActivePhoneList.removeIf(value -> value.equals(phoneId));
ActiveSubscriptionInfo activeSubscriptionInfo = new ActiveSubscriptionInfo();
- activeSubscriptionInfo.isOpportunistic = info.isOpportunistic();
+ activeSubscriptionInfo.slotIndex = phoneId;
+ activeSubscriptionInfo.isOpportunistic = info.isOpportunistic() ? 1 : 0;
activeSubscriptionInfo.carrierId = info.getCarrierId();
- mLastActiveSubscriptionInfos.put(phoneId, activeSubscriptionInfo);
+ if (!MessageNano.messageNanoEquals(
+ mLastActiveSubscriptionInfos.get(phoneId), activeSubscriptionInfo)) {
+ addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+ .setActiveSubscriptionInfoChange(activeSubscriptionInfo).build());
+
+ mLastActiveSubscriptionInfos.put(phoneId, activeSubscriptionInfo);
+ }
+ }
+
+ for (int phoneId : inActivePhoneList) {
+ mLastActiveSubscriptionInfos.remove(phoneId);
+ addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+ .setActiveSubscriptionInfoChange(makeInvalidSubscriptionInfo(phoneId)).build());
}
}
@@ -684,28 +731,16 @@
public void updateEnabledModemBitmap(int enabledModemBitmap) {
if (mLastEnabledModemBitmap == enabledModemBitmap) return;
mLastEnabledModemBitmap = enabledModemBitmap;
- writePhoneStatusChangedEvent();
+ addTelephonyEvent(new TelephonyEventBuilder()
+ .setEnabledModemBitmap(mLastEnabledModemBitmap).build());
}
- /** Write the event of phone status changed. */
- public void writePhoneStatusChangedEvent() {
- int phoneCount = TelephonyManager.getDefault().getPhoneCount();
- PhoneStatus phoneStatus = new PhoneStatus();
- phoneStatus.enabledModemBitmap = mLastEnabledModemBitmap;
- phoneStatus.simState = new int[phoneCount];
- Arrays.fill(phoneStatus.simState, SimState.SIM_STATE_ABSENT);
- for (int i = 0; i < mLastSimState.size(); i++) {
- int phoneId = mLastSimState.keyAt(i);
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- phoneStatus.simState[phoneId] = mLastSimState.get(phoneId);
- }
- }
-
- // Phone status is not associated with any phone id, so set the phone id to -1 for the phone
- // status changed event.
- addTelephonyEvent(new TelephonyEventBuilder(-1 /* phoneId */)
- .setPhoneStatusChange(phoneStatus)
- .build());
+ private static ActiveSubscriptionInfo makeInvalidSubscriptionInfo(int phoneId) {
+ ActiveSubscriptionInfo invalidSubscriptionInfo = new ActiveSubscriptionInfo();
+ invalidSubscriptionInfo.slotIndex = phoneId;
+ invalidSubscriptionInfo.carrierId = -1;
+ invalidSubscriptionInfo.isOpportunistic = -1;
+ return invalidSubscriptionInfo;
}
/**
@@ -1709,6 +1744,32 @@
}
/**
+ * Write network validation event.
+ * @param networkValidationState the network validation state.
+ */
+ public void writeNetworkValidate(int networkValidationState) {
+ addTelephonyEvent(
+ new TelephonyEventBuilder().setNetworkValidate(networkValidationState).build());
+ }
+
+ /**
+ * Write data switch event.
+ * @param dataSwitch the reason and state of data switch.
+ */
+ public void writeDataSwitch(DataSwitch dataSwitch) {
+ addTelephonyEvent(new TelephonyEventBuilder().setDataSwitch(dataSwitch).build());
+ }
+
+ /**
+ * Write on demand data switch event.
+ * @param onDemandDataSwitch the apn and state of on demand data switch.
+ */
+ public void writeOnDemandDataSwitch(OnDemandDataSwitch onDemandDataSwitch) {
+ addTelephonyEvent(
+ new TelephonyEventBuilder().setOnDemandDataSwitch(onDemandDataSwitch).build());
+ }
+
+ /**
* Write phone state changed event
*
* @param phoneId Phone id
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
index 6a57469..2604959 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierResolverTest.java
@@ -177,27 +177,27 @@
mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
waitForMs(200);
assertEquals(CID_ATT, mCarrierResolver.getCarrierId());
- assertEquals(CID_ATT, mCarrierResolver.getPreciseCarrierId());
+ assertEquals(CID_ATT, mCarrierResolver.getSpecificCarrierId());
doReturn(GID_TRACFONE).when(mPhone).getGroupIdLevel1();
mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
waitForMs(200);
assertEquals(CID_TRACFONE, mCarrierResolver.getCarrierId());
- assertEquals(CID_TRACFONE_ATT, mCarrierResolver.getPreciseCarrierId());
+ assertEquals(CID_TRACFONE_ATT, mCarrierResolver.getSpecificCarrierId());
doReturn(MCCMNC_TRACFONE_TMO).when(mTelephonyManager)
.getSimOperatorNumericForPhone(eq(phoneId));
mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
waitForMs(200);
assertEquals(CID_TRACFONE, mCarrierResolver.getCarrierId());
- assertEquals(CID_TRACFONE_TMO, mCarrierResolver.getPreciseCarrierId());
+ assertEquals(CID_TRACFONE_TMO, mCarrierResolver.getSpecificCarrierId());
doReturn(MCCMNC_O2).when(mTelephonyManager)
.getSimOperatorNumericForPhone(eq(phoneId));
mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
waitForMs(200);
assertEquals(CID_O2, mCarrierResolver.getCarrierId());
- assertEquals(CID_O2, mCarrierResolver.getPreciseCarrierId());
+ assertEquals(CID_O2, mCarrierResolver.getSpecificCarrierId());
doReturn(MCCMNC_O2).when(mTelephonyManager)
.getSimOperatorNumericForPhone(eq(phoneId));
@@ -205,7 +205,7 @@
mCarrierResolver.sendEmptyMessage(SIM_LOAD_EVENT);
waitForMs(200);
assertEquals(CID_O2, mCarrierResolver.getCarrierId());
- assertEquals(CID_O2_PREPAID, mCarrierResolver.getPreciseCarrierId());
+ assertEquals(CID_O2_PREPAID, mCarrierResolver.getSpecificCarrierId());
}
@Test
@@ -223,6 +223,7 @@
waitForMs(200);
assertEquals(CID_UNKNOWN, mCarrierResolver.getCarrierId());
assertNull(mCarrierResolver.getCarrierName());
+ assertNull(mCarrierResolver.getCarrierName());
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
index e6e8590..ed7fc1c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityNrTest.java
@@ -45,7 +45,7 @@
// THEN the get method should return correct value
assertThat(cellIdentityNr.getType()).isEqualTo(CellInfo.TYPE_NR);
- assertThat(cellIdentityNr.getChannelNumber()).isEqualTo(NRARFCN);
+ assertThat(cellIdentityNr.getNrarfcn()).isEqualTo(NRARFCN);
assertThat(cellIdentityNr.getPci()).isEqualTo(PCI);
assertThat(cellIdentityNr.getTac()).isEqualTo(TAC);
assertThat(cellIdentityNr.getOperatorAlphaLong()).isEqualTo(ALPHAL);
@@ -95,7 +95,7 @@
// THEN the new object is equal to the old one
assertThat(anotherCellIdentityNr).isEqualTo(anotherCellIdentityNr);
assertThat(anotherCellIdentityNr.getType()).isEqualTo(CellInfo.TYPE_NR);
- assertThat(anotherCellIdentityNr.getChannelNumber()).isEqualTo(NRARFCN);
+ assertThat(anotherCellIdentityNr.getNrarfcn()).isEqualTo(NRARFCN);
assertThat(anotherCellIdentityNr.getPci()).isEqualTo(PCI);
assertThat(anotherCellIdentityNr.getTac()).isEqualTo(TAC);
assertThat(anotherCellIdentityNr.getOperatorAlphaLong()).isEqualTo(ALPHAL);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index 7746bd5..d5f400b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -386,13 +386,14 @@
assertTrue(mDataAllowed[0]);
// Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated.
- mPhoneSwitcher.setOpportunisticDataSubscription(2);
+ mPhoneSwitcher.trySetPreferredSubscription(2, false, null);
waitABit();
assertFalse(mDataAllowed[0]);
assertTrue(mDataAllowed[1]);
// Unset preferred sub should make default data sub (phone 0 / sub 1) activated again.
- mPhoneSwitcher.unsetOpportunisticDataSubscription();
+ mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ false, null);
waitABit();
assertTrue(mDataAllowed[0]);
assertFalse(mDataAllowed[1]);
@@ -441,7 +442,7 @@
assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
// Set sub 2 as preferred sub should make phone 1 preferredDataModem
- mPhoneSwitcher.setOpportunisticDataSubscription(2);
+ mPhoneSwitcher.trySetPreferredSubscription(2, false, null);
waitABit();
verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
@@ -454,7 +455,8 @@
clearInvocations(mActivePhoneSwitchHandler);
// Unset preferred sub should make phone0 preferredDataModem again.
- mPhoneSwitcher.unsetOpportunisticDataSubscription();
+ mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ false, null);
waitABit();
verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
@@ -640,7 +642,13 @@
doReturn(mDefaultDataSub).when(mSubscriptionController).getDefaultDataSubId();
doAnswer(invocation -> {
int phoneId = (int) invocation.getArguments()[0];
- return mSlotIndexToSubId[phoneId][0];
+ if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
+ return mSlotIndexToSubId[0][0];
+ } else {
+ return mSlotIndexToSubId[phoneId][0];
+ }
}).when(mSubscriptionController).getSubIdUsingPhoneId(anyInt());
doAnswer(invocation -> {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index dfc2a0b..206ebea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -151,6 +151,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
public class RILTest extends TelephonyTest {
@@ -212,7 +213,7 @@
private static final int RSSI_ASU = 24;
private static final int SYSTEM_ID = 65533;
private static final int TAC = 65535;
- private static final int TIME_ADVANCE = 4;
+ private static final int TIMING_ADVANCE = 4;
private static final long TIMESTAMP = 215924934;
private static final int UARFCN = 690;
private static final int TYPE_CDMA = 2;
@@ -1099,7 +1100,7 @@
lte.signalStrengthLte.rsrq = -RSRQ;
lte.signalStrengthLte.rssnr = RSSNR;
lte.signalStrengthLte.cqi = CQI;
- lte.signalStrengthLte.timingAdvance = TIME_ADVANCE;
+ lte.signalStrengthLte.timingAdvance = TIMING_ADVANCE;
android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
record.cellInfoType = TYPE_LTE;
record.registered = false;
@@ -1120,7 +1121,7 @@
CellIdentityLte cil = new CellIdentityLte(CI, PCI, TAC, EARFCN, Integer.MAX_VALUE, MCC_STR,
MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
CellSignalStrengthLte css = new CellSignalStrengthLte(
- RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+ RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
expected.setCellIdentity(cil);
expected.setCellSignalStrength(css);
expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1140,7 +1141,7 @@
cellinfo.cellIdentityGsm.mnc = MNC_STR;
cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
- cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
+ cellinfo.signalStrengthGsm.timingAdvance = TIMING_ADVANCE;
android.hardware.radio.V1_0.CellInfo record = new android.hardware.radio.V1_0.CellInfo();
record.cellInfoType = TYPE_GSM;
record.registered = false;
@@ -1161,7 +1162,7 @@
CellIdentityGsm ci = new CellIdentityGsm(
LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
- RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+ RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1305,7 +1306,7 @@
CellIdentityLte cil = new CellIdentityLte(
CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
CellSignalStrengthLte css = new CellSignalStrengthLte(
- RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+ RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
expected.setCellIdentity(cil);
expected.setCellSignalStrength(css);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1326,7 +1327,7 @@
CellIdentityLte cil = new CellIdentityLte(CI, PCI, TAC, EARFCN, BANDWIDTH, MCC_STR, MNC_STR,
EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
CellSignalStrengthLte css = new CellSignalStrengthLte(
- RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+ RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
expected.setCellIdentity(cil);
expected.setCellSignalStrength(css);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1349,7 +1350,7 @@
CellIdentityLte cil = new CellIdentityLte(
CI, PCI, TAC, EARFCN, BANDWIDTH, null, null, ALPHA_LONG, ALPHA_SHORT);
CellSignalStrengthLte css = new CellSignalStrengthLte(
- RSSI, RSRP, RSRQ, RSSNR, CQI, TIME_ADVANCE);
+ RSSI, RSRP, RSRQ, RSSNR, CQI, TIMING_ADVANCE);
expected.setCellIdentity(cil);
expected.setCellSignalStrength(css);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1369,7 +1370,7 @@
CellIdentityGsm ci = new CellIdentityGsm(
LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
- RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+ RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1390,7 +1391,7 @@
CellIdentityGsm ci = new CellIdentityGsm(
LAC, CID, ARFCN, BSIC, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
- RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+ RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1413,7 +1414,7 @@
CellIdentityGsm ci = new CellIdentityGsm(
LAC, CID, ARFCN, BSIC, null, null, ALPHA_LONG, ALPHA_SHORT);
CellSignalStrengthGsm cs = new CellSignalStrengthGsm(
- RSSI, BIT_ERROR_RATE, TIME_ADVANCE);
+ RSSI, BIT_ERROR_RATE, TIMING_ADVANCE);
expected.setCellIdentity(ci);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
expected.setCellSignalStrength(cs);
@@ -1603,24 +1604,89 @@
assertEquals("100:foo", request.getWorkSourceClientId());
}
- private ArrayList<CellInfo> getCellInfoListForLTE(
- String mcc, String mnc, String alphaLong, String alphaShort) {
- android.hardware.radio.V1_2.CellInfoLte lte = new android.hardware.radio.V1_2.CellInfoLte();
+ @Test
+ public void testCellInfoTimestamp_1_4() {
+ ArrayList<android.hardware.radio.V1_4.CellInfo> records =
+ new ArrayList<android.hardware.radio.V1_4.CellInfo>();
+
+ for (int i = 0; i < 5 /* arbitrary */; i++) {
+ android.hardware.radio.V1_4.CellInfo record =
+ new android.hardware.radio.V1_4.CellInfo();
+ record.info = new android.hardware.radio.V1_4.CellInfo.Info();
+ record.info.lte(new android.hardware.radio.V1_4.CellInfoLte());
+ initializeCellInfoLte_1_2(record.info.lte().base);
+ record.info.lte().base.cellIdentityLte.base.ci += i; // make them marginally unique
+
+ records.add(record);
+ }
+ List<CellInfo> cil = RIL.convertHalCellInfoList_1_4(records);
+
+ // Check that all timestamps are set to a valid number and are equal
+ final long ts = cil.get(0).getTimeStamp();
+ for (CellInfo ci : cil) {
+ assertTrue(ci.getTimeStamp() > 0 && ci.getTimeStamp() != Long.MAX_VALUE);
+ assertEquals(ci.getTimeStamp(), ts);
+ }
+ }
+
+ @Test
+ public void testCellInfoTimestamp_1_2() {
+ ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+ new ArrayList<android.hardware.radio.V1_2.CellInfo>();
+
+ for (int i = 0; i < 5 /* arbitrary */; i++) {
+ android.hardware.radio.V1_2.CellInfo record =
+ new android.hardware.radio.V1_2.CellInfo();
+ record.cellInfoType = TYPE_LTE;
+ record.timeStamp = Long.MAX_VALUE;
+ record.registered = false;
+ record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
+ record.lte.add(new android.hardware.radio.V1_2.CellInfoLte());
+ initializeCellInfoLte_1_2(record.lte.get(0));
+ record.lte.get(0).cellIdentityLte.base.ci += i; // make them marginally unique
+
+ records.add(record);
+ }
+ List<CellInfo> cil = RIL.convertHalCellInfoList_1_2(records);
+
+ // Check that all timestamps are set to a valid number and are equal
+ final long ts = cil.get(0).getTimeStamp();
+ for (CellInfo ci : cil) {
+ assertTrue(ci.getTimeStamp() > 0 && ci.getTimeStamp() != Long.MAX_VALUE);
+ assertEquals(ci.getTimeStamp(), ts);
+ }
+ }
+
+ private static void initializeCellInfoLte_1_2(android.hardware.radio.V1_2.CellInfoLte lte) {
lte.cellIdentityLte.base.ci = CI;
lte.cellIdentityLte.base.pci = PCI;
lte.cellIdentityLte.base.tac = TAC;
lte.cellIdentityLte.base.earfcn = EARFCN;
lte.cellIdentityLte.bandwidth = BANDWIDTH;
- lte.cellIdentityLte.base.mcc = mcc;
- lte.cellIdentityLte.base.mnc = mnc;
- lte.cellIdentityLte.operatorNames.alphaLong = alphaLong;
- lte.cellIdentityLte.operatorNames.alphaShort = alphaShort;
lte.signalStrengthLte.signalStrength = RSSI_ASU;
lte.signalStrengthLte.rsrp = -RSRP;
lte.signalStrengthLte.rsrq = -RSRQ;
lte.signalStrengthLte.rssnr = RSSNR;
lte.signalStrengthLte.cqi = CQI;
- lte.signalStrengthLte.timingAdvance = TIME_ADVANCE;
+ lte.signalStrengthLte.timingAdvance = TIMING_ADVANCE;
+
+ lte.cellIdentityLte.operatorNames.alphaLong = ALPHA_LONG;
+ lte.cellIdentityLte.operatorNames.alphaShort = ALPHA_SHORT;
+ lte.cellIdentityLte.base.mcc = MCC_STR;
+ lte.cellIdentityLte.base.mnc = MNC_STR;
+ }
+
+ private ArrayList<CellInfo> getCellInfoListForLTE(
+ String mcc, String mnc, String alphaLong, String alphaShort) {
+ android.hardware.radio.V1_2.CellInfoLte lte = new android.hardware.radio.V1_2.CellInfoLte();
+
+ initializeCellInfoLte_1_2(lte);
+ // Override the defaults for test-specific purposes
+ lte.cellIdentityLte.operatorNames.alphaLong = alphaLong;
+ lte.cellIdentityLte.operatorNames.alphaShort = alphaShort;
+ lte.cellIdentityLte.base.mcc = mcc;
+ lte.cellIdentityLte.base.mnc = mnc;
+
android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
record.cellInfoType = TYPE_LTE;
record.registered = false;
@@ -1648,7 +1714,7 @@
cellinfo.cellIdentityGsm.operatorNames.alphaShort = alphaShort;
cellinfo.signalStrengthGsm.signalStrength = RSSI_ASU;
cellinfo.signalStrengthGsm.bitErrorRate = BIT_ERROR_RATE;
- cellinfo.signalStrengthGsm.timingAdvance = TIME_ADVANCE;
+ cellinfo.signalStrengthGsm.timingAdvance = TIMING_ADVANCE;
android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
record.cellInfoType = TYPE_GSM;
record.registered = false;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 38ebf4e..0a683b0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -148,7 +148,7 @@
testInsertSim();
/* Get SUB ID */
- int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+ int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
@@ -189,7 +189,7 @@
testInsertSim();
/* Get SUB ID */
- int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+ int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
@@ -300,7 +300,7 @@
@SmallTest
public void testMigrateImsSettings() throws Exception {
testInsertSim();
- int[] subIds = mSubscriptionControllerUT.getActiveSubIdList();
+ int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIds != null && subIds.length != 0);
int subID = subIds[0];
@@ -554,7 +554,7 @@
/* insert some sims */
testInsertMultipleRemoteSims();
assertEquals(1, mSubscriptionControllerUT.getDefaultSubId());
- int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList();
+ int[] subIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(subIdsArray.length > 0);
int len = subIdsArray.length;
@@ -564,7 +564,7 @@
assertTrue(result > 0);
// now check the number of subs left. should be one less than earlier
- int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList();
+ int[] newSubIdsArray = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
assertTrue(newSubIdsArray.length > 0);
assertEquals(len - 1, newSubIdsArray.length);
@@ -802,8 +802,8 @@
mSubscriptionControllerUT.addSubInfoRecord("123", 1); // sub 1
mSubscriptionControllerUT.addSubInfoRecord("456", 0); // sub 2
+ int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
// Make sure the return sub ids are sorted by slot index
- assertTrue("active sub ids = " + mSubscriptionControllerUT.getActiveSubIdList(),
- Arrays.equals(mSubscriptionControllerUT.getActiveSubIdList(), new int[]{2, 1}));
+ assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index c804cd0..52a0cb1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -151,7 +151,8 @@
((MockContentResolver) mContext.getContentResolver()).addProvider(
SubscriptionManager.CONTENT_URI.getAuthority(),
new FakeSubscriptionContentProvider());
- doReturn(new int[]{}).when(mSubscriptionController).getActiveSubIdList();
+ doReturn(new int[]{}).when(mSubscriptionController)
+ .getActiveSubIdList(/*visibleOnly*/false);
mIccRecord = mUiccProfile.getIccRecords();
mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG);
@@ -170,7 +171,8 @@
public void testSimAbsent() throws Exception {
doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
.getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
- doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getActiveSubIdList();
+ doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController)
+ .getActiveSubIdList(/*visibleOnly*/false);
mUpdater.updateInternalIccState(
IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 35bab98..b708b1e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -15,8 +15,8 @@
*/
package com.android.internal.telephony;
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE;
-import static android.telephony.PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE;
import static android.telephony.PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED;
import static org.junit.Assert.assertEquals;
@@ -44,7 +44,7 @@
private PhoneStateListener mPhoneStateListener;
private TelephonyRegistry mTelephonyRegistry;
private PhoneCapability mPhoneCapability;
- private int mPreferredSubId;
+ private int mActiveSubId;
private int mSrvccState = -1;
public class PhoneStateListenerWrapper extends PhoneStateListener {
@@ -60,8 +60,8 @@
setReady(true);
}
@Override
- public void onPreferredDataSubIdChanged(int preferredSubId) {
- mPreferredSubId = preferredSubId;
+ public void onActiveDataSubscriptionIdChanged(int activeSubId) {
+ mActiveSubId = activeSubId;
setReady(true);
}
}
@@ -121,23 +121,23 @@
@Test @SmallTest
- public void testPreferredDataSubChanged() {
+ public void testActiveDataSubChanged() {
// mTelephonyRegistry.listen with notifyNow = true should trigger callback immediately.
setReady(false);
- int preferredSubId = 0;
- mTelephonyRegistry.notifyPreferredDataSubIdChanged(preferredSubId);
+ int activeSubId = 0;
+ mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
mTelephonyRegistry.listen(mContext.getOpPackageName(),
mPhoneStateListener.callback,
- LISTEN_PREFERRED_DATA_SUBID_CHANGE, true);
+ LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE, true);
waitUntilReady();
- assertEquals(preferredSubId, mPreferredSubId);
+ assertEquals(activeSubId, mActiveSubId);
// notifyPhoneCapabilityChanged with a new capability. Callback should be triggered.
setReady(false);
- mPreferredSubId = 1;
- mTelephonyRegistry.notifyPreferredDataSubIdChanged(preferredSubId);
+ mActiveSubId = 1;
+ mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
waitUntilReady();
- assertEquals(preferredSubId, mPreferredSubId);
+ assertEquals(activeSubId, mActiveSubId);
}
/**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index 6289e31..9aafb25 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -254,8 +254,8 @@
public void onLooperPrepared() {
Handler h = new Handler();
- DataServiceManager manager = new DataServiceManager(mPhone, TransportType.WWAN);
- mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h);
+ DataServiceManager manager = new DataServiceManager(mPhone, TransportType.WWAN, "");
+ mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h, "");
mDcc.start();
mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, manager,
mDcTesterFailBringUpAll, mDcc);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
index 27d1839..b7b49fd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
@@ -85,7 +85,7 @@
@Override
public void onLooperPrepared() {
mHandler = new Handler();
- mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, mHandler);
+ mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, mHandler, "");
mDcc.start();
setReady(true);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 29fc9fa..e220d30 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -878,10 +878,10 @@
verifyDataConnected(FAKE_APN1);
- assertTrue(mDct.getAutoAttachOnCreation());
+ assertTrue(mDct.getAutoAttachEnabled());
mDct.update();
// The auto attach flag should be reset after update
- assertFalse(mDct.getAutoAttachOnCreation());
+ assertFalse(mDct.getAutoAttachEnabled());
verify(mSST, times(1)).registerForDataConnectionDetached(eq(TransportType.WWAN), eq(mDct),
intArgumentCaptor.capture(), eq(null));
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 e14931c..a4b3b58 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -983,7 +983,7 @@
false, "", false, false, 0, 0, 0);
when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
hasPrivileges);
- when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
+ when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
Collections.singletonList(subInfo));
}
@@ -1011,7 +1011,7 @@
when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
hasPrivileges);
ArrayList<SubscriptionInfo> subInfos = new ArrayList<>(Arrays.asList(subInfo1, subInfo2));
- when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subInfos);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
}
private void prepareOperationSubscription(boolean hasPrivileges) throws Exception {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
index dff75b0..294c5bb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -61,10 +61,14 @@
private static final boolean VT_IMS_ENABLE_DEFAULT_VAL = true;
private static final boolean WFC_IMS_EDITABLE_VAL = true;
private static final boolean WFC_IMS_NOT_EDITABLE_VAL = false;
+ private static final boolean WFC_IMS_ROAMING_EDITABLE_VAL = true;
+ private static final boolean WFC_IMS_ROAMING_NOT_EDITABLE_VAL = false;
private static final int WFC_IMS_MODE_DEFAULT_VAL =
ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL =
ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED;
+ private static final boolean WFC_USE_HOME_MODE_FOR_ROAMING_VAL = true;
+ private static final boolean WFC_NOT_USE_HOME_MODE_FOR_ROAMING_VAL = false;
PersistableBundle mBundle;
@Mock IBinder mBinder;
@@ -107,6 +111,8 @@
ENHANCED_4G_MODE_EDITABLE);
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
WFC_IMS_EDITABLE_VAL);
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
+ WFC_IMS_ROAMING_EDITABLE_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL,
WFC_IMS_ENABLE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL,
@@ -118,6 +124,9 @@
mBundle.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL,
ENHANCED_4G_MODE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, true);
+ mBundle.putBoolean(
+ CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
+ WFC_NOT_USE_HOME_MODE_FOR_ROAMING_VAL);
}
@Test @SmallTest
@@ -653,6 +662,98 @@
eq(WFC_IMS_MODE_DEFAULT_VAL));
}
+ /**
+ * Tests the operation of getWfcMode when the configuration to use the home network mode when
+ * roaming for WFC is false. First, it checks that the user setting for WFC_IMS_ROAMING_MODE is
+ * returned when WFC roaming is set to editable. Then, it switches the WFC roaming mode to not
+ * editable and ensures that the default WFC roaming mode is returned.
+ *
+ * Preconditions:
+ * - CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = false
+ */
+ @Test @SmallTest
+ public void getWfcMode_useWfcHomeModeConfigFalse_shouldUseWfcRoamingMode() {
+ // Set some values that are different than the defaults for WFC mode.
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+
+ ImsManager imsManager = getImsManagerAndInitProvisionedValues();
+
+ // Check that use the WFC roaming network mode.
+ assertEquals(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED,
+ imsManager.getWfcMode(true));
+ verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+
+ // Set WFC roaming network mode to not editable.
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL,
+ WFC_IMS_ROAMING_NOT_EDITABLE_VAL);
+
+ // Check that use the default WFC roaming network mode.
+ assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
+ verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+ }
+
+ /**
+ * Tests the operation of getWfcMode when the configuration to use the home network mode when
+ * roaming for WFC is true independent of whether or not the WFC roaming mode is editable.
+ *
+ * Preconditions:
+ * - CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = true
+ */
+ @Test @SmallTest
+ public void getWfcMode_useWfcHomeModeConfigTrue_shouldUseWfcHomeMode() {
+ // Set some values that are different than the defaults for WFC mode.
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+
+ // Set to use WFC home network mode in roaming network.
+ mBundle.putBoolean(
+ CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
+ WFC_USE_HOME_MODE_FOR_ROAMING_VAL);
+
+ ImsManager imsManager = getImsManagerAndInitProvisionedValues();
+
+ // Check that use the WFC home network mode.
+ assertEquals(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY, imsManager.getWfcMode(true));
+ verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+
+ // Set WFC home network mode to not editable.
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
+ WFC_IMS_NOT_EDITABLE_VAL);
+
+ // Check that use the default WFC home network mode.
+ assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
+ verify(mSubscriptionController, times(1)).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+ }
+
private ImsManager getImsManagerAndInitProvisionedValues() {
when(mImsConfigImplBaseMock.getConfigInt(anyInt()))
.thenAnswer(invocation -> {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
index 0acb694..26afbe3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/MmTelFeatureConnectionTest.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -193,7 +194,7 @@
// Simulate subscriptions changed, where testSub1 is no longer active
doReturn(createSubscriptionInfoList(new int[] {testSub2, testSub3}))
- .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+ .when(mSubscriptionManager).getActiveSubscriptionInfoList(anyBoolean());
mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
// verify that the subscription changed listener is not removed, since we still have a
@@ -220,7 +221,7 @@
// Simulate subscriptions changed, where testSub1 is no longer active
doReturn(createSubscriptionInfoList(new int[] {testSub2}))
- .when(mSubscriptionManager).getActiveSubscriptionInfoList();
+ .when(mSubscriptionManager).getActiveSubscriptionInfoList(anyBoolean());
mCallbackManagerUT.mSubChangedListener.onSubscriptionsChanged();
assertFalse(mCallbackManagerUT.doesCallbackExist(testCallback1));
// verify that the subscription listener is removed, since the only active callback has been
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
index 411ed1d..2007dca 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionControllerMock.java
@@ -259,7 +259,7 @@
throw new RuntimeException("not implemented");
}
@Override
- public int[] getActiveSubIdList() {
+ public int[] getActiveSubIdList(boolean visibleOnly) {
throw new RuntimeException("not implemented");
}
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
index 984b583..412cc1b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/TelephonyRegistryMock.java
@@ -427,12 +427,12 @@
}
@Override
- public void notifyRadioPowerStateChanged(int state) {
+ public void notifyActiveDataSubIdChanged(int subId) {
throw new RuntimeException("Not implemented");
}
@Override
- public void notifyPreferredDataSubIdChanged(int subId) {
+ public void notifyRadioPowerStateChanged(int state) {
throw new RuntimeException("Not implemented");
}