Merge "Fix ImsService Callback synchronization issues"
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
index abf91c9..59fdd0f 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -324,6 +324,7 @@
public Notification.Builder getNotificationBuilder() {
Context context = mPhone.getContext();
Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
+ notificationIntent.putExtra("expandable", true);
PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
PendingIntent.FLAG_ONE_SHOT);
CharSequence title = context.getText(
diff --git a/src/java/com/android/internal/telephony/IccCard.java b/src/java/com/android/internal/telephony/IccCard.java
index 7e98bc9..bef6afc 100644
--- a/src/java/com/android/internal/telephony/IccCard.java
+++ b/src/java/com/android/internal/telephony/IccCard.java
@@ -34,8 +34,8 @@
* Apps (those that have access to Phone object) can retrieve this object
* by calling phone.getIccCard()
*
- * This interface is implemented by IccCardProxy and the object PhoneApp
- * gets when it calls getIccCard is IccCardProxy.
+ * This interface is implemented by UiccProfile and the object PhoneApp
+ * gets when it calls getIccCard is UiccProfile.
*/
public interface IccCard {
/**
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index e6032a5..5e2850d 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -22,11 +22,12 @@
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.telephony.CarrierConfigManager;
-import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.Rlog;
import android.util.SparseArray;
import android.util.SparseIntArray;
+import java.util.ArrayList;
import java.util.Arrays;
/**
@@ -48,6 +49,8 @@
private final SparseArray<SparseIntArray> mRatFamilyMap = new SparseArray<>();
private final Phone mPhone;
+ private boolean mVoiceRatchetEnabled = true;
+ private boolean mDataRatchetEnabled = true;
/**
* Updates the ServiceState with a new set of cell bandwidths IFF the new bandwidth list has a
@@ -98,22 +101,37 @@
}
/** Ratchets RATs and cell bandwidths if oldSS and newSS have the same RAT family. */
- public void ratchet(ServiceState oldSS, ServiceState newSS) {
- int newVoiceRat = ratchetRat(oldSS.getRilVoiceRadioTechnology(),
- newSS.getRilVoiceRadioTechnology());
- int newDataRat = ratchetRat(oldSS.getRilDataRadioTechnology(),
- newSS.getRilDataRadioTechnology());
-
+ public void ratchet(ServiceState oldSS, ServiceState newSS, boolean locationChange) {
if (isSameRatFamily(oldSS, newSS)) {
updateBandwidths(oldSS.getCellBandwidths(), newSS);
}
+ // temporarily disable rat ratchet on location change.
+ if (locationChange) {
+ mVoiceRatchetEnabled = false;
+ mDataRatchetEnabled = false;
+ return;
+ }
+ if (mVoiceRatchetEnabled) {
+ int newVoiceRat = ratchetRat(oldSS.getRilVoiceRadioTechnology(),
+ newSS.getRilVoiceRadioTechnology());
+ newSS.setRilVoiceRadioTechnology(newVoiceRat);
+ } else if (oldSS.getRilVoiceRadioTechnology() != newSS.getRilVoiceRadioTechnology()) {
+ // resume rat ratchet on following rat change within the same location
+ mVoiceRatchetEnabled = true;
+ }
+
+ if (mDataRatchetEnabled) {
+ int newDataRat = ratchetRat(oldSS.getRilDataRadioTechnology(),
+ newSS.getRilDataRadioTechnology());
+ newSS.setRilDataRadioTechnology(newDataRat);
+ } else if (oldSS.getRilVoiceRadioTechnology() != newSS.getRilVoiceRadioTechnology()) {
+ // resume rat ratchet on following rat change within the same location
+ mVoiceRatchetEnabled = true;
+ }
boolean newUsingCA = oldSS.isUsingCarrierAggregation()
|| newSS.isUsingCarrierAggregation()
|| newSS.getCellBandwidths().length > 1;
-
- newSS.setRilVoiceRadioTechnology(newVoiceRat);
- newSS.setRilDataRadioTechnology(newDataRat);
newSS.setIsUsingCarrierAggregation(newUsingCA);
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 9c5b558..dbc06e3 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -139,7 +139,8 @@
* and ignore stale responses. The value is a count-down of
* expected responses in this pollingContext.
*/
- private int[] mPollingContext;
+ @VisibleForTesting
+ public int[] mPollingContext;
private boolean mDesiredPowerState;
/**
@@ -2655,8 +2656,8 @@
// ratchet the new tech up through its rat family but don't drop back down
// until cell change or device is OOS
boolean isDataInService = mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
- if (!hasLocationChanged && isDataInService) {
- mRatRatcheter.ratchet(mSS, mNewSS);
+ if (isDataInService) {
+ mRatRatcheter.ratchet(mSS, mNewSS, hasLocationChanged);
}
boolean hasRilVoiceRadioTechnologyChanged =
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index e379a69..d996fb3 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -29,7 +29,6 @@
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
-import com.android.internal.telephony.uicc.IccCardProxy;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccProfile;
@@ -100,10 +99,6 @@
return new IccSmsInterfaceManager(phone);
}
- public IccCardProxy makeIccCardProxy(Context context, CommandsInterface ci, int phoneId) {
- return new IccCardProxy(context, ci, phoneId);
- }
-
/**
* Create a new UiccProfile object.
*/
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 8a101b7..496336f 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -39,6 +39,7 @@
import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.telephony.AccessNetworkConstants;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -1838,10 +1839,26 @@
KeepalivePacketData pkt = (KeepalivePacketData) msg.obj;
int slotId = msg.arg1;
int intervalMillis = msg.arg2 * 1000;
- mPhone.mCi.startNattKeepalive(
- DataConnection.this.mCid, pkt, intervalMillis,
- DataConnection.this.obtainMessage(
- EVENT_KEEPALIVE_STARTED, slotId, 0, null));
+ if (mDataServiceManager.getTransportType()
+ == AccessNetworkConstants.TransportType.WWAN) {
+ mPhone.mCi.startNattKeepalive(
+ DataConnection.this.mCid, pkt, intervalMillis,
+ DataConnection.this.obtainMessage(
+ EVENT_KEEPALIVE_STARTED, slotId, 0, null));
+ } else {
+ // We currently do not support NATT Keepalive requests using the
+ // DataService API, so unless the request is WWAN (always bound via
+ // the CommandsInterface), the request cannot be honored.
+ //
+ // TODO: b/72331356 to add support for Keepalive to the DataService
+ // so that keepalive requests can be handled (if supported) by the
+ // underlying transport.
+ if (mNetworkAgent != null) {
+ mNetworkAgent.onPacketKeepaliveEvent(
+ msg.arg1,
+ ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
+ }
+ }
retVal = HANDLED;
break;
}
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardProxy.java b/src/java/com/android/internal/telephony/uicc/IccCardProxy.java
deleted file mode 100644
index f9629e7..0000000
--- a/src/java/com/android/internal/telephony/uicc/IccCardProxy.java
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.uicc;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.UserHandle;
-import android.telephony.Rlog;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.CommandsInterface.RadioState;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
-import com.android.internal.telephony.uicc.IccCardStatus.CardState;
-import com.android.internal.telephony.uicc.IccCardStatus.PinState;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * @Deprecated use {@link UiccController}.getUiccCard instead.
- *
- * The Phone App assumes that there is only one icc card, and one icc application
- * available at a time. Moreover, it assumes such object (represented with IccCard)
- * is available all the time (whether {@link RILConstants#RIL_REQUEST_GET_SIM_STATUS} returned
- * or not, whether card has desired application or not, whether there really is a card in the
- * slot or not).
- *
- * UiccController, however, can handle multiple instances of icc objects (multiple
- * {@link UiccCardApplication}, multiple {@link IccFileHandler}, multiple {@link IccRecords})
- * created and destroyed dynamically during phone operation.
- *
- * This class implements the IccCard interface that is always available (right after default
- * phone object is constructed) to expose the current (based on voice radio technology)
- * application on the uicc card, so that external apps won't break.
- */
-
-public class IccCardProxy extends Handler implements IccCard {
- private static final boolean DBG = true;
- private static final String LOG_TAG = "IccCardProxy";
-
- private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 1;
- private static final int EVENT_RADIO_ON = 2;
- private static final int EVENT_ICC_CHANGED = 3;
- private static final int EVENT_ICC_ABSENT = 4;
- private static final int EVENT_ICC_LOCKED = 5;
- private static final int EVENT_APP_READY = 6;
- private static final int EVENT_RECORDS_LOADED = 7;
- private static final int EVENT_IMSI_READY = 8;
- private static final int EVENT_NETWORK_LOCKED = 9;
-
- private static final int EVENT_ICC_RECORD_EVENTS = 500;
- private static final int EVENT_CARRIER_PRIVILEGES_LOADED = 503;
-
- private Integer mPhoneId = null;
-
- private final Object mLock = new Object();
- private Context mContext;
- private CommandsInterface mCi;
- private TelephonyManager mTelephonyManager;
-
- private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
-
- private int mCurrentAppType = UiccController.APP_FAM_3GPP; //default to 3gpp?
- private UiccController mUiccController = null;
- private UiccSlot mUiccSlot = null;
- private UiccCard mUiccCard = null;
- private UiccCardApplication mUiccApplication = null;
- private IccRecords mIccRecords = null;
- private RadioState mRadioState = RadioState.RADIO_UNAVAILABLE;
- private boolean mInitialized = false;
- private State mExternalState = State.UNKNOWN;
-
- public static final String ACTION_INTERNAL_SIM_STATE_CHANGED = "android.intent.action.internal_sim_state_changed";
-
- public IccCardProxy(Context context, CommandsInterface ci, int phoneId) {
- if (DBG) log("ctor: ci=" + ci + " phoneId=" + phoneId);
- mContext = context;
- mCi = ci;
- mPhoneId = phoneId;
- mTelephonyManager = (TelephonyManager) mContext.getSystemService(
- Context.TELEPHONY_SERVICE);
- mUiccController = UiccController.getInstance();
- mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
- ci.registerForOn(this,EVENT_RADIO_ON, null);
- ci.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
-
- resetProperties();
- }
-
- public void dispose() {
- synchronized (mLock) {
- log("Disposing");
- //Cleanup icc references
- mUiccController.unregisterForIccChanged(this);
- mUiccController = null;
- mCi.unregisterForOn(this);
- mCi.unregisterForOffOrNotAvailable(this);
- }
- }
-
- /*
- * The card application that the external world sees will be based on the
- * voice radio technology only!
- */
- public void setVoiceRadioTech(int radioTech) {
- synchronized (mLock) {
- if (DBG) {
- log("Setting radio tech " + ServiceState.rilRadioTechnologyToString(radioTech));
- }
- if (ServiceState.isGsm(radioTech)) {
- mCurrentAppType = UiccController.APP_FAM_3GPP;
- } else {
- mCurrentAppType = UiccController.APP_FAM_3GPP2;
- }
- updateCurrentAppType();
- }
- }
-
- /**
- * Update current app type and post EVENT_ICC_CHANGED.
- */
- private void updateCurrentAppType() {
- synchronized (mLock) {
- boolean isLteOnCdmaMode = TelephonyManager.getLteOnCdmaModeStatic()
- == PhoneConstants.LTE_ON_CDMA_TRUE;
- if (mCurrentAppType == UiccController.APP_FAM_3GPP2) {
- if (isLteOnCdmaMode) {
- log("updateCurrentAppType: is cdma/lte device, force IccCardProxy into 3gpp"
- + " mode");
- mCurrentAppType = UiccController.APP_FAM_3GPP;
- }
-
- if (DBG) {
- log("updateCurrentAppType: "
- + " mCurrentAppType=" + mCurrentAppType
- + " isLteOnCdmaMode=" + isLteOnCdmaMode);
- }
- }
-
- mInitialized = true;
- sendMessage(obtainMessage(EVENT_ICC_CHANGED));
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_RADIO_OFF_OR_UNAVAILABLE:
- mRadioState = mCi.getRadioState();
- updateExternalState();
- break;
- case EVENT_RADIO_ON:
- mRadioState = RadioState.RADIO_ON;
- if (!mInitialized) {
- updateCurrentAppType();
- } else {
- // updateCurrentAppType() triggers ICC_CHANGED, which eventually
- // calls updateExternalState; thus, we don't need this in the
- // above case
- updateExternalState();
- }
- break;
- case EVENT_ICC_CHANGED:
- if (mInitialized) {
- updateIccAvailability();
- }
- break;
- case EVENT_ICC_ABSENT:
- setExternalState(State.ABSENT);
- break;
- case EVENT_ICC_LOCKED:
- processLockedState();
- break;
- case EVENT_APP_READY:
- setExternalState(State.READY);
- break;
- case EVENT_RECORDS_LOADED:
- // Update the MCC/MNC.
- if (mIccRecords != null) {
- String operator = mIccRecords.getOperatorNumeric();
- log("operator=" + operator + " mPhoneId=" + mPhoneId);
-
- if (!TextUtils.isEmpty(operator)) {
- mTelephonyManager.setSimOperatorNumericForPhone(mPhoneId, operator);
- String countryCode = operator.substring(0,3);
- if (countryCode != null) {
- mTelephonyManager.setSimCountryIsoForPhone(mPhoneId,
- MccTable.countryCodeForMcc(Integer.parseInt(countryCode)));
- } else {
- loge("EVENT_RECORDS_LOADED Country code is null");
- }
- } else {
- loge("EVENT_RECORDS_LOADED Operator name is null");
- }
- }
- if (mUiccCard != null && !mUiccCard.areCarrierPriviligeRulesLoaded()) {
- mUiccCard.registerForCarrierPrivilegeRulesLoaded(
- this, EVENT_CARRIER_PRIVILEGES_LOADED, null);
- } else {
- setExternalState(State.LOADED);
- }
- break;
- case EVENT_IMSI_READY:
- broadcastInternalIccStateChangedIntent(IccCardConstants.INTENT_VALUE_ICC_IMSI,
- null);
- break;
- case EVENT_NETWORK_LOCKED:
- mNetworkLockedRegistrants.notifyRegistrants();
- setExternalState(State.NETWORK_LOCKED);
- break;
- case EVENT_ICC_RECORD_EVENTS:
- if ((mCurrentAppType == UiccController.APP_FAM_3GPP) && (mIccRecords != null)) {
- AsyncResult ar = (AsyncResult)msg.obj;
- int eventCode = (Integer) ar.result;
- if (eventCode == SIMRecords.EVENT_SPN) {
- mTelephonyManager.setSimOperatorNameForPhone(
- mPhoneId, mIccRecords.getServiceProviderName());
- }
- }
- break;
-
- case EVENT_CARRIER_PRIVILEGES_LOADED:
- log("EVENT_CARRIER_PRIVILEGES_LOADED");
- if (mUiccCard != null) {
- mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this);
- }
- setExternalState(State.LOADED);
- break;
-
- default:
- loge("Unhandled message with number: " + msg.what);
- break;
- }
- }
-
- private void updateIccAvailability() {
- synchronized (mLock) {
- UiccSlot newSlot = mUiccController.getUiccSlotForPhone(mPhoneId);
- UiccCard newCard = mUiccController.getUiccCard(mPhoneId);
- UiccCardApplication newApp = null;
- IccRecords newRecords = null;
- if (newCard != null) {
- newApp = newCard.getApplication(mCurrentAppType);
- if (newApp != null) {
- newRecords = newApp.getIccRecords();
- }
- }
-
- if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard
- || mUiccSlot != newSlot) {
- if (DBG) log("Icc changed. Reregistering.");
- unregisterUiccCardEvents();
- mUiccSlot = newSlot;
- mUiccCard = newCard;
- mUiccApplication = newApp;
- mIccRecords = newRecords;
- registerUiccCardEvents();
- }
- updateExternalState();
- }
- }
-
- void resetProperties() {
- if (mCurrentAppType == UiccController.APP_FAM_3GPP) {
- log("update icc_operator_numeric=" + "");
- mTelephonyManager.setSimOperatorNumericForPhone(mPhoneId, "");
- mTelephonyManager.setSimCountryIsoForPhone(mPhoneId, "");
- mTelephonyManager.setSimOperatorNameForPhone(mPhoneId, "");
- }
- }
-
- private void HandleDetectedState() {
- // CAF_MSIM SAND
-// setExternalState(State.DETECTED, false);
- }
-
- private void updateExternalState() {
-
- // mUiccCard could be null at bootup, before valid card states have
- // been received from UiccController.
- if (mUiccCard == null) {
- setExternalState(State.UNKNOWN);
- return;
- }
-
- if (mUiccCard.getCardState() == CardState.CARDSTATE_ABSENT) {
- /*
- * Both IccCardProxy and UiccController are registered for
- * RadioState changes. When the UiccController receives a radio
- * state changed to Unknown it will dispose of all of the IccCard
- * objects, which will then notify the IccCardProxy and the null
- * object will force the state to unknown. However, because the
- * IccCardProxy is also registered for RadioState changes, it will
- * recieve that signal first. By triggering on radio state changes
- * directly, we reduce the time window during which the modem is
- * UNAVAILABLE but the IccStatus is reported as something valid.
- * This is not ideal.
- */
- if (mRadioState == RadioState.RADIO_UNAVAILABLE) {
- setExternalState(State.UNKNOWN);
- } else {
- setExternalState(State.ABSENT);
- }
- return;
- }
-
- if (mUiccCard.getCardState() == CardState.CARDSTATE_ERROR) {
- setExternalState(State.CARD_IO_ERROR);
- return;
- }
-
- if (mUiccCard.getCardState() == CardState.CARDSTATE_RESTRICTED) {
- setExternalState(State.CARD_RESTRICTED);
- return;
- }
-
- if (mUiccApplication == null) {
- setExternalState(State.NOT_READY);
- return;
- }
-
- // By process of elimination, the UICC Card State = PRESENT
- switch (mUiccApplication.getState()) {
- case APPSTATE_UNKNOWN:
- /*
- * APPSTATE_UNKNOWN is a catch-all state reported whenever the app
- * is not explicitly in one of the other states. To differentiate the
- * case where we know that there is a card present, but the APP is not
- * ready, we choose NOT_READY here instead of unknown. This is possible
- * in at least two cases:
- * 1) A transient during the process of the SIM bringup
- * 2) There is no valid App on the SIM to load, which can be the case with an
- * eSIM/soft SIM.
- */
- setExternalState(State.NOT_READY);
- break;
- case APPSTATE_DETECTED:
- HandleDetectedState();
- break;
- case APPSTATE_SUBSCRIPTION_PERSO:
- if (mUiccApplication.getPersoSubState() ==
- PersoSubState.PERSOSUBSTATE_SIM_NETWORK) {
- setExternalState(State.NETWORK_LOCKED);
- }
- // Otherwise don't change external SIM state.
- break;
- case APPSTATE_READY:
- setExternalState(State.READY);
- break;
- }
- }
-
- private void registerUiccCardEvents() {
- if (mUiccApplication != null) {
- mUiccApplication.registerForReady(this, EVENT_APP_READY, null);
- }
- if (mIccRecords != null) {
- mIccRecords.registerForImsiReady(this, EVENT_IMSI_READY, null);
- mIccRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- mIccRecords.registerForLockedRecordsLoaded(this, EVENT_ICC_LOCKED, null);
- mIccRecords.registerForNetworkLockedRecordsLoaded(this, EVENT_NETWORK_LOCKED, null);
- mIccRecords.registerForRecordsEvents(this, EVENT_ICC_RECORD_EVENTS, null);
- }
- }
-
- private void unregisterUiccCardEvents() {
- if (mUiccCard != null) mUiccCard.unregisterForCarrierPrivilegeRulesLoaded(this);
- if (mUiccApplication != null) {
- mUiccApplication.unregisterForReady(this);
- }
- if (mIccRecords != null) {
- mIccRecords.unregisterForImsiReady(this);
- mIccRecords.unregisterForRecordsLoaded(this);
- mIccRecords.unregisterForLockedRecordsLoaded(this);
- mIccRecords.unregisterForNetworkLockedRecordsLoaded(this);
- mIccRecords.unregisterForRecordsEvents(this);
- }
- }
-
- private void broadcastInternalIccStateChangedIntent(String value, String reason) {
- synchronized (mLock) {
- if (mPhoneId == null) {
- loge("broadcastInternalIccStateChangedIntent: Card Index is not set; Return!!");
- return;
- }
-
- Intent intent = new Intent(ACTION_INTERNAL_SIM_STATE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
- intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
- intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
- intent.putExtra(PhoneConstants.PHONE_KEY, mPhoneId); // SubId may not be valid.
- log("broadcastInternalIccStateChangedIntent: Sending intent "
- + "ACTION_INTERNAL_SIM_STATE_CHANGED value = " + value
- + " for mPhoneId : " + mPhoneId);
- ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
- }
- }
-
- private void setExternalState(State newState, boolean override) {
- synchronized (mLock) {
- if (mPhoneId == null || !SubscriptionManager.isValidSlotIndex(mPhoneId)) {
- loge("setExternalState: mPhoneId=" + mPhoneId + " is invalid; Return!!");
- return;
- }
-
- if (!override && newState == mExternalState) {
- log("setExternalState: !override and newstate unchanged from " + newState);
- return;
- }
- mExternalState = newState;
- log("setExternalState: set mPhoneId=" + mPhoneId + " mExternalState=" + mExternalState);
- mTelephonyManager.setSimStateForPhone(mPhoneId, getState().toString());
-
- broadcastInternalIccStateChangedIntent(getIccStateIntentString(mExternalState),
- getIccStateReason(mExternalState));
- }
- }
-
- private void processLockedState() {
- synchronized (mLock) {
- if (mUiccApplication == null) {
- //Don't need to do anything if non-existent application is locked
- return;
- }
- PinState pin1State = mUiccApplication.getPin1State();
- if (pin1State == PinState.PINSTATE_ENABLED_PERM_BLOCKED) {
- setExternalState(State.PERM_DISABLED);
- return;
- }
-
- AppState appState = mUiccApplication.getState();
- switch (appState) {
- case APPSTATE_PIN:
- setExternalState(State.PIN_REQUIRED);
- break;
- case APPSTATE_PUK:
- setExternalState(State.PUK_REQUIRED);
- break;
- case APPSTATE_DETECTED:
- case APPSTATE_READY:
- case APPSTATE_SUBSCRIPTION_PERSO:
- case APPSTATE_UNKNOWN:
- // Neither required
- break;
- }
- }
- }
-
- private void setExternalState(State newState) {
- setExternalState(newState, false);
- }
-
- public boolean getIccRecordsLoaded() {
- synchronized (mLock) {
- if (mIccRecords != null) {
- return mIccRecords.getRecordsLoaded();
- }
- return false;
- }
- }
-
- private String getIccStateIntentString(State state) {
- switch (state) {
- case ABSENT: return IccCardConstants.INTENT_VALUE_ICC_ABSENT;
- case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
- case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
- case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
- case READY: return IccCardConstants.INTENT_VALUE_ICC_READY;
- case NOT_READY: return IccCardConstants.INTENT_VALUE_ICC_NOT_READY;
- case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ICC_LOCKED;
- case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR;
- case CARD_RESTRICTED: return IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED;
- case LOADED: return IccCardConstants.INTENT_VALUE_ICC_LOADED;
- default: return IccCardConstants.INTENT_VALUE_ICC_UNKNOWN;
- }
- }
-
- /**
- * Locked state have a reason (PIN, PUK, NETWORK, PERM_DISABLED, CARD_IO_ERROR)
- * @return reason
- */
- private String getIccStateReason(State state) {
- switch (state) {
- case PIN_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN;
- case PUK_REQUIRED: return IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK;
- case NETWORK_LOCKED: return IccCardConstants.INTENT_VALUE_LOCKED_NETWORK;
- case PERM_DISABLED: return IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED;
- case CARD_IO_ERROR: return IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR;
- case CARD_RESTRICTED: return IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED;
- default: return null;
- }
- }
-
- /* IccCard interface implementation */
- @Override
- public State getState() {
- synchronized (mLock) {
- return mExternalState;
- }
- }
-
- @Override
- public IccRecords getIccRecords() {
- synchronized (mLock) {
- return mIccRecords;
- }
- }
-
- /**
- * Notifies handler of any transition into State.NETWORK_LOCKED
- */
- @Override
- public void registerForNetworkLocked(Handler h, int what, Object obj) {
- synchronized (mLock) {
- Registrant r = new Registrant (h, what, obj);
-
- mNetworkLockedRegistrants.add(r);
-
- if (getState() == State.NETWORK_LOCKED) {
- r.notifyRegistrant();
- }
- }
- }
-
- @Override
- public void unregisterForNetworkLocked(Handler h) {
- synchronized (mLock) {
- mNetworkLockedRegistrants.remove(h);
- }
- }
-
- @Override
- public void supplyPin(String pin, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.supplyPin(pin, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void supplyPuk(String puk, String newPin, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.supplyPuk(puk, newPin, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void supplyPin2(String pin2, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.supplyPin2(pin2, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void supplyPuk2(String puk2, String newPin2, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.supplyPuk2(puk2, newPin2, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void supplyNetworkDepersonalization(String pin, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.supplyNetworkDepersonalization(pin, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("CommandsInterface is not set.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public boolean getIccLockEnabled() {
- synchronized (mLock) {
- /* defaults to false, if ICC is absent/deactivated */
- Boolean retValue = mUiccApplication != null ?
- mUiccApplication.getIccLockEnabled() : false;
- return retValue;
- }
- }
-
- @Override
- public boolean getIccFdnEnabled() {
- synchronized (mLock) {
- Boolean retValue = mUiccApplication != null ?
- mUiccApplication.getIccFdnEnabled() : false;
- return retValue;
- }
- }
-
- public boolean getIccPin2Blocked() {
- /* defaults to disabled */
- Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccPin2Blocked() : false;
- return retValue;
- }
-
- public boolean getIccPuk2Blocked() {
- /* defaults to disabled */
- Boolean retValue = mUiccApplication != null ? mUiccApplication.getIccPuk2Blocked() : false;
- return retValue;
- }
-
- @Override
- public void setIccLockEnabled(boolean enabled, String password, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.setIccLockEnabled(enabled, password, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void setIccFdnEnabled(boolean enabled, String password, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.setIccFdnEnabled(enabled, password, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void changeIccLockPassword(String oldPassword, String newPassword, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.changeIccLockPassword(oldPassword, newPassword, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public void changeIccFdnPassword(String oldPassword, String newPassword, Message onComplete) {
- synchronized (mLock) {
- if (mUiccApplication != null) {
- mUiccApplication.changeIccFdnPassword(oldPassword, newPassword, onComplete);
- } else if (onComplete != null) {
- Exception e = new RuntimeException("ICC card is absent.");
- AsyncResult.forMessage(onComplete).exception = e;
- onComplete.sendToTarget();
- return;
- }
- }
- }
-
- @Override
- public String getServiceProviderName() {
- synchronized (mLock) {
- if (mIccRecords != null) {
- return mIccRecords.getServiceProviderName();
- }
- return null;
- }
- }
-
- @Override
- public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
- synchronized (mLock) {
- Boolean retValue = mUiccCard != null ? mUiccCard.isApplicationOnIcc(type) : false;
- return retValue;
- }
- }
-
- @Override
- public boolean hasIccCard() {
- synchronized (mLock) {
- if (mUiccCard != null && mUiccCard.getCardState() != CardState.CARDSTATE_ABSENT) {
- return true;
- }
- return false;
- }
- }
-
- private void log(String s) {
- Rlog.d(LOG_TAG, s);
- }
-
- private void loge(String msg) {
- Rlog.e(LOG_TAG, msg);
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("IccCardProxy: " + this);
- pw.println(" mContext=" + mContext);
- pw.println(" mCi=" + mCi);
- pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
- for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
- pw.println(" mNetworkLockedRegistrants[" + i + "]="
- + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler());
- }
- pw.println(" mCurrentAppType=" + mCurrentAppType);
- pw.println(" mUiccController=" + mUiccController);
- pw.println(" mUiccCard=" + mUiccCard);
- pw.println(" mUiccApplication=" + mUiccApplication);
- pw.println(" mIccRecords=" + mIccRecords);
- pw.println(" mRadioState=" + mRadioState);
- pw.println(" mInitialized=" + mInitialized);
- pw.println(" mExternalState=" + mExternalState);
-
- pw.flush();
- }
-}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 8e3fb96..a217c34 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -198,6 +198,10 @@
}
}
+ public boolean isExtendedApduSupported() {
+ return (mAtr != null && mAtr.isExtendedApduSupported());
+ }
+
@Override
protected void finalize() {
if (DBG) log("UiccSlot finalized");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 74aec16..ac116ad 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -158,6 +158,10 @@
mBundle.putStringArray(
CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});
+ mBundle.putStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES,
+ // UMTS < GPRS < EDGE
+ new String[]{"3,1,2"});
+
mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
@@ -1330,4 +1334,130 @@
assertTrue(actualNitzSignal.mElapsedRealtime <= SystemClock.elapsedRealtime());
}
}
+
+ // Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
+ // Expect no rat update when move from E to G.
+ @Test
+ public void testRatRatchet() throws Exception {
+ CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
+ NetworkRegistrationState dataResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, 1);
+ sst.mPollingContext[0] = 2;
+ // update data reg state to be in service
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ NetworkRegistrationState voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());
+
+ // EDGE -> GPRS
+ voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 1, 0, false, null,
+ cellIdentity, false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());
+ }
+
+ // Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
+ // Bypass rat rachet when cell id changed. Expect rat update from E to G
+ @Test
+ public void testRatRatchetWithCellChange() throws Exception {
+ CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
+ NetworkRegistrationState dataResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, 1);
+ sst.mPollingContext[0] = 2;
+ // update data reg state to be in service
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ NetworkRegistrationState voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());
+
+ // RAT: EDGE -> GPRS cell ID: -1 -> 5
+ cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
+ voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 1, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
+ }
+
+ // Edge, GPRS and UMTS are grouped under the same family where Edge > GPRS > UMTS .
+ // Expect no rat update from E to G immediately following cell id change.
+ // Expect ratratchet (from G to UMTS) for the following rat update within the cell location.
+ @Test
+ public void testRatRatchetWithCellChangeBeforeRatChange() throws Exception {
+ // cell ID update
+ CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
+ NetworkRegistrationState dataResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, 1);
+ sst.mPollingContext[0] = 2;
+ // update data reg state to be in service
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ NetworkRegistrationState voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());
+
+ // RAT: EDGE -> GPRS, cell ID unchanged. Expect no rat ratchet following cell Id change.
+ voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 1, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
+
+ // RAT: GPRS -> UMTS
+ voiceResult = new NetworkRegistrationState(
+ 0, 0, 1, 3, 0, false, null, cellIdentity, false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());
+
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 0f75a94..782d489 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -64,7 +64,6 @@
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.test.SimulatedCommandsVerifier;
-import com.android.internal.telephony.uicc.IccCardProxy;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IsimUiccRecords;
@@ -109,8 +108,6 @@
@Mock
protected UiccController mUiccController;
@Mock
- protected IccCardProxy mIccCardProxy;
- @Mock
protected UiccProfile mUiccProfile;
@Mock
protected CallManager mCallManager;
@@ -328,9 +325,6 @@
doReturn(mSST).when(mTelephonyComponentFactory)
.makeServiceStateTracker(nullable(GsmCdmaPhone.class),
nullable(CommandsInterface.class));
- doReturn(mIccCardProxy).when(mTelephonyComponentFactory)
- .makeIccCardProxy(nullable(Context.class), nullable(CommandsInterface.class),
- anyInt());
doReturn(mUiccProfile).when(mTelephonyComponentFactory)
.makeUiccProfile(nullable(Context.class), nullable(CommandsInterface.class),
nullable(IccCardStatus.class), anyInt(), nullable(UiccCard.class));
@@ -419,7 +413,7 @@
doReturn(mRuimRecords).when(mUiccCardApplication3gpp2).getIccRecords();
doReturn(mIsimUiccRecords).when(mUiccCardApplicationIms).getIccRecords();
- //mIccCardProxy
+ //mUiccProfile
doReturn(mSimRecords).when(mUiccProfile).getIccRecords();
doAnswer(new Answer<IccRecords>() {
public IccRecords answer(InvocationOnMock invocation) {
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 f13d2c2..0097ef6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -35,6 +35,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -524,6 +525,36 @@
assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
}
+ @Test
+ @SmallTest
+ public void testStartKeepaliveWLAN() throws Exception {
+ testConnectEvent();
+ waitForMs(200);
+
+ DataServiceManager mockDsm = mock(DataServiceManager.class);
+ doReturn(TransportType.WLAN).when(mockDsm).getTransportType();
+ replaceInstance(DataConnection.class, "mDataServiceManager", mDc, mockDsm);
+
+ final int sessionHandle = 0xF00;
+ final int slotId = 3;
+ final int interval = 10; // seconds
+ // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
+ // and check that the packet is sent to the RIL.
+ KeepalivePacketData kd = KeepalivePacketData.nattKeepalivePacket(
+ NetworkUtils.numericToInetAddress("1.2.3.4"),
+ 1234,
+ NetworkUtils.numericToInetAddress("8.8.8.8"),
+ 4500);
+ mDc.obtainMessage(
+ DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
+ waitForMs(100);
+ // testStartStopNattKeepalive() verifies that this request is passed with WWAN.
+ // Thus, even though we can't see the response in NetworkAgent, we can verify that the
+ // CommandsInterface never receives a request and infer that it was dropped due to WLAN.
+ verify(mSimulatedCommandsVerifier, times(0))
+ .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
+ }
+
public void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception {
testConnectEvent();
waitForMs(200);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardProxyTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardProxyTest.java
deleted file mode 100644
index 479acb7..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardProxyTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.telephony.uicc;
-
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doReturn;
-
-import android.os.HandlerThread;
-import android.support.test.filters.FlakyTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
-import com.android.internal.telephony.uicc.IccCardStatus.CardState;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mock;
-
-public class IccCardProxyTest extends TelephonyTest {
- private IccCardProxy mIccCardProxyUT;
- // private UiccCard mUiccCard;
- private IccCardProxyHandlerThread mIccCardProxyHandlerThread;
- private static final int PHONE_ID = 0;
- private static final int PHONE_COUNT = 1;
-
- private static final int SCARY_SLEEP_MS = 200;
- // Must match IccCardProxy.EVENT_ICC_CHANGED
- private static final int EVENT_ICC_CHANGED = 3;
-
- @Mock private IccCardStatus mIccCardStatus;
- @Mock private UiccCard mUiccCard;
- @Mock private UiccCardApplication mUiccCardApplication;
-
- private class IccCardProxyHandlerThread extends HandlerThread {
-
- private IccCardProxyHandlerThread(String name) {
- super(name);
- }
-
- @Override
- public void onLooperPrepared() {
- /* create a new UICC Controller associated with the simulated Commands */
- mIccCardProxyUT = new IccCardProxy(mContext, mSimulatedCommands, PHONE_ID);
- setReady(true);
- }
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp(this.getClass().getSimpleName());
- doReturn(PHONE_COUNT).when(mTelephonyManager).getPhoneCount();
- doReturn(PHONE_COUNT).when(mTelephonyManager).getSimCount();
- mSimulatedCommands.setIccCardStatus(mIccCardStatus);
- mIccCardProxyHandlerThread = new IccCardProxyHandlerThread(TAG);
- mIccCardProxyHandlerThread.start();
- waitUntilReady();
- }
-
- @After
- public void tearDown() throws Exception {
- mIccCardProxyHandlerThread.quitSafely();
- super.tearDown();
- }
-
- @Test
- @SmallTest
- public void testInitialCardState() {
- assertEquals(mIccCardProxyUT.getState(), State.UNKNOWN);
- }
-
- @Test
- @Ignore
- @FlakyTest
- @SmallTest
- public void testPowerOn() {
- mSimulatedCommands.setRadioPower(true, null);
- mSimulatedCommands.notifyRadioOn();
- doReturn(mUiccCard).when(mUiccController).getUiccCard(anyInt());
- mIccCardProxyUT.sendMessage(mIccCardProxyUT.obtainMessage(EVENT_ICC_CHANGED));
-
- waitForMs(SCARY_SLEEP_MS);
- assertEquals(CommandsInterface.RadioState.RADIO_ON, mSimulatedCommands.getRadioState());
- assertEquals(mIccCardProxyUT.getState(), State.NOT_READY);
- logd("IccCardProxy state = " + mIccCardProxyUT.getState());
- }
-
- @Test
- @Ignore
- @FlakyTest
- @SmallTest
- public void testCardLoaded() {
- testPowerOn();
- doReturn(CardState.CARDSTATE_PRESENT).when(mUiccCard).getCardState();
- mIccCardProxyUT.sendMessage(mIccCardProxyUT.obtainMessage(EVENT_ICC_CHANGED));
-
- waitForMs(SCARY_SLEEP_MS);
- assertEquals(mIccCardProxyUT.getState(), State.NOT_READY);
- }
-
- @Test
- @Ignore
- @FlakyTest
- @SmallTest
- public void testAppNotLoaded() {
- testPowerOn();
- doReturn(CardState.CARDSTATE_PRESENT).when(mUiccCard).getCardState();
- mIccCardProxyUT.sendMessage(mIccCardProxyUT.obtainMessage(EVENT_ICC_CHANGED));
- doReturn(AppState.APPSTATE_UNKNOWN).when(mUiccCardApplication).getState();
- doReturn(mUiccCardApplication).when(mUiccCard).getApplication(anyInt());
-
- waitForMs(SCARY_SLEEP_MS);
- assertEquals(mIccCardProxyUT.getState(), State.NOT_READY);
- }
-
- @Test
- @Ignore
- @FlakyTest
- @SmallTest
- public void testAppReady() {
- testPowerOn();
- doReturn(CardState.CARDSTATE_PRESENT).when(mUiccCard).getCardState();
- mIccCardProxyUT.sendMessage(mIccCardProxyUT.obtainMessage(EVENT_ICC_CHANGED));
- doReturn(AppState.APPSTATE_READY).when(mUiccCardApplication).getState();
- doReturn(mUiccCardApplication).when(mUiccCard).getApplication(anyInt());
-
- waitForMs(SCARY_SLEEP_MS);
- assertEquals(mIccCardProxyUT.getState(), State.READY);
- }
-}