Merge "Unit Tests for CellInfo Timestamp"
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/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index ee10023..2e5d058 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -71,7 +71,7 @@
CellularNetworkServiceProvider(int slotId) {
super(slotId);
- mPhone = PhoneFactory.getPhone(getSlotId());
+ mPhone = PhoneFactory.getPhone(getSlotIndex());
mHandlerThread = new HandlerThread(CellularNetworkService.class.getSimpleName());
mHandlerThread.start();
@@ -488,13 +488,13 @@
}
@Override
- protected NetworkServiceProvider createNetworkServiceProvider(int slotId) {
- if (DBG) log("Cellular network service created for slot " + slotId);
- if (!SubscriptionManager.isValidSlotIndex(slotId)) {
- loge("Tried to Cellular network service with invalid slotId " + slotId);
+ public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
+ if (DBG) log("Cellular network service created for slot " + slotIndex);
+ if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
+ loge("Tried to Cellular network service with invalid slotId " + slotIndex);
return null;
}
- return new CellularNetworkServiceProvider(slotId);
+ return new CellularNetworkServiceProvider(slotIndex);
}
private void log(String s) {
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/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 05374f1..9b24946 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -2266,6 +2266,13 @@
*/
default void enableModem(boolean enable, Message result) {};
+ /**
+ * Query whether logical modem is enabled or disabled
+ *
+ * @param result a Message to return to the requester
+ */
+ default void getModemStatus(Message result) {};
+
default List<ClientRequestStats> getClientRequestStats() {
return null;
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 6f139f6..7213fca 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();
}
@@ -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/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index c558721..66e4e4f 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -90,7 +90,7 @@
}
@Override
- public void onDeregistered(ImsReasonInfo info) {
+ public void onUnregistered(ImsReasonInfo info) {
Rlog.d(TAG, "onImsDisconnected imsReasonInfo=" + info);
synchronized (mLock) {
mIsRegistered = false;
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 01a78ff..616e9fe 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -22,11 +22,15 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemProperties;
+import android.os.storage.StorageManager;
import android.telephony.PhoneCapability;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.util.Log;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* This class manages phone's configuration which defines the potential capability (static) of the
* phone and its current activated capability (current).
@@ -40,6 +44,8 @@
public static final String SSSS = "";
private static final String LOG_TAG = "PhoneCfgMgr";
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 PhoneConfigurationManager sInstance = null;
private final Context mContext;
@@ -47,6 +53,8 @@
private PhoneCapability mCurrentCapability;
private final RadioConfig mRadioConfig;
private final MainThreadHandler mHandler;
+ private final Phone[] mPhones;
+ private final Map<Integer, Boolean> mPhoneStatusMap;
/**
* Init method to instantiate the object
@@ -75,8 +83,20 @@
mCurrentCapability = mStaticCapability;
mRadioConfig = RadioConfig.getInstance(mContext);
mHandler = new MainThreadHandler();
+ mPhoneStatusMap = new HashMap<>();
notifyCapabilityChanged();
+
+ mPhones = PhoneFactory.getPhones();
+ if (!StorageManager.inCryptKeeperBounce()) {
+ for (Phone phone : mPhones) {
+ phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
+ }
+ } else {
+ for (Phone phone : mPhones) {
+ phone.mCi.registerForOn(mHandler, Phone.EVENT_RADIO_ON, phone);
+ }
+ }
}
/**
@@ -96,9 +116,24 @@
private final class MainThreadHandler extends Handler {
@Override
public void handleMessage(Message msg) {
+ AsyncResult ar;
+ Phone phone = null;
switch (msg.what) {
+ case Phone.EVENT_RADIO_AVAILABLE:
+ case Phone.EVENT_RADIO_ON:
+ log("Received EVENT_RADIO_AVAILABLE/EVENT_RADIO_ON");
+ if (msg.obj instanceof Phone) {
+ phone = (Phone) msg.obj;
+ }
+ if (phone == null) {
+ log("Unable to add phoneStatus to cache. "
+ + "No phone object provided for event " + msg.what);
+ } else {
+ updatePhoneStatus(phone);
+ }
+ break;
case EVENT_SWITCH_DSDS_CONFIG_DONE:
- AsyncResult ar = (AsyncResult) msg.obj;
+ ar = (AsyncResult) msg.obj;
if (ar != null && ar.exception == null) {
int numOfLiveModems = msg.arg1;
setMultiSimProperties(numOfLiveModems);
@@ -106,6 +141,17 @@
log(msg.what + " failure. Not switching multi-sim config." + ar.exception);
}
break;
+ case EVENT_GET_MODEM_STATUS_DONE:
+ ar = (AsyncResult) msg.obj;
+ if (ar != null && ar.exception == null) {
+ int phoneId = msg.arg1;
+ boolean enabled = (boolean) ar.result;
+ //update the cache each time getModemStatus is requested
+ mPhoneStatusMap.put(phoneId, enabled);
+ } else {
+ log(msg.what + " failure. Not updating modem status." + ar.exception);
+ }
+ break;
}
}
}
@@ -123,6 +169,48 @@
return;
}
phone.mCi.enableModem(enable, result);
+ updatePhoneStatus(phone);
+ }
+
+ /**
+ * Get phone status (enabled/disabled)
+ *
+ * @param phone which phone to operate on
+ */
+ public boolean getPhoneStatus(Phone phone) {
+ if (phone == null) {
+ log("getPhonetatus failed phone is null");
+ return false;
+ }
+
+ int phoneId = phone.getPhoneId();
+
+ //use cache if the status has already been updated/queried
+ if (mPhoneStatusMap.containsKey(phoneId)) {
+ return mPhoneStatusMap.get(phoneId);
+ } else {
+ //return false if modem status is not in cache
+ updatePhoneStatus(phone);
+ return false;
+ }
+ }
+
+ /**
+ * method to call RIL getM
+ */
+ private void updatePhoneStatus(Phone phone) {
+ Message callback = Message.obtain(
+ mHandler, EVENT_GET_MODEM_STATUS_DONE, phone.getPhoneId(), 0 /**dummy arg*/);
+ phone.mCi.getModemStatus(callback);
+ }
+
+ /**
+ * Add status of the phone to the status HashMap
+ * @param phoneId
+ * @param status
+ */
+ public void addToPhoneStatusCache(int phoneId, boolean status) {
+ mPhoneStatusMap.put(phoneId, status);
}
/**
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 42b3691..043de1c 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -242,7 +242,8 @@
sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);
- sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext);
+ sPhoneConfigurationManager = PhoneConfigurationManager.init(
+ sContext);
sCellularNetworkValidator = CellularNetworkValidator.make(sContext);
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index e0c4557..d455cb4 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);
@@ -258,6 +297,7 @@
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
netCap.setNetworkSpecifier(new MatchAllNetworkSpecifier());
NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
@@ -294,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: {
@@ -313,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: {
@@ -323,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: {
@@ -332,6 +386,10 @@
onValidationDone(subId, passed);
break;
}
+ case EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK: {
+ removeDefaultNetworkChangeCallback();
+ break;
+ }
}
}
@@ -370,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");
@@ -382,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);
}
}
@@ -493,6 +599,10 @@
activate(phoneId);
}
}
+
+ notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId(
+ mPreferredDataPhoneId));
+
// Notify all registrants.
mActivePhoneRegistrants.notifyRegistrants();
}
@@ -688,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);
}
}
@@ -708,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) {
@@ -750,11 +901,34 @@
? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
}
+ public int getPreferredDataSubscriptionId() {
+ return mPreferredDataSubId;
+ }
+
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 1e7b026..e18e3c1 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -84,6 +84,7 @@
import android.telephony.SmsManager;
import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.PrefNetworkMode;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
@@ -903,6 +904,37 @@
}
@Override
+ public void getModemStatus(Message result) {
+ IRadio radioProxy = getRadioProxy(result);
+ if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
+ if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
+ if (result != null) {
+ AsyncResult.forMessage(result, null,
+ CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+ result.sendToTarget();
+ }
+ return;
+ }
+
+ android.hardware.radio.V1_3.IRadio radioProxy13 =
+ (android.hardware.radio.V1_3.IRadio) radioProxy;
+ if (radioProxy13 != null) {
+ RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
+ mRILDefaultWorkSource);
+
+ if (RILJ_LOGD) {
+ riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+ }
+
+ try {
+ radioProxy13.getModemStackStatus(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getModemStatus", e);
+ }
+ }
+ }
+
+ @Override
public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
Message result) {
@@ -1438,7 +1470,8 @@
if (RILJ_LOGD) {
riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + ",accessNetworkType=" + accessNetworkType + ",isRoaming="
+ + ",accessNetworkType="
+ + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+ isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
+ ",addresses=" + addresses + ",dnses=" + dnses);
}
@@ -1456,7 +1489,8 @@
if (RILJ_LOGD) {
riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
- + ",accessNetworkType=" + accessNetworkType + ",isRoaming="
+ + ",accessNetworkType="
+ + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+ isRoaming + ",allowRoaming=" + allowRoaming + ","
+ dataProfile + ",addresses=" + addresses + ",dnses=" + dnses);
}
@@ -2518,7 +2552,7 @@
}
@Override
- public void setPreferredNetworkType(int networkType , Message result) {
+ public void setPreferredNetworkType(@PrefNetworkMode int networkType , Message result) {
IRadio radioProxy = getRadioProxy(result);
if (radioProxy != null) {
RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
@@ -2542,7 +2576,7 @@
(android.hardware.radio.V1_4.IRadio) radioProxy;
try {
radioProxy14.setPreferredNetworkTypeBitmap(
- rr.mSerial, RadioAccessFamily.getRafFromNetworkType(networkType));
+ rr.mSerial, convertToHalRadioAccessFamily(networkType));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "setPreferredNetworkTypeBitmap", e);
}
@@ -2550,6 +2584,13 @@
}
}
+ private static int convertToHalRadioAccessFamily(@PrefNetworkMode int networkMode) {
+ // android.hardware.radio.V1_0.RadioAccessFamily is one bit shift
+ // from TelephonyManager.NetworkTypeBitMask
+ int networkTypeBitmask = RadioAccessFamily.getRafFromNetworkType(networkMode);
+ return networkTypeBitmask << 1;
+ }
+
@Override
public void getPreferredNetworkType(Message result) {
IRadio radioProxy = getRadioProxy(result);
@@ -5307,6 +5348,8 @@
return "RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA";
case RIL_REQUEST_ENABLE_MODEM:
return "RIL_REQUEST_ENABLE_MODEM";
+ case RIL_REQUEST_GET_MODEM_STATUS:
+ return "RIL_REQUEST_GET_MODEM_STATUS";
default: return "<unknown request>";
}
}
@@ -5615,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));
}
@@ -5632,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;
@@ -5648,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/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index baed262..fd0b011 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -77,6 +77,7 @@
import android.util.LocalLog;
import android.util.Pair;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.StatsLog;
import android.util.TimestampedValue;
@@ -174,10 +175,10 @@
private RegistrantList mVoiceRoamingOffRegistrants = new RegistrantList();
private RegistrantList mDataRoamingOnRegistrants = new RegistrantList();
private RegistrantList mDataRoamingOffRegistrants = new RegistrantList();
- protected RegistrantList mAttachedRegistrants = new RegistrantList();
- protected RegistrantList mDetachedRegistrants = new RegistrantList();
+ protected SparseArray<RegistrantList> mAttachedRegistrants = new SparseArray<>();
+ protected SparseArray<RegistrantList> mDetachedRegistrants = new SparseArray();
private RegistrantList mVoiceRegStateOrRatChangedRegistrants = new RegistrantList();
- private RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
+ private SparseArray<RegistrantList> mDataRegStateOrRatChangedRegistrants = new SparseArray<>();
private RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
private RegistrantList mNetworkDetachedRegistrants = new RegistrantList();
private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
@@ -573,9 +574,9 @@
CarrierServiceStateTracker.CARRIER_EVENT_VOICE_REGISTRATION, null);
registerForNetworkDetached(mCSST,
CarrierServiceStateTracker.CARRIER_EVENT_VOICE_DEREGISTRATION, null);
- registerForDataConnectionAttached(mCSST,
+ registerForDataConnectionAttached(TransportType.WWAN, mCSST,
CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null);
- registerForDataConnectionDetached(mCSST,
+ registerForDataConnectionDetached(TransportType.WWAN, mCSST,
CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null);
registerForImsCapabilityChanged(mCSST,
CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null);
@@ -602,8 +603,15 @@
}
// If we are previously in service, we need to notify that we are out of service now.
- if (mSS != null && mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
- mDetachedRegistrants.notifyRegistrants();
+ for (int transport : mTransportManager.getAvailableTransports()) {
+ if (mSS != null) {
+ NetworkRegistrationState nrs = mSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
+ if (nrs != null && nrs.isInService()
+ && mDetachedRegistrants.get(transport) != null) {
+ mDetachedRegistrants.get(transport).notifyRegistrants();
+ }
+ }
}
mSS = new ServiceState();
@@ -672,7 +680,9 @@
// Tell everybody that the registration state and RAT have changed.
notifyVoiceRegStateRilRadioTechnologyChanged();
- notifyDataRegStateRilRadioTechnologyChanged();
+ for (int transport : mTransportManager.getAvailableTransports()) {
+ notifyDataRegStateRilRadioTechnologyChanged(transport);
+ }
}
@VisibleForTesting
@@ -738,14 +748,24 @@
* AsyncResult in msg.obj where AsyncResult#result contains the
* new RAT as an Integer Object.
*/
- protected void notifyDataRegStateRilRadioTechnologyChanged() {
- int rat = mSS.getRilDataRadioTechnology();
- int drs = mSS.getDataRegState();
- if (DBG) log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
+ protected void notifyDataRegStateRilRadioTechnologyChanged(int transport) {
+ NetworkRegistrationState nrs = mSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
+ if (nrs != null) {
+ int rat = ServiceState.networkTypeToRilRadioTechnology(
+ nrs.getAccessNetworkTechnology());
+ int drs = regCodeToServiceState(nrs.getRegState());
+ if (DBG) {
+ log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
+ }
+ RegistrantList registrantList = mDataRegStateOrRatChangedRegistrants.get(transport);
+ if (registrantList != null) {
+ registrantList.notifyResult(new Pair<>(drs, rat));
+ }
+ }
mPhone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.rilRadioTechnologyToString(rat));
- mDataRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(drs, rat));
+ ServiceState.rilRadioTechnologyToString(mSS.getRilDataRadioTechnology()));
}
/**
@@ -1747,8 +1767,7 @@
* Roaming Indicator shall be sent if device is registered
* on a CDMA or EVDO system.
*/
- boolean isRoamIndForHomeSystem = isRoamIndForHomeSystem(
- Integer.toString(mRoamingIndicator));
+ boolean isRoamIndForHomeSystem = isRoamIndForHomeSystem(mRoamingIndicator);
if (mNewSS.getDataRoaming() == isRoamIndForHomeSystem) {
log("isRoamIndForHomeSystem=" + isRoamIndForHomeSystem
+ ", override data roaming to " + !isRoamIndForHomeSystem);
@@ -1978,8 +1997,7 @@
// list of ERIs for home system, mCdmaRoaming is true.
boolean cdmaRoaming =
regCodeIsRoaming(registrationState)
- && !isRoamIndForHomeSystem(
- Integer.toString(roamingIndicator));
+ && !isRoamIndForHomeSystem(roamingIndicator);
mNewSS.setVoiceRoaming(cdmaRoaming);
mRoamingIndicator = roamingIndicator;
mIsInPrl = (systemIsInPrl == 0) ? false : true;
@@ -2259,20 +2277,22 @@
* Determine whether a roaming indicator is in the carrier-specified list of ERIs for
* home system
*
- * @param roamInd roaming indicator in String
+ * @param roamInd roaming indicator
* @return true if the roamInd is in the carrier-specified list of ERIs for home network
*/
- private boolean isRoamIndForHomeSystem(String roamInd) {
+ private boolean isRoamIndForHomeSystem(int roamInd) {
// retrieve the carrier-specified list of ERIs for home system
- String[] homeRoamIndicators = Resources.getSystem()
- .getStringArray(com.android.internal.R.array.config_cdma_home_system);
+ final PersistableBundle config = getCarrierConfig();
+ int[] homeRoamIndicators = config.getIntArray(CarrierConfigManager
+ .KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY);
+
log("isRoamIndForHomeSystem: homeRoamIndicators=" + Arrays.toString(homeRoamIndicators));
if (homeRoamIndicators != null) {
// searches through the comma-separated list for a match,
// return true if one is found.
- for (String homeRoamInd : homeRoamIndicators) {
- if (homeRoamInd.equals(roamInd)) {
+ for (int homeRoamInd : homeRoamIndicators) {
+ if (homeRoamInd == roamInd) {
return true;
}
}
@@ -2962,16 +2982,48 @@
mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
&& mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;
- boolean hasDataAttached =
- mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
- && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
+ SparseBooleanArray hasDataAttached = new SparseBooleanArray(
+ mTransportManager.getAvailableTransports().length);
+ SparseBooleanArray hasDataDetached = new SparseBooleanArray(
+ mTransportManager.getAvailableTransports().length);
+ SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray(
+ mTransportManager.getAvailableTransports().length);
+ SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray(
+ mTransportManager.getAvailableTransports().length);
+ boolean anyDataRegChanged = false;
+ boolean anyDataRatChanged = false;
+ for (int transport : mTransportManager.getAvailableTransports()) {
+ NetworkRegistrationState oldNrs = mSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
+ NetworkRegistrationState newNrs = mNewSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
- boolean hasDataDetached =
- mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE
- && mNewSS.getDataRegState() != ServiceState.STATE_IN_SERVICE;
+ boolean changed = (oldNrs == null || !oldNrs.isInService())
+ && (newNrs != null && newNrs.isInService());
+ hasDataAttached.put(transport, changed);
- boolean hasDataRegStateChanged =
- mSS.getDataRegState() != mNewSS.getDataRegState();
+ changed = (oldNrs != null && oldNrs.isInService())
+ && (newNrs == null || !newNrs.isInService());
+ hasDataDetached.put(transport, changed);
+
+ int oldRAT = oldNrs != null ? oldNrs.getAccessNetworkTechnology()
+ : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ int newRAT = newNrs != null ? newNrs.getAccessNetworkTechnology()
+ : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ hasRilDataRadioTechnologyChanged.put(transport, oldRAT != newRAT);
+ if (oldRAT != newRAT) {
+ anyDataRatChanged = true;
+ }
+
+ int oldRegState = oldNrs != null ? oldNrs.getRegState()
+ : NetworkRegistrationState.REG_STATE_UNKNOWN;
+ int newRegState = newNrs != null ? newNrs.getRegState()
+ : NetworkRegistrationState.REG_STATE_UNKNOWN;
+ hasDataRegStateChanged.put(transport, oldRegState != newRegState);
+ if (oldRegState != newRegState) {
+ anyDataRegChanged = true;
+ }
+ }
boolean hasVoiceRegStateChanged =
mSS.getVoiceRegState() != mNewSS.getVoiceRegState();
@@ -3001,9 +3053,6 @@
boolean hasRilVoiceRadioTechnologyChanged =
mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
- boolean hasRilDataRadioTechnologyChanged =
- mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology();
-
boolean hasChanged = !mNewSS.equals(mSS);
boolean hasVoiceRoamingOn = !mSS.getVoiceRoaming() && mNewSS.getVoiceRoaming();
@@ -3070,7 +3119,7 @@
}
// Add an event log when connection state changes
- if (hasVoiceRegStateChanged || hasDataRegStateChanged) {
+ if (hasVoiceRegStateChanged || anyDataRegChanged) {
EventLog.writeEvent(mPhone.isPhoneTypeGsm() ? EventLogTags.GSM_SERVICE_STATE_CHANGE :
EventLogTags.CDMA_SERVICE_STATE_CHANGE,
mSS.getVoiceRegState(), mSS.getDataRegState(),
@@ -3127,19 +3176,13 @@
updatePhoneObject();
}
- TelephonyManager tm =
- (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
-
- if (hasRilDataRadioTechnologyChanged) {
+ TelephonyManager tm = (TelephonyManager) mPhone.getContext().getSystemService(
+ Context.TELEPHONY_SERVICE);
+ if (anyDataRatChanged) {
tm.setDataNetworkTypeForPhone(mPhone.getPhoneId(), mSS.getRilDataRadioTechnology());
StatsLog.write(StatsLog.MOBILE_RADIO_TECHNOLOGY_CHANGED,
- ServiceState.rilRadioTechnologyToNetworkType(mSS.getRilDataRadioTechnology()),
- mPhone.getPhoneId());
-
- if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
- == mSS.getRilDataRadioTechnology()) {
- log("pollStateDone: IWLAN enabled");
- }
+ ServiceState.rilRadioTechnologyToNetworkType(
+ mSS.getRilDataRadioTechnology()), mPhone.getPhoneId());
}
if (hasRegistered) {
@@ -3159,9 +3202,6 @@
updateSpnDisplay();
tm.setNetworkOperatorNameForPhone(mPhone.getPhoneId(), mSS.getOperatorAlpha());
-
- String prevOperatorNumeric = tm.getNetworkOperatorForPhone(mPhone.getPhoneId());
- String prevCountryIsoCode = tm.getNetworkCountryIso(mPhone.getPhoneId());
String operatorNumeric = mSS.getOperatorNumeric();
if (!mPhone.isPhoneTypeGsm()) {
@@ -3213,34 +3253,56 @@
TelephonyMetrics.getInstance().writeServiceStateChanged(mPhone.getPhoneId(), mSS);
}
- if (hasDataAttached || has4gHandoff || hasDataDetached || hasRegistered
- || hasDeregistered) {
+ boolean shouldLogAttachedChange = false;
+ boolean shouldLogRatChange = false;
+
+ if (hasRegistered || hasDeregistered) {
+ shouldLogAttachedChange = true;
+ }
+
+ if (has4gHandoff) {
+ mAttachedRegistrants.get(TransportType.WWAN).notifyRegistrants();
+ shouldLogAttachedChange = true;
+ }
+
+ if (hasRilVoiceRadioTechnologyChanged) {
+ shouldLogRatChange = true;
+ notifySignalStrength();
+ }
+
+ for (int transport : mTransportManager.getAvailableTransports()) {
+ if (hasRilDataRadioTechnologyChanged.get(transport)) {
+ shouldLogRatChange = true;
+ notifySignalStrength();
+ }
+
+ if (hasDataRegStateChanged.get(transport)
+ || hasRilDataRadioTechnologyChanged.get(transport)) {
+ notifyDataRegStateRilRadioTechnologyChanged(transport);
+ mPhone.notifyDataConnection();
+ }
+
+ if (hasDataAttached.get(transport)) {
+ shouldLogAttachedChange = true;
+ mAttachedRegistrants.get(transport).notifyRegistrants();
+ }
+ if (hasDataDetached.get(transport)) {
+ shouldLogAttachedChange = true;
+ mDetachedRegistrants.get(transport).notifyRegistrants();
+ }
+ }
+
+ if (shouldLogAttachedChange) {
logAttachChange();
}
-
- if (hasDataAttached || has4gHandoff) {
- mAttachedRegistrants.notifyRegistrants();
- }
-
- if (hasDataDetached) {
- mDetachedRegistrants.notifyRegistrants();
- }
-
- if (hasRilDataRadioTechnologyChanged || hasRilVoiceRadioTechnologyChanged) {
+ if (shouldLogRatChange) {
logRatChange();
-
- notifySignalStrength();
}
if (hasVoiceRegStateChanged || hasRilVoiceRadioTechnologyChanged) {
notifyVoiceRegStateRilRadioTechnologyChanged();
}
- if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
- notifyDataRegStateRilRadioTechnologyChanged();
- mPhone.notifyDataConnection();
- }
-
if (hasVoiceRoamingOn || hasVoiceRoamingOff || hasDataRoamingOn || hasDataRoamingOff) {
logRoamingChange();
}
@@ -4020,38 +4082,72 @@
/**
* Registration point for transition into DataConnection attached.
+ * @param transport Transport type
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- public void registerForDataConnectionAttached(Handler h, int what, Object obj) {
+ public void registerForDataConnectionAttached(int transport, Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
- mAttachedRegistrants.add(r);
+ if (mAttachedRegistrants.get(transport) == null) {
+ mAttachedRegistrants.put(transport, new RegistrantList());
+ }
+ mAttachedRegistrants.get(transport).add(r);
- if (getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
+ if (mSS != null) {
+ NetworkRegistrationState netRegState = mSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
+ if (netRegState == null || netRegState.isInService()) {
+ r.notifyRegistrant();
+ }
}
}
- public void unregisterForDataConnectionAttached(Handler h) {
- mAttachedRegistrants.remove(h);
+
+ /**
+ * Unregister for data attached event
+ *
+ * @param transport Transport type
+ * @param h Handler to notify
+ */
+ public void unregisterForDataConnectionAttached(int transport, Handler h) {
+ if (mAttachedRegistrants.get(transport) != null) {
+ mAttachedRegistrants.get(transport).remove(h);
+ }
}
/**
* Registration point for transition into DataConnection detached.
+ * @param transport Transport type
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- public void registerForDataConnectionDetached(Handler h, int what, Object obj) {
+ public void registerForDataConnectionDetached(int transport, Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
- mDetachedRegistrants.add(r);
+ if (mDetachedRegistrants.get(transport) == null) {
+ mDetachedRegistrants.put(transport, new RegistrantList());
+ }
+ mDetachedRegistrants.get(transport).add(r);
- if (getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) {
- r.notifyRegistrant();
+ if (mSS != null) {
+ NetworkRegistrationState netRegState = mSS.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, transport);
+ if (netRegState != null && !netRegState.isInService()) {
+ r.notifyRegistrant();
+ }
}
}
- public void unregisterForDataConnectionDetached(Handler h) {
- mDetachedRegistrants.remove(h);
+
+ /**
+ * Unregister for data detatched event
+ *
+ * @param transport Transport type
+ * @param h Handler to notify
+ */
+ public void unregisterForDataConnectionDetached(int transport, Handler h) {
+ if (mDetachedRegistrants.get(transport) != null) {
+ mDetachedRegistrants.get(transport).remove(h);
+ }
}
/**
@@ -4078,17 +4174,31 @@
* new radio technology will be returned AsyncResult#result as an Integer Object.
* The AsyncResult will be in the notification Message#obj.
*
+ * @param transport Transport
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- public void registerForDataRegStateOrRatChanged(Handler h, int what, Object obj) {
+ public void registerForDataRegStateOrRatChanged(int transport, Handler h, int what,
+ Object obj) {
Registrant r = new Registrant(h, what, obj);
- mDataRegStateOrRatChangedRegistrants.add(r);
- notifyDataRegStateRilRadioTechnologyChanged();
+ if (mDataRegStateOrRatChangedRegistrants.get(transport) == null) {
+ mDataRegStateOrRatChangedRegistrants.put(transport, new RegistrantList());
+ }
+ mDataRegStateOrRatChangedRegistrants.get(transport).add(r);
+ notifyDataRegStateRilRadioTechnologyChanged(transport);
}
- public void unregisterForDataRegStateOrRatChanged(Handler h) {
- mDataRegStateOrRatChangedRegistrants.remove(h);
+
+ /**
+ * Unregister for data registration state changed or RAT changed event
+ *
+ * @param transport Transport
+ * @param h The handler
+ */
+ public void unregisterForDataRegStateOrRatChanged(int transport, Handler h) {
+ if (mDataRegStateOrRatChangedRegistrants.get(transport) != null) {
+ mDataRegStateOrRatChangedRegistrants.get(transport).remove(h);
+ }
}
/**
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index f89ba4d..12e5845 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -2690,16 +2690,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 +2706,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);
}
}
diff --git a/src/java/com/android/internal/telephony/TelephonyTester.java b/src/java/com/android/internal/telephony/TelephonyTester.java
index 0ab6ec8..e054183 100644
--- a/src/java/com/android/internal/telephony/TelephonyTester.java
+++ b/src/java/com/android/internal/telephony/TelephonyTester.java
@@ -24,6 +24,7 @@
import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.ims.ImsCallProfile;
@@ -148,10 +149,12 @@
if (DBG) log("sIntentReceiver.onReceive: action=" + action);
if (action.equals(mPhone.getActionDetached())) {
log("simulate detaching");
- mPhone.getServiceStateTracker().mDetachedRegistrants.notifyRegistrants();
+ mPhone.getServiceStateTracker().mDetachedRegistrants.get(TransportType.WWAN)
+ .notifyRegistrants();
} else if (action.equals(mPhone.getActionAttached())) {
log("simulate attaching");
- mPhone.getServiceStateTracker().mAttachedRegistrants.notifyRegistrants();
+ mPhone.getServiceStateTracker().mAttachedRegistrants.get(TransportType.WWAN)
+ .notifyRegistrants();
} else if (action.equals(ACTION_TEST_CONFERENCE_EVENT_PACKAGE)) {
log("inject simulated conference event package");
handleTestConferenceEventPackage(context,
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index 26d9ec7..d7f0ae3 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -625,6 +625,10 @@
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_EMERGENCY;
}
+ if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MCX)) {
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_MCX;
+ }
if (error) {
// TODO: If this error condition is removed, the framework's handling of
// NET_CAPABILITY_NOT_RESTRICTED will need to be updated so requests for
diff --git a/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
index ae69631..41b8dab 100644
--- a/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
+++ b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
@@ -67,7 +67,7 @@
private CellularDataServiceProvider(int slotId) {
super(slotId);
- mPhone = PhoneFactory.getPhone(getSlotId());
+ mPhone = PhoneFactory.getPhone(getSlotIndex());
mHandlerThread = new HandlerThread(CellularDataService.class.getSimpleName());
mHandlerThread.start();
@@ -125,10 +125,10 @@
}
@Override
- public void setupDataCall(int radioTechnology, DataProfile dataProfile, boolean isRoaming,
+ public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
boolean allowRoaming, int reason, LinkProperties linkProperties,
DataServiceCallback callback) {
- if (DBG) log("setupDataCall " + getSlotId());
+ if (DBG) log("setupDataCall " + getSlotIndex());
Message message = null;
// Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -138,13 +138,13 @@
mCallbackMap.put(message, callback);
}
- mPhone.mCi.setupDataCall(radioTechnology, dataProfile, isRoaming, allowRoaming, reason,
- linkProperties, message);
+ mPhone.mCi.setupDataCall(accessNetworkType, dataProfile, isRoaming, allowRoaming,
+ reason, linkProperties, message);
}
@Override
public void deactivateDataCall(int cid, int reason, DataServiceCallback callback) {
- if (DBG) log("deactivateDataCall " + getSlotId());
+ if (DBG) log("deactivateDataCall " + getSlotIndex());
Message message = null;
// Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -160,7 +160,7 @@
@Override
public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
DataServiceCallback callback) {
- if (DBG) log("setInitialAttachApn " + getSlotId());
+ if (DBG) log("setInitialAttachApn " + getSlotIndex());
Message message = null;
// Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -176,7 +176,7 @@
@Override
public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
DataServiceCallback callback) {
- if (DBG) log("setDataProfile " + getSlotId());
+ if (DBG) log("setDataProfile " + getSlotIndex());
Message message = null;
// Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -191,7 +191,7 @@
@Override
public void getDataCallList(DataServiceCallback callback) {
- if (DBG) log("getDataCallList " + getSlotId());
+ if (DBG) log("getDataCallList " + getSlotIndex());
Message message = null;
// Only obtain the message when the caller wants a callback. If the caller doesn't care
@@ -211,13 +211,13 @@
}
@Override
- public DataServiceProvider createDataServiceProvider(int slotId) {
- log("Cellular data service created for slot " + slotId);
- if (!SubscriptionManager.isValidSlotIndex(slotId)) {
- loge("Tried to cellular data service with invalid slotId " + slotId);
+ public DataServiceProvider onCreateDataServiceProvider(int slotIndex) {
+ log("Cellular data service created for slot " + slotIndex);
+ if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
+ loge("Tried to cellular data service with invalid slotId " + slotIndex);
return null;
}
- return new CellularDataServiceProvider(slotId);
+ return new CellularDataServiceProvider(slotIndex);
}
private void log(String s) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 51dc0ee..f3623bd 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -41,8 +41,10 @@
import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
+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;
@@ -109,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,
@@ -881,17 +886,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;
@@ -906,7 +919,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"
@@ -954,7 +973,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;
@@ -1125,6 +1149,10 @@
result.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
break;
}
+ case PhoneConstants.APN_TYPE_MCX: {
+ result.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
+ break;
+ }
default:
}
}
@@ -1191,6 +1219,27 @@
}
/**
+ * @return {@code True} if 464xlat should be skipped.
+ */
+ @VisibleForTesting
+ public boolean shouldSkip464Xlat() {
+ switch (mApnSetting.getSkip464Xlat()) {
+ case Telephony.Carriers.SKIP_464XLAT_ENABLE:
+ return true;
+ case Telephony.Carriers.SKIP_464XLAT_DISABLE:
+ return false;
+ case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
+ default:
+ break;
+ }
+
+ // As default, return true if ims and no internet
+ final NetworkCapabilities nc = getNetworkCapabilities();
+ return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+ && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ }
+
+ /**
* @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address.
*/
@VisibleForTesting
@@ -1358,7 +1407,8 @@
if (DBG) log("DcDefaultState: enter");
// Register for DRS or RAT change
- mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(getHandler(),
+ mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
+ mDataServiceManager.getTransportType(), getHandler(),
DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(),
@@ -1374,7 +1424,8 @@
if (DBG) log("DcDefaultState: exit");
// Unregister for DRS or RAT change.
- mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(getHandler());
+ mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
+ mDataServiceManager.getTransportType(), getHandler());
mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler());
mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler());
@@ -1803,6 +1854,9 @@
}
misc.subscriberId = mPhone.getSubscriberId();
+ // set skip464xlat if it is not default otherwise
+ misc.skip464xlat = shouldSkip464Xlat();
+
mRestrictedNetworkOverride = shouldRestrictNetwork();
mUnmeteredUseOnly = isUnmeteredUseOnly();
@@ -2763,6 +2817,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/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 9015be4..6e477ce 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -66,6 +66,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
+import android.telephony.NetworkRegistrationState;
import android.telephony.PcoData;
import android.telephony.Rlog;
import android.telephony.ServiceState;
@@ -128,6 +129,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,
@@ -733,9 +753,9 @@
}
public void registerServiceStateTrackerEvents() {
- mPhone.getServiceStateTracker().registerForDataConnectionAttached(this,
+ mPhone.getServiceStateTracker().registerForDataConnectionAttached(mTransportType, this,
DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
- mPhone.getServiceStateTracker().registerForDataConnectionDetached(this,
+ mPhone.getServiceStateTracker().registerForDataConnectionDetached(mTransportType, this,
DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
DctConstants.EVENT_ROAMING_ON, null);
@@ -745,18 +765,19 @@
DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
- mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this,
+ mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(mTransportType, this,
DctConstants.EVENT_DATA_RAT_CHANGED, null);
}
public void unregisterServiceStateTrackerEvents() {
- mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(this);
- mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(this);
+ mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(mTransportType, this);
+ mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(mTransportType, this);
mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
- mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(this);
+ mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(mTransportType,
+ this);
}
private void registerForAllEvents() {
@@ -969,42 +990,45 @@
com.android.internal.R.array.networkAttributes);
for (String networkConfigString : networkConfigStrings) {
NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
- ApnContext apnContext = null;
+ 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);
}
@@ -1219,7 +1243,7 @@
boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
// TODO: Remove this hack added by ag/641832.
- int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
+ int radioTech = getDataRat();
if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
desiredPowerState = true;
radioStateFromCarrier = true;
@@ -1427,7 +1451,7 @@
apnContext.requestLog(str);
apnContext.setState(DctConstants.State.IDLE);
}
- int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
+ int radioTech = getDataRat();
apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
.isConcurrentVoiceAndDataAllowed());
if (apnContext.getState() == DctConstants.State.IDLE) {
@@ -1674,7 +1698,7 @@
log("fetchDunApns: net.tethering.noprovisioning=true ret: empty list");
return new ArrayList<ApnSetting>(0);
}
- int bearer = mPhone.getServiceState().getRilDataRadioTechnology();
+ int bearer = getDataRat();
ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
@@ -1765,7 +1789,7 @@
*/
private boolean teardownForDun() {
// CDMA always needs to do this the profile id is correct
- final int rilRat = mPhone.getServiceState().getRilDataRadioTechnology();
+ final int rilRat = getDataRat();
if (ServiceState.isCdma(rilRat)) return true;
ArrayList<ApnSetting> apns = fetchDunApns();
@@ -1855,7 +1879,7 @@
// On GSM/LTE we can share existing apn connections provided they support
// this type.
if (!apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DUN)
- || ServiceState.isGsm(mPhone.getServiceState().getRilDataRadioTechnology())) {
+ || ServiceState.isGsm(getDataRat())) {
dataConnection = checkForCompatibleConnectedApnContext(apnContext);
if (dataConnection != null) {
// Get the apn setting used by the data connection
@@ -2107,9 +2131,8 @@
boolean retry = true;
String reason = apnContext.getReason();
- if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
- (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
- && isHigherPriorityApnContextActive(apnContext))) {
+ if (Phone.REASON_RADIO_TURNED_OFF.equals(reason) || (isOnlySingleDcAllowed(getDataRat())
+ && isHigherPriorityApnContextActive(apnContext))) {
retry = false;
}
return retry;
@@ -2409,8 +2432,7 @@
cleanUpConnectionInternal(true, releaseType, apnContext);
}
- if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())
- && !isHigherPriorityApnContextActive(apnContext)) {
+ if (isOnlySingleDcAllowed(getDataRat()) && !isHigherPriorityApnContextActive(apnContext)) {
if (DBG) log("disableApn:isOnlySingleDcAllowed true & higher priority APN disabled");
// If the highest priority APN is disabled and only single
// data call is allowed, try to setup data call on other connectable APN.
@@ -2842,9 +2864,8 @@
cause, cid, mTelephonyManager.getNetworkType());
}
ApnSetting apn = apnContext.getApnSetting();
- mPhone.notifyPreciseDataConnectionFailed(
- apnContext.getApnType(), apn != null ? apn.getApnName()
- : "unknown", cause);
+ mPhone.notifyPreciseDataConnectionFailed(apnContext.getApnType(),
+ apn != null ? apn.getApnName() : null, cause);
// Compose broadcast intent send to the specific carrier signaling receivers
Intent intent = new Intent(TelephonyIntents
@@ -2984,7 +3005,7 @@
}
apnContext.setApnSetting(null);
apnContext.setDataConnection(null);
- if (isOnlySingleDcAllowed(mPhone.getServiceState().getRilDataRadioTechnology())) {
+ if (isOnlySingleDcAllowed(getDataRat())) {
if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
setupDataOnConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION,
RetryFailures.ALWAYS);
@@ -3180,7 +3201,8 @@
dest.isEnabled(), networkTypeBitmask, dest.getProfileId(),
(dest.isPersistent() || src.isPersistent()), dest.getMaxConns(),
dest.getWaitTime(), dest.getMaxConnsTime(), dest.getMtu(), dest.getMvnoType(),
- dest.getMvnoMatchData(), dest.getApnSetId(), dest.getCarrierId());
+ dest.getMvnoMatchData(), dest.getApnSetId(), dest.getCarrierId(),
+ dest.getSkip464Xlat());
}
private DataConnection createDataConnection() {
@@ -3503,8 +3525,7 @@
break;
case DctConstants.EVENT_DATA_RAT_CHANGED:
- if (mPhone.getServiceState().getRilDataRadioTechnology()
- == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
+ if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
// unknown rat is an exception for data rat change. It's only received when out
// of service and is not applicable for apn bearer bitmask. We should bypass the
// check of waiting apn list and keep the data connection on, and no need to
@@ -4114,8 +4135,7 @@
if (mAllApnSettings.isEmpty()) {
cleanUpAllConnectionsInternal(detach, Phone.REASON_APN_CHANGED);
} else {
- int radioTech = mPhone.getServiceState().getRilDataRadioTechnology();
- if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
+ if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
// unknown rat is an exception for data rat change. Its only received when out of
// service and is not applicable for apn bearer bitmask. We should bypass the check
// of waiting apn list and keep the data connection on.
@@ -4124,8 +4144,7 @@
for (ApnContext apnContext : mApnContexts.values()) {
ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
ArrayList<ApnSetting> waitingApns = buildWaitingApns(
- apnContext.getApnType(),
- mPhone.getServiceState().getRilDataRadioTechnology());
+ apnContext.getApnType(), getDataRat());
if (VDBG) log("new waitingApns:" + waitingApns);
if ((currentWaitingApns != null)
&& ((waitingApns.size() != currentWaitingApns.size())
@@ -4738,4 +4757,14 @@
}
return "UNKNOWN";
}
+
+ private int getDataRat() {
+ ServiceState ss = mPhone.getServiceState();
+ NetworkRegistrationState nrs = ss.getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, mTransportType);
+ if (nrs != null) {
+ return ServiceState.networkTypeToRilRadioTechnology(nrs.getAccessNetworkTechnology());
+ }
+ return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
+ }
}
diff --git a/src/java/com/android/internal/telephony/TransportManager.java b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
similarity index 100%
rename from src/java/com/android/internal/telephony/TransportManager.java
rename to src/java/com/android/internal/telephony/dataconnection/TransportManager.java
diff --git a/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
index ffe4bac..fd00dff 100644
--- a/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
+++ b/src/java/com/android/internal/telephony/ims/RcsMessageStoreController.java
@@ -131,6 +131,9 @@
synchronized (RcsMessageStoreController.class) {
if (sInstance == null) {
sInstance = new RcsMessageStoreController(context.getContentResolver());
+ if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
+ ServiceManager.addService(RCS_SERVICE_NAME, sInstance);
+ }
} else {
Rlog.e(TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -138,20 +141,8 @@
return sInstance;
}
- private RcsMessageStoreController(ContentResolver contentResolver) {
- mContentResolver = contentResolver;
- mParticipantQueryHelper = new RcsParticipantQueryHelper(contentResolver);
- mMessageQueryHelper = new RcsMessageQueryHelper(contentResolver);
- mThreadQueryHelper = new RcsThreadQueryHelper(contentResolver, mParticipantQueryHelper);
- mEventQueryHelper = new RcsEventQueryHelper(contentResolver);
- mMessageStoreUtil = new RcsMessageStoreUtil(contentResolver);
- if (ServiceManager.getService(RCS_SERVICE_NAME) == null) {
- ServiceManager.addService(RCS_SERVICE_NAME, this);
- }
- }
-
@VisibleForTesting
- public RcsMessageStoreController(ContentResolver contentResolver, Void unused) {
+ public RcsMessageStoreController(ContentResolver contentResolver) {
mContentResolver = contentResolver;
mParticipantQueryHelper = new RcsParticipantQueryHelper(contentResolver);
mMessageQueryHelper = new RcsMessageQueryHelper(contentResolver);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index ab39212..79322e5 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -272,10 +272,13 @@
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
mWakeLock.setReferenceCounted(false);
- if (mDefaultPhone.getServiceStateTracker() != null) {
- mDefaultPhone.getServiceStateTracker()
- .registerForDataRegStateOrRatChanged(this,
- EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null);
+ if (mDefaultPhone.getServiceStateTracker() != null
+ && mDefaultPhone.getTransportManager() != null) {
+ for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
+ mDefaultPhone.getServiceStateTracker()
+ .registerForDataRegStateOrRatChanged(transport, this,
+ EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null);
+ }
}
// Sets the Voice reg state to STATE_OUT_OF_SERVICE and also queries the data service
// state. We don't ever need the voice reg state to be anything other than in or out of
@@ -301,8 +304,10 @@
//Force all referenced classes to unregister their former registered events
if (mDefaultPhone != null && mDefaultPhone.getServiceStateTracker() != null) {
- mDefaultPhone.getServiceStateTracker().
- unregisterForDataRegStateOrRatChanged(this);
+ for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
+ mDefaultPhone.getServiceStateTracker()
+ .unregisterForDataRegStateOrRatChanged(transport, this);
+ }
mDefaultPhone.unregisterForServiceStateChanged(this);
}
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index b78932b..0a6ed7b 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -113,6 +113,7 @@
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
@@ -499,8 +500,12 @@
//***** Constructors
-
public ImsPhoneCallTracker(ImsPhone phone) {
+ this(phone, phone.getContext().getMainExecutor());
+ }
+
+ @VisibleForTesting
+ public ImsPhoneCallTracker(ImsPhone phone, Executor executor) {
this.mPhone = phone;
mMetrics = TelephonyMetrics.getInstance();
@@ -523,6 +528,7 @@
mVtDataUsageSnapshot = new NetworkStats(currentTime, 1);
mVtDataUsageUidSnapshot = new NetworkStats(currentTime, 1);
+ // Allow the executor to be specified for testing.
mImsManagerConnector = new ImsManager.Connector(phone.getContext(), phone.getPhoneId(),
new ImsManager.Connector.Listener() {
@Override
@@ -535,7 +541,7 @@
public void connectionUnavailable() {
stopListeningForCalls();
}
- });
+ }, executor);
mImsManagerConnector.connect();
}
@@ -2973,7 +2979,7 @@
}
@Override
- public void onDeregistered(ImsReasonInfo imsReasonInfo) {
+ public void onUnregistered(ImsReasonInfo imsReasonInfo) {
if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
mPhone.setImsRegistered(false);
@@ -3257,6 +3263,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/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 72f3a38..6f23b2a 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -38,6 +38,7 @@
import android.os.ResultReceiver;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
+import android.telephony.ims.ImsCallForwardInfo;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsSsData;
import android.telephony.ims.ImsSsInfo;
@@ -54,6 +55,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.uicc.IccRecords;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1531,15 +1533,17 @@
sb.append(getErrorMessage(ar));
}
} else {
- ImsSsInfo[] infos = (ImsSsInfo[])ar.result;
- if (infos.length == 0) {
+ List<ImsSsInfo> infos = (List<ImsSsInfo>) ar.result;
+ if (infos.size() == 0) {
sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
} else {
- for (int i = 0, s = infos.length; i < s ; i++) {
- if (infos[i].getIncomingCommunicationBarringNumber() != null) {
- sb.append("Num: " + infos[i].getIncomingCommunicationBarringNumber()
- + " status: " + infos[i].getStatus() + "\n");
- } else if (infos[i].getStatus() == 1) {
+ ImsSsInfo info;
+ for (int i = 0, s = infos.size(); i < s; i++) {
+ info = infos.get(i);
+ if (info.getIncomingCommunicationBarringNumber() != null) {
+ sb.append("Num: " + info.getIncomingCommunicationBarringNumber()
+ + " status: " + info.getStatus() + "\n");
+ } else if (info.getStatus() == 1) {
sb.append(mContext.getText(com.android.internal
.R.string.serviceEnabled));
} else {
@@ -1772,8 +1776,16 @@
onQueryClirComplete(new AsyncResult(null, clirInfo, ex));
} else if (ssData.isTypeCF()) {
Rlog.d(LOG_TAG, "CALL FORWARD INTERROGATION");
- onQueryCfComplete(new AsyncResult(null, mPhone
- .handleCfQueryResult(ssData.getCallForwardInfo()), ex));
+ // Have to translate to an array, since the modem still returns it in the
+ // ImsCallForwardInfo[] format.
+ List<ImsCallForwardInfo> mCfInfos = ssData.getCallForwardInfo();
+ ImsCallForwardInfo[] mCfInfosCompat = null;
+ if (mCfInfos != null) {
+ mCfInfosCompat = new ImsCallForwardInfo[mCfInfos.size()];
+ mCfInfosCompat = mCfInfos.toArray(mCfInfosCompat);
+ }
+ onQueryCfComplete(new AsyncResult(null, mPhone.handleCfQueryResult(
+ mCfInfosCompat), ex));
} else if (ssData.isTypeBarring()) {
onSuppSvcQueryComplete(new AsyncResult(null, ssData.getSuppServiceInfoCompat(),
ex));
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..39cdea4 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;
@@ -598,7 +599,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 +667,16 @@
log.endTime = new TelephonyProto.Time();
log.endTime.systemTimestampMillis = System.currentTimeMillis();
log.endTime.elapsedTimestampMillis = SystemClock.elapsedRealtime();
+
+ // Log the last active subscription information.
+ ActiveSubscriptionInfo[] activeSubscriptionInfo =
+ new ActiveSubscriptionInfo[mLastActiveSubscriptionInfos.size()];
+ for (int i = 0; i < mLastActiveSubscriptionInfos.size(); i++) {
+ int key = mLastActiveSubscriptionInfos.keyAt(i);
+ activeSubscriptionInfo[key] = mLastActiveSubscriptionInfos.get(key);
+ }
+ log.lastActiveSubscriptionInfo = activeSubscriptionInfo;
+
return log;
}
@@ -664,19 +686,41 @@
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 (isDifferentSubscriptionInfo(
+ mLastActiveSubscriptionInfos.get(phoneId), activeSubscriptionInfo)) {
+ addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+ .setActiveSubscriptionInfoChange(activeSubscriptionInfo).build());
+
+ mLastActiveSubscriptionInfos.put(phoneId, activeSubscriptionInfo);
+ }
+ }
+
+ for (int phoneId : inActivePhoneList) {
+ mLastActiveSubscriptionInfos.remove(phoneId);
+ ActiveSubscriptionInfo invalidSubInfo = new ActiveSubscriptionInfo();
+ invalidSubInfo.slotIndex = phoneId;
+ invalidSubInfo.carrierId = -1;
+ invalidSubInfo.isOpportunistic = -1;
+ addTelephonyEvent(new TelephonyEventBuilder(phoneId)
+ .setActiveSubscriptionInfoChange(invalidSubInfo).build());
}
}
@@ -684,28 +728,8 @@
public void updateEnabledModemBitmap(int enabledModemBitmap) {
if (mLastEnabledModemBitmap == enabledModemBitmap) return;
mLastEnabledModemBitmap = enabledModemBitmap;
- writePhoneStatusChangedEvent();
- }
-
- /** 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());
+ addTelephonyEvent(new TelephonyEventBuilder()
+ .setEnabledModemBitmap(mLastEnabledModemBitmap).build());
}
/**
@@ -1709,6 +1733,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
@@ -2434,4 +2484,14 @@
return SimState.SIM_STATE_UNKNOWN;
}
}
+
+ private static boolean isDifferentSubscriptionInfo(
+ ActiveSubscriptionInfo oldInfo, ActiveSubscriptionInfo newInfo) {
+ if (oldInfo == null || newInfo == null) {
+ return oldInfo == newInfo;
+ }
+
+ return oldInfo.slotIndex != newInfo.slotIndex || oldInfo.carrierId != newInfo.carrierId
+ || oldInfo.isOpportunistic != newInfo.isOpportunistic;
+ }
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 23eabad..99f3aa5 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -16,6 +16,9 @@
package com.android.internal.telephony.uicc;
+import static android.telephony.TelephonyManager.UNINITIALIZED_CARD_ID;
+import static android.telephony.TelephonyManager.UNSUPPORTED_CARD_ID;
+
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -128,6 +131,8 @@
// The array index is the card ID (int).
// This mapping exists to expose card-based functionality without exposing the EID, which is
// considered sensetive information.
+ // mCardStrings is populated using values from the IccSlotStatus and IccCardStatus. For
+ // HAL < 1.2, these do not contain the EID or the ICCID, so mCardStrings will be empty
private ArrayList<String> mCardStrings;
// This is the card ID of the default eUICC. It starts as UNINITIALIZED_CARD_ID.
@@ -213,7 +218,7 @@
mLauncher = new UiccStateChangedLauncher(c, this);
mCardStrings = loadCardStrings();
- mDefaultEuiccCardId = TelephonyManager.UNINITIALIZED_CARD_ID;
+ mDefaultEuiccCardId = UNINITIALIZED_CARD_ID;
}
private int getSlotIdFromPhoneId(int phoneId) {
@@ -555,7 +560,8 @@
if (eidIsNotSupported(status)) {
// we will never get EID from the HAL, so set mDefaultEuiccCardId to UNSUPPORTED_CARD_ID
- mDefaultEuiccCardId = TelephonyManager.UNSUPPORTED_CARD_ID;
+ if (DBG) log("eid is not supported");
+ mDefaultEuiccCardId = UNSUPPORTED_CARD_ID;
}
mPhoneIdToSlotId[index] = slotId;
@@ -589,7 +595,7 @@
// EID may be unpopulated if RadioConfig<1.2
// If so, just register for EID loaded and skip this stuff
if (isEuicc && cardString == null
- && mDefaultEuiccCardId != TelephonyManager.UNSUPPORTED_CARD_ID) {
+ && mDefaultEuiccCardId != UNSUPPORTED_CARD_ID) {
((EuiccCard) card).registerForEidReady(this, EVENT_EID_READY, index);
}
@@ -633,18 +639,24 @@
* to match to a card ID.
*
* @return the matching cardId, or UNINITIALIZED_CARD_ID if the card string does not map to a
- * currently loaded cardId
+ * currently loaded cardId, or UNSUPPORTED_CARD_ID if the device does not support card IDs
*/
public int convertToPublicCardId(String cardString) {
- if (TextUtils.isEmpty(cardString)) {
- return TelephonyManager.UNINITIALIZED_CARD_ID;
+ if (mDefaultEuiccCardId == UNSUPPORTED_CARD_ID) {
+ // even if cardString is not an EID, if EID is not supported (e.g. HAL < 1.2) we can't
+ // guarentee a working card ID implementation, so return UNSUPPORTED_CARD_ID
+ return UNSUPPORTED_CARD_ID;
}
+ if (TextUtils.isEmpty(cardString)) {
+ return UNINITIALIZED_CARD_ID;
+ }
+
if (cardString.length() < EID_LENGTH) {
cardString = IccUtils.stripTrailingFs(cardString);
}
int id = mCardStrings.indexOf(cardString);
if (id == -1) {
- return TelephonyManager.UNINITIALIZED_CARD_ID;
+ return UNINITIALIZED_CARD_ID;
} else {
return id;
}
@@ -916,7 +928,7 @@
// set mCardStrings and the defaultEuiccCardId using the now available EID
String eid = ((EuiccCard) card).getEid();
addCardId(eid);
- if (mDefaultEuiccCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
+ if (mDefaultEuiccCardId == UNINITIALIZED_CARD_ID) {
// TODO(b/122738148) the default eUICC should not be removable
mDefaultEuiccCardId = convertToPublicCardId(eid);
log("onEidReady: eid=" + eid + " slot=" + slotId + " mDefaultEuiccCardId="
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index 57f33ce..aa37ff7 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -226,7 +226,7 @@
public void testRegistrationCallbackNoCallbackIfUnknown() throws RemoteException {
mRegBinder.addRegistrationCallback(mCallback2);
// Verify that if we have never set the registration state, we do not callback immediately
- // with onDeregistered.
+ // with onUnregistered.
verify(mCallback2, never()).onDeregistered(any(ImsReasonInfo.class));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
index 1eac933..fdefa1d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierRestrictionRulesTest.java
@@ -207,7 +207,7 @@
list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
- List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+ List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
List<Boolean> expected =
Arrays.asList(true, true, true, true, true, true, true, true, true, true, true);
@@ -247,7 +247,7 @@
list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
- List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+ List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
List<Boolean> expected =
Arrays.asList(true, true, true, true, true, true, true,
@@ -282,7 +282,7 @@
list.add(new CarrierIdentifier(MCC1, MNC3, null, null, null, null));
list.add(new CarrierIdentifier(MCC1, MNC4, null, null, null, null));
- List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+ List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
List<Boolean> expected = Arrays.asList(true, true, true, true, false, false);
assertTrue(result.equals(expected));
@@ -309,7 +309,7 @@
list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
- List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+ List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
List<Boolean> expected = Arrays.asList(true, true, true, true);
assertTrue(result.equals(expected));
@@ -335,7 +335,7 @@
list.add(new CarrierIdentifier(MCC4, MNC4, null, null, null, null));
list.add(new CarrierIdentifier(MCC5, MNC5, null, null, null, null));
- List<Boolean> result = rules.isCarrierIdentifiersAllowed(list);
+ List<Boolean> result = rules.areCarrierIdentifiersAllowed(list);
List<Boolean> expected = Arrays.asList(false, false, false);
assertTrue(result.equals(expected));
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/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 6ad5b8f..2f20579 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -903,7 +903,8 @@
waitForMs(100);
- sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
+ sst.registerForDataConnectionAttached(TransportType.WWAN, mTestHandler,
+ EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -925,7 +926,7 @@
waitForMs(100);
// Unregister registrant
- sst.unregisterForDataConnectionAttached(mTestHandler);
+ sst.unregisterForDataConnectionAttached(TransportType.WWAN, mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -949,7 +950,8 @@
waitForMs(100);
- sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
+ sst.registerForDataConnectionAttached(TransportType.WWAN, mTestHandler,
+ EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -971,7 +973,7 @@
waitForMs(100);
// Unregister registrant
- sst.unregisterForDataConnectionAttached(mTestHandler);
+ sst.unregisterForDataConnectionAttached(TransportType.WWAN, mTestHandler);
// set service state in service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
@@ -993,7 +995,8 @@
mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
- sst.registerForDataConnectionDetached(mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
+ sst.registerForDataConnectionDetached(TransportType.WWAN, mTestHandler,
+ EVENT_DATA_CONNECTION_DETACHED, null);
// set service state out of service and trigger events to post message on handler
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
@@ -1015,7 +1018,7 @@
waitForMs(100);
// Unregister registrant
- sst.unregisterForDataConnectionDetached(mTestHandler);
+ sst.unregisterForDataConnectionDetached(TransportType.WWAN, mTestHandler);
// set service state out of service
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
@@ -1050,11 +1053,12 @@
@Test
@MediumTest
public void testRegisterForDataRegStateOrRatChange() {
- int drs = NetworkRegistrationState.REG_STATE_HOME;
+ int drs = ServiceState.STATE_IN_SERVICE;
int rat = sst.mSS.RIL_RADIO_TECHNOLOGY_LTE;
sst.mSS.setRilDataRadioTechnology(rat);
sst.mSS.setDataRegState(drs);
- sst.registerForDataRegStateOrRatChanged(mTestHandler, EVENT_DATA_RAT_CHANGED, null);
+ sst.registerForDataRegStateOrRatChanged(TransportType.WWAN, mTestHandler,
+ EVENT_DATA_RAT_CHANGED, null);
waitForMs(100);
@@ -1062,7 +1066,8 @@
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
verify(mTestHandler).sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
assertEquals(EVENT_DATA_RAT_CHANGED, messageArgumentCaptor.getValue().what);
- assertEquals(new Pair<Integer, Integer>(drs, rat),
+ assertEquals(new Pair<Integer, Integer>(ServiceState.STATE_IN_SERVICE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE),
((AsyncResult)messageArgumentCaptor.getValue().obj).result);
}
@@ -1423,7 +1428,8 @@
sst.registerForDataRoamingOff(mTestHandler, EVENT_DATA_ROAMING_OFF, null, true);
sst.registerForVoiceRoamingOff(mTestHandler, EVENT_VOICE_ROAMING_OFF, null);
- sst.registerForDataConnectionDetached(mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
+ sst.registerForDataConnectionDetached(TransportType.WWAN, mTestHandler,
+ EVENT_DATA_CONNECTION_DETACHED, null);
// Call functions which would trigger posting of message on test handler
doReturn(false).when(mPhone).isPhoneTypeGsm();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 35bab98..576ee33 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_SUBID_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 onActiveDataSubIdChanged(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_SUBID_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/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index a18fb28..2b330db 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -45,6 +45,7 @@
import android.provider.BlockedNumberContract;
import android.provider.Settings;
import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.NetworkRegistrationState;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -143,6 +144,8 @@
@Mock
protected ServiceState mServiceState;
@Mock
+ protected NetworkRegistrationState mNetworkRegistrationState;
+ @Mock
protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
@Mock
protected IDeviceIdleController mIDeviceIdleController;
@@ -491,6 +494,8 @@
doReturn(TransportType.WWAN).when(mTransportManager).getCurrentTransport(anyInt());
doReturn(true).when(mDataEnabledSettings).isDataEnabled();
doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
+ doReturn(mNetworkRegistrationState).when(mServiceState).getNetworkRegistrationState(
+ anyInt(), anyInt());
//SIM
doReturn(1).when(mTelephonyManager).getSimCount();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
index b4ce3e3..3be4104 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
@@ -129,6 +129,7 @@
assertEquals(a1.getMvnoMatchData(), a2.getMvnoMatchData());
assertEquals(a1.getNetworkTypeBitmask(), a2.getNetworkTypeBitmask());
assertEquals(a1.getApnSetId(), a2.getApnSetId());
+ assertEquals(a1.getSkip464Xlat(), a2.getSkip464Xlat());
}
@Test
@@ -229,7 +230,7 @@
expectedApn = ApnSetting.makeApnSetting(
-1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
- 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1);
+ 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, -1);
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v6 string with carrierId=100
@@ -239,7 +240,17 @@
expectedApn = ApnSetting.makeApnSetting(
-1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
- 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, 100);
+ 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, 100, -1);
+ assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+ // A v7 string with skip_464xlat=1
+ testString =
+ "[ApnSettingV7] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3,"
+ + "-1, 1";
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, 1);
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// Return no apn if insufficient fields given.
@@ -279,7 +290,7 @@
expectedApns.add(ApnSetting.makeApnSetting(
-1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
- 0, 0, false, 0, 0, 0, 0, -1, "", 3, -1));
+ 0, 0, false, 0, 0, 0, 0, -1, "", 3, -1, -1));
assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString));
}
@@ -292,9 +303,9 @@
null, null, -1, "user", "password", 0,
ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
4096, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "");
- String expected = "[ApnSettingV6] Name, 99, 12345, apn, null, "
+ String expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
+ "null, null, null, 10, 0, hipri | default, "
- + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0, -1";
+ + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0, -1, -1";
assertEquals(expected, apn.toString());
final int networkTypeBitmask = 1 << (14 - 1);
@@ -302,10 +313,10 @@
99, "12345", "Name", "apn", null, 10,
null, null, -1, "user", "password", 0,
ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
- networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3, -1);
- expected = "[ApnSettingV6] Name, 99, 12345, apn, null, "
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3, -1, 1);
+ expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
+ "null, null, null, 10, 0, hipri | default, "
- + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3, -1";
+ + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3, -1, 1";
assertEquals(expected, apn.toString());
}
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 7fd6f35..6289e31 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -157,6 +157,93 @@
-1, // mvno_type
""); // mnvo_match_data
+ private ApnSetting mApn3 = ApnSetting.makeApnSetting(
+ 2164, // id
+ "44010", // numeric
+ "sp-mode", // name
+ "spmode.ne.jp", // apn
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ ApnSetting.TYPE_DEFAULT, // types
+ ApnSetting.PROTOCOL_IPV6, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
+ true, // carrier_enabled
+ 0, // networktype_bitmask
+ 0, // profile_id
+ false, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ -1, // mvno_type
+ "", // mnvo_match_data
+ 0, // apn_set_id
+ -1, // carrier_id
+ 1); // skip_464xlat
+
+ private ApnSetting mApn4 = ApnSetting.makeApnSetting(
+ 2164, // id
+ "44010", // numeric
+ "sp-mode", // name
+ "spmode.ne.jp", // apn
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ ApnSetting.TYPE_IMS, // types
+ ApnSetting.PROTOCOL_IPV6, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
+ true, // carrier_enabled
+ 0, // networktype_bitmask
+ 0, // profile_id
+ false, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ -1, // mvno_type
+ ""); // mnvo_match_data
+
+ private ApnSetting mApn5 = ApnSetting.makeApnSetting(
+ 2164, // id
+ "44010", // numeric
+ "sp-mode", // name
+ "spmode.ne.jp", // apn
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ ApnSetting.TYPE_IMS, // types
+ ApnSetting.PROTOCOL_IPV6, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
+ true, // carrier_enabled
+ 0, // networktype_bitmask
+ 0, // profile_id
+ false, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ -1, // mvno_type
+ "", // mnvo_match_data
+ 0, // apn_set_id
+ -1, // carrier_id
+ 0); // skip_464xlat
+
private class DataConnectionTestHandler extends HandlerThread {
private DataConnectionTestHandler(String name) {
@@ -510,6 +597,44 @@
}
@Test
+ public void testShouldSkip464Xlat() throws Exception {
+ assertFalse(testShouldSkip464XlatEvent(mApn1));
+ disconnectEvent();
+
+ assertTrue(testShouldSkip464XlatEvent(mApn3));
+ disconnectEvent();
+
+ assertTrue(testShouldSkip464XlatEvent(mApn4));
+ disconnectEvent();
+
+ assertFalse(testShouldSkip464XlatEvent(mApn5));
+ disconnectEvent();
+ }
+
+ private boolean testShouldSkip464XlatEvent(ApnSetting apn) throws Exception {
+ Method method = DataConnection.class.getDeclaredMethod("shouldSkip464Xlat");
+ method.setAccessible(true);
+
+ doReturn(apn).when(mApnContext).getApnSetting();
+ connectEvent();
+ logd(getNetworkCapabilities().toString());
+
+ return (Boolean) method.invoke(mDc);
+ }
+
+ private void connectEvent() throws Exception {
+ mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
+ waitForMs(200);
+ assertEquals("DcActiveState", getCurrentState().getName());
+ }
+
+ private void disconnectEvent() throws Exception {
+ mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
+ waitForMs(100);
+ assertEquals("DcInactiveState", getCurrentState().getName());
+ }
+
+ @Test
@SmallTest
public void testIsIpAddress() throws Exception {
// IPv4
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 8d8a080..29fc9fa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -61,6 +61,7 @@
import android.os.PersistableBundle;
import android.provider.Settings;
import android.provider.Telephony;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
@@ -229,7 +230,8 @@
Telephony.Carriers.MVNO_MATCH_DATA,
Telephony.Carriers.NETWORK_TYPE_BITMASK,
Telephony.Carriers.APN_SET_ID,
- Telephony.Carriers.CARRIER_ID});
+ Telephony.Carriers.CARRIER_ID,
+ Telephony.Carriers.SKIP_464XLAT});
mc.addRow(new Object[]{
2163, // id
@@ -260,7 +262,8 @@
"", // mnvo_match_data
NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
0, // apn_set_id
- -1 // carrier_id
+ -1, // carrier_id
+ -1 // skip_464xlat
});
mc.addRow(new Object[]{
@@ -292,7 +295,8 @@
"", // mnvo_match_data
NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
0, // apn_set_id
- -1 // carrier_id
+ -1, // carrier_id
+ -1 // skip_464xlat
});
mc.addRow(new Object[]{
@@ -324,7 +328,8 @@
"", // mnvo_match_data
0, // network_type_bitmask
0, // apn_set_id
- -1 // carrier_id
+ -1, // carrier_id
+ -1 // skip_464xlat
});
mc.addRow(new Object[]{
@@ -356,7 +361,8 @@
"", // mnvo_match_data
NETWORK_TYPE_EHRPD_BITMASK, // network_type_bitmask
0, // apn_set_id
- -1 // carrier_id
+ -1, // carrier_id
+ -1 // skip_464xlat
});
mc.addRow(new Object[]{
@@ -388,7 +394,8 @@
"", // mnvo_match_data
0, // network_type_bitmask
0, // apn_set_id
- -1 // carrier_id
+ -1, // carrier_id
+ -1 // skip_464xlat
});
return mc;
@@ -422,6 +429,8 @@
doReturn("fake.action_attached").when(mPhone).getActionAttached();
doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
.getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mContextFixture.putStringArrayResource(com.android.internal.R.array.networkAttributes,
sNetworkAttributes);
@@ -443,6 +452,8 @@
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
doReturn(true).when(mSimRecords).getRecordsLoaded();
doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
@@ -592,8 +603,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -641,8 +651,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -666,8 +675,7 @@
dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN2, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -698,8 +706,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -752,8 +759,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -808,8 +814,7 @@
waitForMs(200);
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN3, 2, 64, 0, 0);
@@ -859,7 +864,7 @@
mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
waitForMs(100);
- verify(mSST, times(1)).registerForDataConnectionAttached(eq(mDct),
+ verify(mSST, times(1)).registerForDataConnectionAttached(eq(TransportType.WWAN), eq(mDct),
intArgumentCaptor.capture(), eq(null));
// Ideally this should send EVENT_DATA_CONNECTION_ATTACHED");
mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
@@ -878,7 +883,7 @@
// The auto attach flag should be reset after update
assertFalse(mDct.getAutoAttachOnCreation());
- verify(mSST, times(1)).registerForDataConnectionDetached(eq(mDct),
+ verify(mSST, times(1)).registerForDataConnectionDetached(eq(TransportType.WWAN), eq(mDct),
intArgumentCaptor.capture(), eq(null));
// Ideally this should send EVENT_DATA_CONNECTION_DETACHED
mDct.sendMessage(mDct.obtainMessage(intArgumentCaptor.getValue(), null));
@@ -916,8 +921,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -959,8 +963,7 @@
waitForMs(200);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), any(DataProfile.class),
+ eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
}
@@ -1013,8 +1016,7 @@
waitForMs(200);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), any(DataProfile.class),
+ eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
}
@@ -1135,8 +1137,8 @@
@SmallTest
public void testTrySetupDefaultOnIWLAN() throws Exception {
initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
@@ -1188,8 +1190,8 @@
@Test
@SmallTest
public void testUpdateWaitingApnListOnDataRatChange() throws Exception {
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1206,8 +1208,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
@@ -1215,8 +1216,8 @@
//data rat change from ehrpd to lte
logd("Sending EVENT_DATA_RAT_CHANGED");
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
waitForMs(200);
@@ -1239,8 +1240,7 @@
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1308,8 +1308,8 @@
@Test
@SmallTest
public void testDataRatChangeOOS() throws Exception {
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1326,8 +1326,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
// Verify if RIL command was sent properly.
verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
@@ -1335,8 +1334,8 @@
// Data rat change from ehrpd to unknown due to OOS
logd("Sending EVENT_DATA_RAT_CHANGED");
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
waitForMs(200);
@@ -1346,8 +1345,8 @@
any(Message.class));
// Data rat resume from unknown to ehrpd
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD).when(mServiceState)
- .getRilDataRadioTechnology();
+ doReturn(TelephonyManager.NETWORK_TYPE_EHRPD).when(mNetworkRegistrationState)
+ .getAccessNetworkTechnology();
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
waitForMs(200);
@@ -1434,9 +1433,6 @@
@Test
@SmallTest
public void testNetworkStatusChangedRecoveryOFF() throws Exception {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
-
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
@@ -1452,8 +1448,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1494,8 +1489,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1511,10 +1505,6 @@
waitForMs(200);
verify(mSimulatedCommandsVerifier, times(1)).getDataCallList(any(Message.class));
-
- // reset the setting at the end of this test
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
- waitForMs(200);
}
@FlakyTest
@@ -1541,8 +1531,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1556,10 +1545,6 @@
verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
any(Message.class));
-
- // reset the setting at the end of this test
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
- waitForMs(200);
}
@@ -1586,8 +1571,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1599,9 +1583,6 @@
// expected to get preferred network type
verify(mSST, times(1)).reRegisterNetwork(eq(null));
-
- // reset the setting at the end of this test
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
}
@Test
@@ -1627,8 +1608,7 @@
ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(ServiceState.rilRadioTechnologyToAccessNetworkType(
- mServiceState.getRilDataRadioTechnology())), dpCaptor.capture(),
+ eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
@@ -1640,9 +1620,6 @@
// expected to get preferred network type
verify(mSST, times(1)).powerOffRadioSafely();
-
- // reset the setting at the end of this test
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
}
private void verifyDataEnabledChangedMessage(boolean enabled, int reason) {
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 ab0d061..294c5bb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -34,7 +34,9 @@
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.stub.ImsConfigImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
@@ -44,10 +46,12 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import java.util.Hashtable;
+@RunWith(AndroidJUnit4.class)
public class ImsManagerTest extends TelephonyTest {
private static final String UNSET_PROVISIONED_STRING = "unset";
private static final boolean ENHANCED_4G_MODE_DEFAULT_VAL = true;
@@ -57,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;
@@ -78,6 +86,8 @@
super.setUp("ImsManagerTest");
mPhoneId = mPhone.getPhoneId();
mBundle = mContextFixture.getCarrierConfigBundle();
+ // Force MmTelFeatureConnection to create an executor using Looper.myLooper().
+ doReturn(null).when(mContext).getMainLooper();
doReturn(mSubId).when(mSubscriptionController).getSubId(mPhoneId);
@@ -101,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,
@@ -112,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
@@ -647,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/RcsMessageStoreControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
index 25cfb20..39ec048 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/RcsMessageStoreControllerTest.java
@@ -65,7 +65,7 @@
mContentResolver = (MockContentResolver) mContext.getContentResolver();
mContentResolver.addProvider("rcs", mFakeRcsProvider);
- mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver, null);
+ mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver);
}
@After
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index e8a002c..d1a33a0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -110,7 +110,7 @@
}
@Override
public void onLooperPrepared() {
- mCTUT = new ImsPhoneCallTracker(mImsPhone);
+ mCTUT = new ImsPhoneCallTracker(mImsPhone, Runnable::run);
mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
@@ -272,7 +272,7 @@
@SmallTest
public void testImsDeregistered() {
// when IMS is deregistered
- mRegistrationCallback.onDeregistered(new ImsReasonInfo());
+ mRegistrationCallback.onUnregistered(new ImsReasonInfo());
// then service state should be OUT_OF_SERVICE and ImsPhone state set to not registered
verify(mImsPhone).setServiceState(eq(ServiceState.STATE_OUT_OF_SERVICE));
verify(mImsPhone).setImsRegistered(eq(false));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 2555488..6432d05 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -285,7 +285,7 @@
mImsPhoneUT.dispose();
assertEquals(0, list.size());
verify(mImsCT).dispose();
- verify(mSST).unregisterForDataRegStateOrRatChanged(mImsPhoneUT);
+ verify(mSST, times(2)).unregisterForDataRegStateOrRatChanged(anyInt(), eq(mImsPhoneUT));
}
@Test
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");
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
index c95b91a..7cb6d78 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -109,8 +109,9 @@
mIccCardStatus.mImsSubscriptionAppIndex =
mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
mSimulatedCommands.setIccCardStatus(mIccCardStatus);
- // slotIndex should be invalid when testing with older versions (before 1.2) of hal
- mIccCardStatus.physicalSlotIndex = UiccController.INVALID_SLOT_ID;
+ // for testing we pretend slotIndex is set. In reality it would be invalid on older versions
+ // (before 1.2) of hal
+ mIccCardStatus.physicalSlotIndex = 0;
mUiccControllerHandlerThread = new UiccControllerHandlerThread(TAG);
mUiccControllerHandlerThread.start();
waitUntilReady();
@@ -235,6 +236,7 @@
ics.atr = "abcdef0123456789abcdef";
ics.iccid = "123451234567890";
ics.eid = "A1B2C3D4";
+ ics.physicalSlotIndex = 0;
AsyncResult ar = new AsyncResult(null, ics, null);
Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
mUiccControllerUT.handleMessage(msg);
@@ -325,6 +327,7 @@
ics.setUniversalPinState(3 /* disabled */);
ics.atr = "abcdef0123456789abcdef";
ics.iccid = "123451234567890";
+ ics.physicalSlotIndex = 0;
AsyncResult ar = new AsyncResult(null, ics, null);
Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
mUiccControllerUT.handleMessage(msg);