Merge "Add NR to CellInfo"
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index f0c6262..7004ef2 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -754,7 +754,6 @@
@Override
public void registerForNetworkScanResult(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
mRilNetworkScanResultRegistrants.addUnique(h, what, obj);
}
@@ -983,8 +982,6 @@
@Override
public void registerForNattKeepaliveStatus(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
-
synchronized (mStateMonitor) {
mNattKeepaliveStatusRegistrants.addUnique(h, what, obj);
}
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index 0393ffa..5eb0456 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -129,9 +129,15 @@
mPackageMonitor.register(
context, mHandler.getLooper(), UserHandle.ALL, false /* externalStorage */);
- mContext.registerReceiverAsUser(mUserUnlockedReceiver, UserHandle.SYSTEM,
+ try {
+ Context contextAsUser = mContext.createPackageContextAsUser(mContext.getPackageName(),
+ 0, UserHandle.SYSTEM);
+ contextAsUser.registerReceiver(mUserUnlockedReceiver,
new IntentFilter(Intent.ACTION_USER_UNLOCKED), null /* broadcastPermission */,
mHandler);
+ } catch (PackageManager.NameNotFoundException e) {
+ loge("Package name not found: " + e.getMessage());
+ }
}
// Create or dispose mBindings and mLastSimState objects.
@@ -424,6 +430,8 @@
Log.d(LOG_TAG, message);
}
+ private static void loge(String message) { Log.e(LOG_TAG, message); }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("CarrierServiceBindHelper:");
for (int i = 0; i < mBindings.size(); i++) {
diff --git a/src/java/com/android/internal/telephony/CellBroadcastHandler.java b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
index 08be268..e9338de 100644
--- a/src/java/com/android/internal/telephony/CellBroadcastHandler.java
+++ b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
@@ -41,14 +41,15 @@
import android.provider.Settings;
import android.provider.Telephony;
import android.provider.Telephony.CellBroadcasts;
+import android.telephony.CbGeoUtils;
+import android.telephony.CbGeoUtils.Geometry;
+import android.telephony.CbGeoUtils.LatLng;
import android.telephony.SmsCbMessage;
import android.telephony.SubscriptionManager;
import android.text.format.DateUtils;
import android.util.LocalLog;
import android.util.Log;
-import com.android.internal.telephony.CbGeoUtils.Geometry;
-import com.android.internal.telephony.CbGeoUtils.LatLng;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import java.io.FileDescriptor;
@@ -142,7 +143,7 @@
} else {
performGeoFencing(message, uri, message.getGeometries(), location);
}
- }, message.getMaximumWaitingTime());
+ }, message.getMaximumWaitingDuration());
} else {
if (DBG) {
log("Broadcast the message directly because no geo-fencing required, "
@@ -220,7 +221,7 @@
msg = "Dispatching emergency SMS CB, SmsCbMessage is: " + message;
log(msg);
mLocalLog.log(msg);
- intent = new Intent(Telephony.Sms.Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
+ intent = new Intent(Telephony.Sms.Intents.ACTION_SMS_EMERGENCY_CB_RECEIVED);
//Emergency alerts need to be delivered with high priority
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
receiverPermission = Manifest.permission.RECEIVE_EMERGENCY_BROADCAST;
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index de4f7c0..0c60bc6 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -73,6 +73,7 @@
static final String CB_FACILITY_BA_MT = "AC";
static final String CB_FACILITY_BA_SIM = "SC";
static final String CB_FACILITY_BA_FD = "FD";
+ static final String CB_FACILITY_BIC_ACR = "AR";
// Used for various supp services apis
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index ede22e1..6cc9e63 100755
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -20,6 +20,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.DisconnectCause;
import android.telephony.Rlog;
import android.telephony.ServiceState;
@@ -94,7 +95,7 @@
public interface Listener {
public void onVideoStateChanged(int videoState);
public void onConnectionCapabilitiesChanged(int capability);
- public void onCallRadioTechChanged(@ServiceState.RilRadioTechnology int vrat);
+ public void onCallRadioTechChanged(@RilRadioTechnology int vrat);
public void onVideoProviderChanged(
android.telecom.Connection.VideoProvider videoProvider);
public void onAudioQualityChanged(int audioQuality);
@@ -125,7 +126,7 @@
@Override
public void onConnectionCapabilitiesChanged(int capability) {}
@Override
- public void onCallRadioTechChanged(@ServiceState.RilRadioTechnology int vrat) {}
+ public void onCallRadioTechChanged(@RilRadioTechnology int vrat) {}
@Override
public void onVideoProviderChanged(
android.telecom.Connection.VideoProvider videoProvider) {}
@@ -227,7 +228,7 @@
*
* This is used to propagate the call radio technology to upper layer.
*/
- private @ServiceState.RilRadioTechnology int mCallRadioTech =
+ private @RilRadioTechnology int mCallRadioTech =
ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
private boolean mAudioModeIsVoip;
private int mAudioQuality;
@@ -902,7 +903,7 @@
* @return the RIL Voice Radio Technology used for current connection,
* see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
*/
- public @ServiceState.RilRadioTechnology int getCallRadioTech() {
+ public @RilRadioTechnology int getCallRadioTech() {
return mCallRadioTech;
}
@@ -980,7 +981,7 @@
* @param vrat the RIL voice radio technology for current connection,
* see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
*/
- public void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+ public void setCallRadioTech(@RilRadioTechnology int vrat) {
if (mCallRadioTech == vrat) {
return;
}
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index 9cce7bc..d3a6cb5 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -24,7 +24,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.telephony.TelephonyRegistryManager;
+import android.telephony.TelephonyRegistryManager;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SrvccState;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index 1bbcd5e..6a22715 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -30,6 +30,7 @@
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.telecom.TelecomManager;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DisconnectCause;
@@ -1654,7 +1655,7 @@
* @param vrat the RIL voice radio technology for CS calls,
* see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
*/
- public void dispatchCsCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+ public void dispatchCsCallRadioTech(@RilRadioTechnology int vrat) {
if (mConnections == null) {
log("dispatchCsCallRadioTech: mConnections is null");
return;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 82bb78b..a2ee834 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -58,6 +58,7 @@
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.AccessNetworkConstants;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.ImsiEncryptionInfo;
@@ -947,27 +948,27 @@
/**
* ImsService reports "IN_SERVICE" for its voice registration state even if the device
* has lost the physical link to the tower. This helper method merges the IMS and modem
- * ServiceState, only overriding the voice registration state when we are registered to IMS over
- * IWLAN. In this case the voice registration state will always be "OUT_OF_SERVICE", so override
- * the voice registration state with the data registration state.
+ * ServiceState, only overriding the voice registration state when we are registered to IMS. In
+ * this case the voice registration state may be "OUT_OF_SERVICE", so override the voice
+ * registration state with the data registration state.
*/
private ServiceState mergeServiceStates(ServiceState baseSs, ServiceState imsSs) {
+ // No need to merge states if the baseSs is IN_SERVICE.
+ if (baseSs.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
+ return baseSs;
+ }
// "IN_SERVICE" in this case means IMS is registered.
if (imsSs.getVoiceRegState() != ServiceState.STATE_IN_SERVICE) {
return baseSs;
}
- if (imsSs.getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
- ServiceState newSs = new ServiceState(baseSs);
- // Voice override for IWLAN. In this case, voice registration is OUT_OF_SERVICE, but
- // the data RAT is IWLAN, so use that as a basis for determining whether or not the
- // physical link is available.
- newSs.setVoiceRegState(baseSs.getDataRegState());
- newSs.setEmergencyOnly(false); // only get here if voice is IN_SERVICE
- return newSs;
- }
-
- return baseSs;
+ ServiceState newSs = new ServiceState(baseSs);
+ // Voice override for IMS case. In this case, voice registration is OUT_OF_SERVICE, but
+ // IMS is available, so use data registration state as a basis for determining
+ // whether or not the physical link is available.
+ newSs.setVoiceRegState(baseSs.getDataRegState());
+ newSs.setEmergencyOnly(false); // only get here if voice is IN_SERVICE
+ return newSs;
}
private boolean handleCallDeflectionIncallSupplementaryService(
@@ -3839,7 +3840,7 @@
* @return the RIL voice radio technology used for CS calls,
* see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
*/
- public @ServiceState.RilRadioTechnology int getCsCallRadioTech() {
+ public @RilRadioTechnology int getCsCallRadioTech() {
int calcVrat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
if (mSST != null) {
calcVrat = getCsCallRadioTech(mSST.mSS.getVoiceRegState(),
@@ -3868,7 +3869,7 @@
* @return the RIL voice radio technology used for CS calls,
* see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
*/
- private @ServiceState.RilRadioTechnology int getCsCallRadioTech(int vrs, int vrat) {
+ private @RilRadioTechnology int getCsCallRadioTech(int vrs, int vrat) {
logd("getCsCallRadioTech, current vrs=" + vrs + ", vrat=" + vrat);
int calcVrat = vrat;
if (vrs != ServiceState.STATE_IN_SERVICE
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index c98d265..d2f256a 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -126,7 +126,7 @@
markMessagesAsRead((ArrayList<byte[]>) ar.result);
} else {
if (Rlog.isLoggable("SMS", Log.DEBUG)) {
- log("Cannot load Sms records");
+ loge("Cannot load Sms records");
}
mSms = null;
}
@@ -147,7 +147,7 @@
if (ar.exception == null) {
mSmsc = (String) ar.result;
} else {
- log("Cannot read SMSC");
+ loge("Cannot read SMSC");
mSmsc = null;
}
mLock.notifyAll();
@@ -194,7 +194,7 @@
//shouldn't really happen, as messages are marked as read, only
//after importing it from icc.
if (Rlog.isLoggable("SMS", Log.DEBUG)) {
- log("markMessagesAsRead - aborting, no icc card present.");
+ loge("markMessagesAsRead - aborting, no icc card present.");
}
return;
}
@@ -276,7 +276,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to update by index");
+ loge("interrupted while trying to update by index");
}
}
return mSuccess;
@@ -317,7 +317,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to update by index");
+ loge("interrupted while trying to update by index");
}
}
return mSuccess;
@@ -344,7 +344,7 @@
IccFileHandler fh = mPhone.getIccFileHandler();
if (fh == null) {
- Rlog.e(LOG_TAG, "Cannot load Sms records. No icc card?");
+ loge("Cannot load Sms records. No icc card?");
mSms = null;
return mSms;
}
@@ -355,7 +355,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to load from the Icc");
+ loge("interrupted while trying to load from the Icc");
}
}
return mSms;
@@ -610,7 +610,7 @@
try {
receivedIntent.send(result);
} catch (PendingIntent.CanceledException e) {
- Rlog.d(LOG_TAG, "receivedIntent cancelled.");
+ loge("receivedIntent cancelled.");
}
}
}
@@ -839,7 +839,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to read SMSC");
+ loge("interrupted while trying to read SMSC");
}
}
return mSmsc;
@@ -863,7 +863,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to write SMSC");
+ loge("interrupted while trying to write SMSC");
}
}
return mSuccess;
@@ -1119,7 +1119,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to set cell broadcast config");
+ loge("interrupted while trying to set cell broadcast config");
}
}
@@ -1139,7 +1139,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to set cell broadcast activation");
+ loge("interrupted while trying to set cell broadcast activation");
}
}
@@ -1160,7 +1160,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to set cdma broadcast config");
+ loge("interrupted while trying to set cdma broadcast config");
}
}
@@ -1180,7 +1180,7 @@
try {
mLock.wait();
} catch (InterruptedException e) {
- log("interrupted while trying to set cdma broadcast activation");
+ loge("interrupted while trying to set cdma broadcast activation");
}
}
@@ -1189,7 +1189,15 @@
@UnsupportedAppUsage
protected void log(String msg) {
- Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg);
+ Rlog.d(LOG_TAG, msg);
+ }
+
+ protected void loge(String msg) {
+ Rlog.e(LOG_TAG, msg);
+ }
+
+ protected void loge(String msg, Throwable e) {
+ Rlog.e(LOG_TAG, msg, e);
}
@UnsupportedAppUsage
@@ -1215,13 +1223,13 @@
}
final ContentResolver resolver = mContext.getContentResolver();
if (!isFailedOrDraft(resolver, messageUri)) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: not FAILED or DRAFT message");
+ loge("sendStoredText: not FAILED or DRAFT message");
returnUnspecifiedFailure(sentIntent);
return;
}
final String[] textAndAddress = loadTextAndAddress(resolver, messageUri);
if (textAndAddress == null) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredText: can not load text");
+ loge("sendStoredText: can not load text");
returnUnspecifiedFailure(sentIntent);
return;
}
@@ -1242,20 +1250,19 @@
}
final ContentResolver resolver = mContext.getContentResolver();
if (!isFailedOrDraft(resolver, messageUri)) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: "
- + "not FAILED or DRAFT message");
+ loge("sendStoredMultipartText: not FAILED or DRAFT message");
returnUnspecifiedFailure(sentIntents);
return;
}
final String[] textAndAddress = loadTextAndAddress(resolver, messageUri);
if (textAndAddress == null) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not load text");
+ loge("sendStoredMultipartText: can not load text");
returnUnspecifiedFailure(sentIntents);
return;
}
final ArrayList<String> parts = SmsManager.getDefault().divideMessage(textAndAddress[0]);
if (parts == null || parts.size() < 1) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]sendStoredMultipartText: can not divide text");
+ loge("sendStoredMultipartText: can not divide text");
returnUnspecifiedFailure(sentIntents);
return;
}
@@ -1327,7 +1334,7 @@
|| type == Telephony.Sms.MESSAGE_TYPE_FAILED;
}
} catch (SQLiteException e) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]isFailedOrDraft: query message type failed", e);
+ loge("isFailedOrDraft: query message type failed", e);
} finally {
if (cursor != null) {
cursor.close();
@@ -1358,7 +1365,7 @@
return new String[]{ cursor.getString(0), cursor.getString(1) };
}
} catch (SQLiteException e) {
- Log.e(LOG_TAG, "[IccSmsInterfaceManager]loadText: query message text failed", e);
+ loge("loadText: query message text failed", e);
} finally {
if (cursor != null) {
cursor.close();
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index 1c9a7e0..95429ef 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -42,6 +42,7 @@
import android.util.LocalLog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.MccTable.MccMnc;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -282,23 +283,16 @@
private String getMccFromCellInfo() {
String selectedMcc = null;
if (mCellInfoList != null) {
- Map<String, Integer> countryCodeMap = new HashMap<>();
+ Map<String, Integer> mccMap = new HashMap<>();
int maxCount = 0;
for (CellInfo cellInfo : mCellInfoList) {
- String mcc = null;
- if (cellInfo instanceof CellInfoGsm) {
- mcc = ((CellInfoGsm) cellInfo).getCellIdentity().getMccString();
- } else if (cellInfo instanceof CellInfoLte) {
- mcc = ((CellInfoLte) cellInfo).getCellIdentity().getMccString();
- } else if (cellInfo instanceof CellInfoWcdma) {
- mcc = ((CellInfoWcdma) cellInfo).getCellIdentity().getMccString();
- }
+ String mcc = getNetworkMcc(cellInfo);
if (mcc != null) {
int count = 1;
- if (countryCodeMap.containsKey(mcc)) {
- count = countryCodeMap.get(mcc) + 1;
+ if (mccMap.containsKey(mcc)) {
+ count = mccMap.get(mcc) + 1;
}
- countryCodeMap.put(mcc, count);
+ mccMap.put(mcc, count);
// This is unlikely, but if MCC from cell info looks different, we choose the
// MCC that occurs most.
if (count > maxCount) {
@@ -312,6 +306,67 @@
}
/**
+ * Get the most frequent MCC + MNC combination with the specified MCC using cell tower
+ * information. If no one combination is more frequent than any other an arbitrary MCC + MNC is
+ * returned with the matching MCC. The MNC value returned can be null if it is not provided by
+ * the cell tower information.
+ *
+ * @param mccToMatch the MCC to match
+ * @return a matching {@link MccMnc}. Null if the information is not available.
+ */
+ @Nullable
+ private MccMnc getMccMncFromCellInfo(String mccToMatch) {
+ MccMnc selectedMccMnc = null;
+ if (mCellInfoList != null) {
+ Map<MccMnc, Integer> mccMncMap = new HashMap<>();
+ int maxCount = 0;
+ for (CellInfo cellInfo : mCellInfoList) {
+ String mcc = getNetworkMcc(cellInfo);
+ if (Objects.equals(mcc, mccToMatch)) {
+ String mnc = getNetworkMnc(cellInfo);
+ MccMnc mccMnc = new MccMnc(mcc, mnc);
+ int count = 1;
+ if (mccMncMap.containsKey(mccMnc)) {
+ count = mccMncMap.get(mccMnc) + 1;
+ }
+ mccMncMap.put(mccMnc, count);
+ // This is unlikely, but if MCC from cell info looks different, we choose the
+ // MCC that occurs most.
+ if (count > maxCount) {
+ maxCount = count;
+ selectedMccMnc = mccMnc;
+ }
+ }
+ }
+ }
+ return selectedMccMnc;
+ }
+
+ private static String getNetworkMcc(CellInfo cellInfo) {
+ String mccString = null;
+ if (cellInfo instanceof CellInfoGsm) {
+ mccString = ((CellInfoGsm) cellInfo).getCellIdentity().getMccString();
+ } else if (cellInfo instanceof CellInfoLte) {
+ mccString = ((CellInfoLte) cellInfo).getCellIdentity().getMccString();
+ } else if (cellInfo instanceof CellInfoWcdma) {
+ mccString = ((CellInfoWcdma) cellInfo).getCellIdentity().getMccString();
+ }
+ return mccString;
+ }
+
+ private static String getNetworkMnc(CellInfo cellInfo) {
+ String mccString = null;
+ if (cellInfo instanceof CellInfoGsm) {
+ mccString = ((CellInfoGsm) cellInfo).getCellIdentity().getMncString();
+ } else if (cellInfo instanceof CellInfoLte) {
+ mccString = ((CellInfoLte) cellInfo).getCellIdentity().getMncString();
+ } else if (cellInfo instanceof CellInfoWcdma) {
+ mccString = ((CellInfoWcdma) cellInfo).getCellIdentity().getMncString();
+ }
+ return mccString;
+ }
+
+ /**
* Called when SIM card state changed. Only when we absolutely know the SIM is absent, we get
* cell info from the network. Other SIM states like NOT_READY might be just a transitioning
* state.
@@ -457,15 +512,23 @@
String countryIso = getCarrierCountry();
String countryIsoDebugInfo = "getCarrierCountry()";
+ // For time zone detection we want the best geographical match we can get, which may differ
+ // from the countryIso.
+ String timeZoneCountryIso = null;
+ String timeZoneCountryIsoDebugInfo = null;
+
if (!TextUtils.isEmpty(mOperatorNumeric)) {
- try {
- String mcc = mOperatorNumeric.substring(0, 3);
- countryIso = MccTable.countryCodeForMcc(mcc);
+ MccMnc mccMnc = MccMnc.fromOperatorNumeric(mOperatorNumeric);
+ if (mccMnc != null) {
+ countryIso = MccTable.countryCodeForMcc(mccMnc.mcc);
countryIsoDebugInfo = "OperatorNumeric(" + mOperatorNumeric
- + "): MccTable.countryCodeForMcc(\"" + mcc + "\")";
- } catch (StringIndexOutOfBoundsException ex) {
+ + "): MccTable.countryCodeForMcc(\"" + mccMnc.mcc + "\")";
+ timeZoneCountryIso = MccTable.geoCountryCodeForMccMnc(mccMnc);
+ timeZoneCountryIsoDebugInfo =
+ "OperatorNumeric: MccTable.geoCountryCodeForMccMnc(" + mccMnc + ")";
+ } else {
loge("updateLocale: Can't get country from operator numeric. mOperatorNumeric = "
- + mOperatorNumeric + ". ex=" + ex);
+ + mOperatorNumeric);
}
}
@@ -475,19 +538,27 @@
String mcc = getMccFromCellInfo();
countryIso = MccTable.countryCodeForMcc(mcc);
countryIsoDebugInfo = "CellInfo: MccTable.countryCodeForMcc(\"" + mcc + "\")";
+
+ MccMnc mccMnc = getMccMncFromCellInfo(mcc);
+ if (mccMnc != null) {
+ timeZoneCountryIso = MccTable.geoCountryCodeForMccMnc(mccMnc);
+ timeZoneCountryIsoDebugInfo =
+ "CellInfo: MccTable.geoCountryCodeForMccMnc(" + mccMnc + ")";
+ }
}
if (mCountryOverride != null) {
countryIso = mCountryOverride;
countryIsoDebugInfo = "mCountryOverride = \"" + mCountryOverride + "\"";
- log("Override current country to " + mCountryOverride);
+ timeZoneCountryIso = countryIso;
+ timeZoneCountryIsoDebugInfo = countryIsoDebugInfo;
}
log("updateLocale: countryIso = " + countryIso
+ ", countryIsoDebugInfo = " + countryIsoDebugInfo);
if (!Objects.equals(countryIso, mCurrentCountryIso)) {
- String msg = "updateLocale: Change the current country to \"" + countryIso
- + "\", countryIsoDebugInfo = " + countryIsoDebugInfo
+ String msg = "updateLocale: Change the current country to \"" + countryIso + "\""
+ + ", countryIsoDebugInfo = " + countryIsoDebugInfo
+ ", mCellInfoList = " + mCellInfoList;
log(msg);
mLocalLog.log(msg);
@@ -502,19 +573,30 @@
mPhone.getContext().sendBroadcast(intent);
}
- // For a test cell, the NitzStateMachine requires handleCountryDetected("") to pass
- // compliance tests. http://b/142840879
+ // Pass the geographical country information to the telephony time zone detection code.
+
boolean isTestMcc = false;
if (!TextUtils.isEmpty(mOperatorNumeric)) {
+ // For a test cell (MCC 001), the NitzStateMachine requires handleCountryDetected("") in
+ // order to pass compliance tests. http://b/142840879
if (mOperatorNumeric.startsWith("001")) {
isTestMcc = true;
- countryIso = "";
+ timeZoneCountryIso = "";
+ timeZoneCountryIsoDebugInfo = "Test cell: " + mOperatorNumeric;
}
}
- if (TextUtils.isEmpty(countryIso) && !isTestMcc) {
+ if (timeZoneCountryIso == null) {
+ // After this timeZoneCountryIso may still be null.
+ timeZoneCountryIso = countryIso;
+ timeZoneCountryIsoDebugInfo = "Defaulted: " + countryIsoDebugInfo;
+ }
+ log("updateLocale: timeZoneCountryIso = " + timeZoneCountryIso
+ + ", timeZoneCountryIsoDebugInfo = " + timeZoneCountryIsoDebugInfo);
+
+ if (TextUtils.isEmpty(timeZoneCountryIso) && !isTestMcc) {
mNitzStateMachine.handleCountryUnavailable();
} else {
- mNitzStateMachine.handleCountryDetected(countryIso);
+ mNitzStateMachine.handleCountryDetected(timeZoneCountryIso);
}
}
diff --git a/src/java/com/android/internal/telephony/MccTable.java b/src/java/com/android/internal/telephony/MccTable.java
index 31b8d0a..d4c2e9a 100644
--- a/src/java/com/android/internal/telephony/MccTable.java
+++ b/src/java/com/android/internal/telephony/MccTable.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.content.Context;
@@ -27,9 +29,15 @@
import android.text.TextUtils;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.LocaleStore;
import com.android.internal.app.LocaleStore.LocaleInfo;
+import libcore.timezone.TelephonyLookup;
+import libcore.timezone.TelephonyNetwork;
+import libcore.timezone.TelephonyNetworkFinder;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -37,6 +45,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
/**
* Mobile Country Code
@@ -46,6 +55,9 @@
public final class MccTable {
static final String LOG_TAG = "MccTable";
+ @GuardedBy("MccTable.class")
+ private static TelephonyNetworkFinder sTelephonyNetworkFinder;
+
static ArrayList<MccEntry> sTable;
static class MccEntry implements Comparable<MccEntry> {
@@ -58,11 +70,11 @@
final String mIso;
final int mSmallestDigitsMnc;
- MccEntry(int mnc, String iso, int smallestDigitsMCC) {
+ MccEntry(int mcc, String iso, int smallestDigitsMCC) {
if (iso == null) {
throw new NullPointerException();
}
- mMcc = mnc;
+ mMcc = mcc;
mIso = iso;
mSmallestDigitsMnc = smallestDigitsMCC;
}
@@ -73,6 +85,77 @@
}
}
+ /**
+ * A combination of MCC and MNC. The MNC is optional and may be null.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static class MccMnc {
+ @NonNull
+ public final String mcc;
+
+ @Nullable
+ public final String mnc;
+
+ /**
+ * Splits the supplied String in two: the first three characters are treated as the MCC,
+ * the remaining characters are treated as the MNC.
+ */
+ @Nullable
+ public static MccMnc fromOperatorNumeric(@NonNull String operatorNumeric) {
+ Objects.requireNonNull(operatorNumeric);
+ String mcc;
+ try {
+ mcc = operatorNumeric.substring(0, 3);
+ } catch (StringIndexOutOfBoundsException e) {
+ return null;
+ }
+
+ String mnc;
+ try {
+ mnc = operatorNumeric.substring(3);
+ } catch (StringIndexOutOfBoundsException e) {
+ mnc = null;
+ }
+ return new MccMnc(mcc, mnc);
+ }
+
+ /**
+ * Creates an MccMnc using the supplied values.
+ */
+ public MccMnc(@NonNull String mcc, @Nullable String mnc) {
+ this.mcc = Objects.requireNonNull(mcc);
+ this.mnc = mnc;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ MccMnc mccMnc = (MccMnc) o;
+ return mcc.equals(mccMnc.mcc)
+ && Objects.equals(mnc, mccMnc.mnc);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mcc, mnc);
+ }
+
+ @Override
+ public String toString() {
+ return "MccMnc{"
+ + "mcc='" + mcc + '\''
+ + ", mnc='" + mnc + '\''
+ + '}';
+ }
+ }
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
publicAlternatives = "There is no alternative for {@code MccTable.entryForMcc}, "
+ "but it was included in hidden APIs due to a static analysis false positive "
@@ -91,11 +174,11 @@
}
/**
- * Given a GSM Mobile Country Code, returns
- * an ISO two-character country code if available.
- * Returns "" if unavailable.
+ * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if
+ * available. Returns empty string if unavailable.
*/
@UnsupportedAppUsage
+ @NonNull
public static String countryCodeForMcc(int mcc) {
MccEntry entry = entryForMcc(mcc);
@@ -107,11 +190,11 @@
}
/**
- * Given a GSM Mobile Country Code, returns
- * an ISO two-character country code if available.
- * Returns empty string if unavailable.
+ * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if
+ * available. Returns empty string if unavailable.
*/
- public static String countryCodeForMcc(String mcc) {
+ @NonNull
+ public static String countryCodeForMcc(@NonNull String mcc) {
try {
return countryCodeForMcc(Integer.parseInt(mcc));
} catch (NumberFormatException ex) {
@@ -120,6 +203,51 @@
}
/**
+ * Given a combination of MCC and MNC, returns a lower case ISO 3166 alpha-2 country code for
+ * the device's geographical location.
+ *
+ * <p>This can give a better geographical result than {@link #countryCodeForMcc(String)}
+ * (which provides the official "which country is the MCC assigned to?" answer) for cases when
+ * MNC is also available: Sometimes an MCC can be used by multiple countries and the MNC can
+ * help distinguish, or the MCC assigned to a country isn't used for geopolitical reasons.
+ * When the geographical country is needed (e.g. time zone detection) this version can provide
+ * more pragmatic results than the official MCC-only answer. This method falls back to calling
+ * {@link #countryCodeForMcc(int)} if no special MCC+MNC cases are found.
+ * Returns empty string if no code can be determined.
+ */
+ @NonNull
+ public static String geoCountryCodeForMccMnc(@NonNull MccMnc mccMnc) {
+ String countryCode = null;
+ if (mccMnc.mnc != null) {
+ countryCode = countryCodeForMccMncNoFallback(mccMnc);
+ }
+ if (TextUtils.isEmpty(countryCode)) {
+ // Try the MCC-only fallback.
+ countryCode = MccTable.countryCodeForMcc(mccMnc.mcc);
+ }
+ return countryCode;
+ }
+
+ @Nullable
+ private static String countryCodeForMccMncNoFallback(MccMnc mccMnc) {
+ synchronized (MccTable.class) {
+ if (sTelephonyNetworkFinder == null) {
+ sTelephonyNetworkFinder = TelephonyLookup.getInstance().getTelephonyNetworkFinder();
+ }
+ }
+ if (sTelephonyNetworkFinder == null) {
+ // This should not happen under normal circumstances, only when the data is missing.
+ return null;
+ }
+ TelephonyNetwork network =
+ sTelephonyNetworkFinder.findNetworkByMccMnc(mccMnc.mcc, mccMnc.mnc);
+ if (network == null) {
+ return null;
+ }
+ return network.getCountryIsoCode();
+ }
+
+ /**
* Given a GSM Mobile Country Code, returns
* an ISO 2-3 character language code if available.
* Returns null if unavailable.
diff --git a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
index 1b28be4..bd90be6 100644
--- a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
+++ b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.IBinder;
@@ -99,8 +100,14 @@
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- phone.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- intentFilter, null, null);
+ try {
+ Context contextAsUser = phone.getContext().createPackageContextAsUser(
+ phone.getContext().getPackageName(), 0, UserHandle.ALL);
+ contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
+ null /* broadcastPermission */, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ loge("Package name not found: " + e.getMessage());
+ }
PhoneConfigurationManager.registerForMultiSimConfigChange(
this, EVENT_BIND_NETWORK_SERVICE, null);
diff --git a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
index c848358..895170d 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -66,10 +66,12 @@
private static final int EVENT_STOP_NETWORK_SCAN_DONE = 5;
private static final int CMD_INTERRUPT_NETWORK_SCAN = 6;
private static final int EVENT_INTERRUPT_NETWORK_SCAN_DONE = 7;
+ private static final int EVENT_MODEM_RESET = 8;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
+ Log.d(TAG, "Received Event :" + msg.what);
switch (msg.what) {
case CMD_START_NETWORK_SCAN:
mScheduler.doStartScan((NetworkScanRequestInfo) msg.obj);
@@ -98,6 +100,14 @@
case EVENT_INTERRUPT_NETWORK_SCAN_DONE:
mScheduler.interruptScanDone((AsyncResult) msg.obj);
break;
+
+ case EVENT_MODEM_RESET:
+ AsyncResult ar = (AsyncResult) msg.obj;
+ mScheduler.deleteScanAndMayNotify(
+ (NetworkScanRequestInfo) ar.userObj,
+ NetworkScan.ERROR_MODEM_ERROR,
+ true);
+ break;
}
}
};
@@ -551,6 +561,7 @@
mLiveRequestInfo = nsri;
nsri.mPhone.startNetworkScan(nsri.getRequest(),
mHandler.obtainMessage(EVENT_START_NETWORK_SCAN_DONE, nsri));
+ nsri.mPhone.mCi.registerForModemReset(mHandler, EVENT_MODEM_RESET, nsri);
return true;
}
return false;
@@ -570,6 +581,7 @@
null);
}
}
+ mLiveRequestInfo.mPhone.mCi.unregisterForModemReset(mHandler);
mLiveRequestInfo = null;
if (mPendingRequestInfo != null) {
startNewScan(mPendingRequestInfo);
diff --git a/src/java/com/android/internal/telephony/NitzStateMachine.java b/src/java/com/android/internal/telephony/NitzStateMachine.java
index ec5aaa6..38c8c56 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachine.java
@@ -51,7 +51,8 @@
void handleNetworkAvailable();
/**
- * Informs the {@link NitzStateMachine} that the network has become unavailable.
+ * Informs the {@link NitzStateMachine} that the network has become unavailable. Any network
+ * state, i.e. NITZ, should be cleared.
*/
void handleNetworkUnavailable();
diff --git a/src/java/com/android/internal/telephony/NitzStateMachineImpl.java b/src/java/com/android/internal/telephony/NitzStateMachineImpl.java
index 23152ac..2fec367 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachineImpl.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachineImpl.java
@@ -267,6 +267,8 @@
logMsg += " [Not setting device time zone (zoneId == null)]";
Rlog.d(LOG_TAG, logMsg);
}
+ mSavedTimeZoneId = null;
+ mNitzTimeZoneDetectionSuccessful = false;
}
} catch (RuntimeException ex) {
Rlog.e(LOG_TAG, "updateTimeZoneFromCountryAndNitz: Processing NITZ data"
@@ -319,18 +321,26 @@
mSavedNitzTime = null;
mTimeLog.log("handleNetworkUnavailable: NITZ state cleared.");
+ TimestampedValue<NitzData> oldNitzSignal = mLatestNitzSignal;
mLatestNitzSignal = null;
mNitzTimeZoneDetectionSuccessful = false;
mSavedTimeZoneId = null;
mTimeZoneLog.log("handleNetworkUnavailable: NITZ state cleared.");
- // mSavedTimeZoneId has been cleared but it might be sufficient to detect the time zone
- // using only the country information that is left.
+ // Avoid doing country-only detection work unnecessarily: if the mLatestNitzSignal was
+ // already null we have nothing to do as it will have been done last time the
+ // mLatestNitzSignal was cleared.
+ if (oldNitzSignal == null) {
+ return;
+ }
+
+ // mSavedTimeZoneId has been cleared but using only the country information that is left
+ // might be sufficient to detect the time zone.
String isoCountryCode = mCountryIsoCode;
- if (isoCountryCode != null) {
- if (!TextUtils.isEmpty(isoCountryCode)) {
- updateTimeZoneFromNetworkCountryCode(isoCountryCode);
- }
+ // We don't need to do country-based time zone detection if the isoCountryCode is null
+ // (unknown) or empty (test cell). TextUtils.isEmpty() does both checks in one.
+ if (!TextUtils.isEmpty(isoCountryCode)) {
+ updateTimeZoneFromNetworkCountryCode(isoCountryCode);
}
}
@@ -348,7 +358,7 @@
@Override
public void handleNitzReceived(TimestampedValue<NitzData> nitzSignal) {
// Always store the latest NITZ signal received.
- mLatestNitzSignal = nitzSignal;
+ mLatestNitzSignal = Objects.requireNonNull(nitzSignal);
updateTimeZoneFromCountryAndNitz();
updateTimeFromNitz();
@@ -576,6 +586,7 @@
+ " iso=" + iso
+ " lookupResult=" + lookupResult);
}
+ mSavedTimeZoneId = null;
}
}
@@ -588,4 +599,9 @@
public NitzData getCachedNitzData() {
return mLatestNitzSignal != null ? mLatestNitzSignal.getValue() : null;
}
+
+ // VisibleForTesting
+ public String getSavedTimeZoneId() {
+ return mSavedTimeZoneId;
+ }
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index fd22e77..fd92404 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -2362,6 +2362,15 @@
mCi.nvResetConfig(3 /* factory NV reset */, response);
}
+ /**
+ * Perform modem configuration erase. Used for network reset
+ *
+ * @param response Callback message.
+ */
+ public void eraseModemConfig(Message response) {
+ mCi.nvResetConfig(2 /* erase NV */, response);
+ }
+
public void notifyDataActivity() {
mNotifier.notifyDataActivity(this);
}
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index b92c68b..0147fef 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -87,7 +87,6 @@
static private Context sContext;
static private PhoneConfigurationManager sPhoneConfigurationManager;
static private PhoneSwitcher sPhoneSwitcher;
- static private SubscriptionMonitor sSubscriptionMonitor;
static private TelephonyNetworkFactory[] sTelephonyNetworkFactories;
static private ImsResolver sImsResolver;
static private NotificationChannelController sNotificationChannelController;
@@ -250,8 +249,6 @@
ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(
ServiceManager.getService("telephony.registry"));
- sSubscriptionMonitor = new SubscriptionMonitor(tr, sContext, sc, numPhones);
-
sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext);
sCellularNetworkValidator = CellularNetworkValidator.make(sContext);
@@ -271,7 +268,7 @@
for (int i = 0; i < numPhones; i++) {
sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
- sSubscriptionMonitor, Looper.myLooper(), sPhones[i]);
+ Looper.myLooper(), sPhones[i]);
}
}
}
@@ -538,16 +535,6 @@
pw.decreaseIndent();
pw.println("++++++++++++++++++++++++++++++++");
- pw.println("SubscriptionMonitor:");
- pw.increaseIndent();
- try {
- sSubscriptionMonitor.dump(fd, pw, args);
- } catch (Exception e) {
- e.printStackTrace();
- }
- pw.decreaseIndent();
- pw.println("++++++++++++++++++++++++++++++++");
-
pw.println("UiccController:");
pw.increaseIndent();
try {
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index c5b7eda..8b8425a 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -79,7 +79,7 @@
public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType,
String callingPackage) {
- return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage,
+ return callPhoneMethodForSubIdWithPrivilegedCheck(subId,
"getCarrierInfoForImsiEncryption",
(phone)-> phone.getCarrierInfoForImsiEncryption(keyType));
}
@@ -103,14 +103,13 @@
*/
public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) {
callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage,
- "setCarrierInfoForImsiEncryption",
+ "resetCarrierKeysForImsiEncryption",
(phone)-> {
phone.resetCarrierKeysForImsiEncryption();
return null;
});
}
-
public String getDeviceSvn(String callingPackage) {
return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage);
}
@@ -434,7 +433,6 @@
aContext, aSubId, aCallingPackage, aMessage));
}
-
private <T> T callPhoneMethodForSubIdWithPrivilegedCheck(
int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) {
return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper,
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index cf64a8b..04240dd 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -53,6 +53,7 @@
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.TelephonyRegistryManager;
import android.telephony.data.ApnSetting;
import android.util.LocalLog;
@@ -64,6 +65,7 @@
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDemandDataSwitch;
import com.android.internal.util.IndentingPrintWriter;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -293,7 +295,7 @@
CommandsInterface[] cis, Phone[] phones) {
if (sPhoneSwitcher == null) {
sPhoneSwitcher = new PhoneSwitcher(maxActivePhones, numPhones, context,
- subscriptionController, looper, tr, cis, phones);
+ subscriptionController, looper, cis, phones);
}
return sPhoneSwitcher;
@@ -346,7 +348,7 @@
@VisibleForTesting
public PhoneSwitcher(int maxActivePhones, int numPhones, Context context,
- SubscriptionController subscriptionController, Looper looper, ITelephonyRegistry tr,
+ SubscriptionController subscriptionController, Looper looper,
CommandsInterface[] cis, Phone[] phones) {
super(looper);
mContext = context;
@@ -392,11 +394,10 @@
mCommandsInterfaces[0].registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
}
- try {
- tr.addOnSubscriptionsChangedListener(context.getOpPackageName(),
- mSubscriptionsChangedListener);
- } catch (RemoteException e) {
- }
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ telephonyRegistryManager.addOnSubscriptionsChangedListener(
+ mSubscriptionsChangedListener, mSubscriptionsChangedListener.getHandlerExecutor());
mConnectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -438,8 +439,8 @@
}
};
- private final IOnSubscriptionsChangedListener mSubscriptionsChangedListener =
- new IOnSubscriptionsChangedListener.Stub() {
+ private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener =
+ new SubscriptionManager.OnSubscriptionsChangedListener() {
@Override
public void onSubscriptionsChanged() {
Message msg = PhoneSwitcher.this.obtainMessage(EVENT_SUBSCRIPTION_CHANGED);
@@ -1301,14 +1302,10 @@
* See {@link PhoneStateListener#LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE}.
*/
private void notifyPreferredDataSubIdChanged() {
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- try {
- log("notifyPreferredDataSubIdChanged to " + mPreferredDataSubId);
- tr.notifyActiveDataSubIdChanged(mPreferredDataSubId);
- } catch (RemoteException ex) {
- // Should never happen because its always available.
- }
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) mContext
+ .getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ log("notifyPreferredDataSubIdChanged to " + mPreferredDataSubId);
+ telephonyRegistryManager.notifyActiveDataSubIdChanged(mPreferredDataSubId);
}
/**
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index 7b45c53..6216200 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
@@ -83,8 +84,14 @@
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL,
- intentFilter, null, null);
+ try {
+ Context contextAsUser = phone.getContext().createPackageContextAsUser(
+ phone.getContext().getPackageName(), 0, UserHandle.ALL);
+ contextAsUser.registerReceiver(mConfigChangedReceiver,
+ intentFilter, null /* broadcastPermission */, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ Rlog.e(LOG_TAG, "Package name not found: " + e.getMessage());
+ }
resetRatFamilyMap();
}
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 0f3d8aa..4b32c72 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -30,7 +30,6 @@
import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
-import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
import android.app.Activity;
@@ -383,13 +382,6 @@
}
}
- private static int getSendSmsFlag(@Nullable PendingIntent deliveryIntent) {
- if (deliveryIntent == null) {
- return 0;
- }
- return CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS;
- }
-
/**
* Use the carrier messaging service to send a text SMS.
*/
@@ -405,8 +397,13 @@
if (text != null) {
try {
- sendTextSms(text, getSubId(),
- mTracker.mDestAddress, getSendSmsFlag(mTracker.mDeliveryIntent),
+ sendTextSms(
+ text,
+ getSubId(),
+ mTracker.mDestAddress,
+ (mTracker.mDeliveryIntent != null)
+ ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
+ : 0,
mSenderCallback);
} catch (RuntimeException e) {
Rlog.e(TAG, "Exception sending the SMS: " + e);
@@ -438,9 +435,15 @@
if (data != null) {
try {
- sendDataSms(data, getSubId(),
- mTracker.mDestAddress, destPort,
- getSendSmsFlag(mTracker.mDeliveryIntent), mSenderCallback);
+ sendDataSms(
+ data,
+ getSubId(),
+ mTracker.mDestAddress,
+ destPort,
+ (mTracker.mDeliveryIntent != null)
+ ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
+ : 0,
+ mSenderCallback);
} catch (RuntimeException e) {
Rlog.e(TAG, "Exception sending the SMS: " + e);
mSenderCallback.onSendSmsComplete(
@@ -566,10 +569,23 @@
@Override
public void onServiceReady() {
+ boolean statusReportRequested = false;
+ for (SmsTracker tracker : mTrackers) {
+ if (tracker.mDeliveryIntent != null) {
+ statusReportRequested = true;
+ break;
+ }
+ }
+
try {
sendMultipartTextSms(
- mParts, getSubId(), mTrackers[0].mDestAddress,
- getSendSmsFlag(mTrackers[0].mDeliveryIntent), mSenderCallback);
+ mParts,
+ getSubId(),
+ mTrackers[0].mDestAddress,
+ statusReportRequested
+ ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
+ : 0,
+ mSenderCallback);
} catch (RuntimeException e) {
Rlog.e(TAG, "Exception sending the SMS: " + e);
mSenderCallback.onSendMultipartSmsComplete(
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 30391ca..b8b1347 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -57,6 +57,7 @@
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityCdma;
@@ -71,7 +72,6 @@
import android.telephony.PhysicalChannelConfig;
import android.telephony.Rlog;
import android.telephony.ServiceState;
-import android.telephony.ServiceState.RilRadioTechnology;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -728,7 +728,8 @@
mMin = null;
mPrlVersion = null;
mIsMinInfoReady = false;
- mNitzState.handleCountryUnavailable();
+ mLastNitzData = null;
+ mNitzState.handleNetworkUnavailable();
mCellIdentity = null;
mNewCellIdentity = null;
mSignalStrengthUpdatedTime = System.currentTimeMillis();
@@ -3014,7 +3015,8 @@
mNewSS.setStateOutOfService();
mNewCellIdentity = null;
setSignalStrengthDefaultValues();
- mNitzState.handleCountryUnavailable();
+ mLastNitzData = null;
+ mNitzState.handleNetworkUnavailable();
pollStateDone();
break;
@@ -3022,7 +3024,8 @@
mNewSS.setStateOff();
mNewCellIdentity = null;
setSignalStrengthDefaultValues();
- mNitzState.handleCountryUnavailable();
+ mLastNitzData = null;
+ mNitzState.handleNetworkUnavailable();
// don't poll when device is shutting down or the poll was not modemTrigged
// (they sent us new radio data) and current network is not IWLAN
if (mDeviceShuttingDown ||
diff --git a/src/java/com/android/internal/telephony/SmsController.java b/src/java/com/android/internal/telephony/SmsController.java
index 0fce4d2..eaa7fc8 100644
--- a/src/java/com/android/internal/telephony/SmsController.java
+++ b/src/java/com/android/internal/telephony/SmsController.java
@@ -551,9 +551,6 @@
}
}
- /**
- * Triggered by `adb shell dumpsys isms`
- */
@Override
public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
@@ -579,6 +576,9 @@
}
}
+ /**
+ * Triggered by `adb shell dumpsys isms`
+ */
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!checkDumpPermission(mContext, LOG_TAG, pw)) {
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 6b7c8a3..66b8709 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -432,82 +432,81 @@
*/
public void sendRetrySms(SMSDispatcher.SmsTracker tracker) {
String oldFormat = tracker.mFormat;
+ boolean retryUsingImsService = false;
- // newFormat will be based on voice technology
+ if (!tracker.mUsesImsServiceForIms && mImsSmsDispatcher.isAvailable()) {
+ // If this tracker has not been handled by ImsSmsDispatcher yet and IMS Service is
+ // available now, retry this failed tracker using IMS Service.
+ retryUsingImsService = true;
+ }
+
+ // If retryUsingImsService is true, newFormat will be IMS SMS format. Otherwise, newFormat
+ // will be based on voice technology.
String newFormat =
- (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType())
- ? mCdmaDispatcher.getFormat() : mGsmDispatcher.getFormat();
+ retryUsingImsService
+ ? mImsSmsDispatcher.getFormat()
+ : (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType())
+ ? mCdmaDispatcher.getFormat()
+ : mGsmDispatcher.getFormat();
- // was previously sent sms format match with voice tech?
- if (oldFormat.equals(newFormat)) {
- if (isCdmaFormat(newFormat)) {
- Rlog.d(TAG, "old format matched new format (cdma)");
- mCdmaDispatcher.sendSms(tracker);
- return;
- } else {
- Rlog.d(TAG, "old format matched new format (gsm)");
- mGsmDispatcher.sendSms(tracker);
+ Rlog.d(TAG, "old format(" + oldFormat + ") ==> new format (" + newFormat + ")");
+ if (!oldFormat.equals(newFormat)) {
+ // format didn't match, need to re-encode.
+ HashMap map = tracker.getData();
+
+ // to re-encode, fields needed are: scAddr, destAddr and text if originally sent as
+ // sendText or data and destPort if originally sent as sendData.
+ if (!(map.containsKey("scAddr") && map.containsKey("destAddr")
+ && (map.containsKey("text")
+ || (map.containsKey("data") && map.containsKey("destPort"))))) {
+ // should never come here...
+ Rlog.e(TAG, "sendRetrySms failed to re-encode per missing fields!");
+ tracker.onFailed(mContext, SmsManager.RESULT_SMS_SEND_RETRY_FAILED, NO_ERROR_CODE);
return;
}
- }
+ String scAddr = (String) map.get("scAddr");
+ String destAddr = (String) map.get("destAddr");
- // format didn't match, need to re-encode.
- HashMap map = tracker.getData();
+ SmsMessageBase.SubmitPduBase pdu = null;
+ // figure out from tracker if this was sendText/Data
+ if (map.containsKey("text")) {
+ Rlog.d(TAG, "sms failed was text");
+ String text = (String) map.get("text");
- // to re-encode, fields needed are: scAddr, destAddr, and
- // text if originally sent as sendText or
- // data and destPort if originally sent as sendData.
- if (!(map.containsKey("scAddr") && map.containsKey("destAddr")
- && (map.containsKey("text")
- || (map.containsKey("data") && map.containsKey("destPort"))))) {
- // should never come here...
- Rlog.e(TAG, "sendRetrySms failed to re-encode per missing fields!");
- tracker.onFailed(mContext, SmsManager.RESULT_SMS_SEND_RETRY_FAILED, NO_ERROR_CODE);
- return;
- }
- String scAddr = (String) map.get("scAddr");
- String destAddr = (String) map.get("destAddr");
+ if (isCdmaFormat(newFormat)) {
+ pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
+ scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
+ } else {
+ pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
+ scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
+ }
+ } else if (map.containsKey("data")) {
+ Rlog.d(TAG, "sms failed was data");
+ byte[] data = (byte[]) map.get("data");
+ Integer destPort = (Integer) map.get("destPort");
- SmsMessageBase.SubmitPduBase pdu = null;
- // figure out from tracker if this was sendText/Data
- if (map.containsKey("text")) {
- Rlog.d(TAG, "sms failed was text");
- String text = (String) map.get("text");
-
- if (isCdmaFormat(newFormat)) {
- Rlog.d(TAG, "old format (gsm) ==> new format (cdma)");
- pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
- scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
- } else {
- Rlog.d(TAG, "old format (cdma) ==> new format (gsm)");
- pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
- scAddr, destAddr, text, (tracker.mDeliveryIntent != null), null);
- }
- } else if (map.containsKey("data")) {
- Rlog.d(TAG, "sms failed was data");
- byte[] data = (byte[]) map.get("data");
- Integer destPort = (Integer) map.get("destPort");
-
- if (isCdmaFormat(newFormat)) {
- Rlog.d(TAG, "old format (gsm) ==> new format (cdma)");
- pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
+ if (isCdmaFormat(newFormat)) {
+ pdu = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(
scAddr, destAddr, destPort.intValue(), data,
(tracker.mDeliveryIntent != null));
- } else {
- Rlog.d(TAG, "old format (cdma) ==> new format (gsm)");
- pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
+ } else {
+ pdu = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(
scAddr, destAddr, destPort.intValue(), data,
(tracker.mDeliveryIntent != null));
+ }
}
+
+ // replace old smsc and pdu with newly encoded ones
+ map.put("smsc", pdu.encodedScAddress);
+ map.put("pdu", pdu.encodedMessage);
+ tracker.mFormat = newFormat;
}
- // replace old smsc and pdu with newly encoded ones
- map.put("smsc", pdu.encodedScAddress);
- map.put("pdu", pdu.encodedMessage);
+ SMSDispatcher dispatcher =
+ retryUsingImsService
+ ? mImsSmsDispatcher
+ : (isCdmaFormat(newFormat)) ? mCdmaDispatcher : mGsmDispatcher;
- SMSDispatcher dispatcher = (isCdmaFormat(newFormat)) ? mCdmaDispatcher : mGsmDispatcher;
-
- tracker.mFormat = dispatcher.getFormat();
dispatcher.sendSms(tracker);
}
diff --git a/src/java/com/android/internal/telephony/SmsPermissions.java b/src/java/com/android/internal/telephony/SmsPermissions.java
index 463ffe7..3aa0756 100644
--- a/src/java/com/android/internal/telephony/SmsPermissions.java
+++ b/src/java/com/android/internal/telephony/SmsPermissions.java
@@ -92,7 +92,7 @@
}
} catch (PackageManager.NameNotFoundException e) {
if (Rlog.isLoggable("SMS", Log.DEBUG)) {
- log("Cannot find configured carrier ims package");
+ loge("Cannot find configured carrier ims package");
}
}
@@ -143,7 +143,7 @@
.enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mContext, mPhone.getSubId(), message);
} catch (SecurityException e) { // To avoid crashing applications
- Log.e(LOG_TAG, message + ": Neither " + callingPackage + " is the default SMS app"
+ loge(message + ": Neither " + callingPackage + " is the default SMS app"
+ " nor the caller has "
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
+ ", or carrier privileges", e);
@@ -171,7 +171,7 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mContext, mPhone.getSubId(), message);
} catch (SecurityException e) { // To avoid crashing applications
- Log.e(LOG_TAG, message + ": Neither " + callingPackage + " is the default SMS app"
+ loge(message + ": Neither " + callingPackage + " is the default SMS app"
+ " nor the caller has " + android.Manifest.permission.MODIFY_PHONE_STATE
+ ", or carrier privileges", e);
return false;
@@ -188,6 +188,14 @@
@UnsupportedAppUsage
protected void log(String msg) {
- Log.d(LOG_TAG, "[IccSmsInterfaceManager] " + msg);
+ Rlog.d(LOG_TAG, msg);
+ }
+
+ protected void loge(String msg) {
+ Rlog.e(LOG_TAG, msg);
+ }
+
+ protected void loge(String msg, Throwable e) {
+ Rlog.e(LOG_TAG, msg, e);
}
}
diff --git a/src/java/com/android/internal/telephony/SubscriptionMonitor.java b/src/java/com/android/internal/telephony/SubscriptionMonitor.java
deleted file mode 100644
index 33376e1..0000000
--- a/src/java/com/android/internal/telephony/SubscriptionMonitor.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-* Copyright (C) 2015 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;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.RemoteException;
-import android.telephony.Rlog;
-import android.util.LocalLog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Utility singleton to monitor subscription changes and help people act on them.
- * Uses Registrant model to post messages to handlers.
- *
- */
-public class SubscriptionMonitor {
-
- private final RegistrantList mSubscriptionsChangedRegistrants[];
-
- private final SubscriptionController mSubscriptionController;
- private final Context mContext;
-
- private final int mPhoneSubId[];
-
- private final Object mLock = new Object();
-
- private final static boolean VDBG = true;
- private final static String LOG_TAG = "SubscriptionMonitor";
-
- private final static int MAX_LOGLINES = 100;
- private final LocalLog mLocalLog = new LocalLog(MAX_LOGLINES);
-
- public SubscriptionMonitor(ITelephonyRegistry tr, Context context,
- SubscriptionController subscriptionController, int numPhones) {
- mSubscriptionController = subscriptionController;
- mContext = context;
-
- mSubscriptionsChangedRegistrants = new RegistrantList[numPhones];
- mPhoneSubId = new int[numPhones];
-
- for (int phoneId = 0; phoneId < numPhones; phoneId++) {
- mSubscriptionsChangedRegistrants[phoneId] = new RegistrantList();
- mPhoneSubId[phoneId] = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
- }
-
- try {
- tr.addOnSubscriptionsChangedListener(context.getOpPackageName(),
- mSubscriptionsChangedListener);
- } catch (RemoteException e) {
- }
- }
-
- @VisibleForTesting
- public SubscriptionMonitor() {
- mSubscriptionsChangedRegistrants = null;
- mSubscriptionController = null;
- mContext = null;
- mPhoneSubId = null;
- }
-
- private final IOnSubscriptionsChangedListener mSubscriptionsChangedListener =
- new IOnSubscriptionsChangedListener.Stub() {
- @Override
- public void onSubscriptionsChanged() {
- synchronized (mLock) {
- for (int phoneId = 0; phoneId < mPhoneSubId.length; phoneId++) {
- final int newSubId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
- final int oldSubId = mPhoneSubId[phoneId];
- if (oldSubId != newSubId) {
- log("Phone[" + phoneId + "] subId changed " + oldSubId + "->" + newSubId
- + ", " + mSubscriptionsChangedRegistrants[phoneId].size()
- + " registrants");
- mPhoneSubId[phoneId] = newSubId;
- mSubscriptionsChangedRegistrants[phoneId].notifyRegistrants();
- }
- }
- }
- }
- };
-
- public void registerForSubscriptionChanged(int phoneId, Handler h, int what, Object o) {
- if (invalidPhoneId(phoneId)) {
- throw new IllegalArgumentException("Invalid PhoneId");
- }
- Registrant r = new Registrant(h, what, o);
- mSubscriptionsChangedRegistrants[phoneId].add(r);
- r.notifyRegistrant();
- }
-
- public void unregisterForSubscriptionChanged(int phoneId, Handler h) {
- if (invalidPhoneId(phoneId)) {
- throw new IllegalArgumentException("Invalid PhoneId");
- }
- mSubscriptionsChangedRegistrants[phoneId].remove(h);
- }
-
- private boolean invalidPhoneId(int phoneId) {
- if (phoneId >= 0 && phoneId < mPhoneSubId.length) return false;
- return true;
- }
-
- private void log(String s) {
- Rlog.d(LOG_TAG, s);
- mLocalLog.log(s);
- }
-
- public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- synchronized (mLock) {
- mLocalLog.dump(fd, printWriter, args);
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
index 78e7138..bdbf395 100644
--- a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -212,8 +213,14 @@
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL,
- intentFilter, null, null);
+ try {
+ Context contextAsUser = phone.getContext().createPackageContextAsUser(
+ phone.getContext().getPackageName(), 0, UserHandle.ALL);
+ contextAsUser.registerReceiver(mConfigChangedReceiver, intentFilter,
+ null /* broadcastPermission */, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ Rlog.e(TAG, "Package name not found: " + e.getMessage());
+ }
sendEmptyMessage(EVENT_BIND_QUALIFIED_NETWORKS_SERVICE);
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index d73c900..a26b561 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.dataconnection;
-import android.app.PendingIntent;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkConfig;
@@ -68,8 +67,6 @@
String mReason;
- PendingIntent mReconnectAlarmIntent;
-
/**
* user/app requested connection on this APN
*/
@@ -170,22 +167,6 @@
}
/**
- * Get the reconnect intent.
- * @return The reconnect intent
- */
- public synchronized PendingIntent getReconnectIntent() {
- return mReconnectAlarmIntent;
- }
-
- /**
- * Save the reconnect intent which can be used for cancelling later.
- * @param intent The reconnect intent
- */
- public synchronized void setReconnectIntent(PendingIntent intent) {
- mReconnectAlarmIntent = intent;
- }
-
- /**
* Get the current APN setting.
* @return APN setting
*/
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 53337fd..e151c7c 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -1329,6 +1329,16 @@
return result;
}
+ /** @return {@code true} if validation is required, {@code false} otherwise. */
+ public boolean isValidationRequired() {
+ final NetworkCapabilities nc = getNetworkCapabilities();
+ return nc != null
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
+ }
+
/**
* @return {@code True} if 464xlat should be skipped.
*/
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index 66d3064..f09d05f 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -133,9 +133,9 @@
final String[] pkgToGrant = {packageName};
try {
mPackageManager.grantDefaultPermissionsToEnabledTelephonyDataServices(
- pkgToGrant, mPhone.getContext().getUserId());
+ pkgToGrant, UserHandle.myUserId());
mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS,
- mPhone.getContext().getUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
+ UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
} catch (RemoteException e) {
loge("Binder to package manager died, permission grant for DataService failed.");
throw e.rethrowAsRuntimeException();
@@ -157,10 +157,9 @@
String[] dataServicesArray = new String[dataServices.size()];
dataServices.toArray(dataServicesArray);
mPackageManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- dataServicesArray, mPhone.getContext().getUserId());
+ dataServicesArray, UserHandle.myUserId());
for (String pkg : dataServices) {
- mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS,
- mPhone.getContext().getUserId(),
+ mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, UserHandle.myUserId(),
pkg, AppOpsManager.MODE_ERRORED);
}
} catch (RemoteException e) {
@@ -287,7 +286,14 @@
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-
+ try {
+ Context contextAsUser = phone.getContext().createPackageContextAsUser(
+ phone.getContext().getPackageName(), 0, UserHandle.ALL);
+ contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
+ null /* broadcastPermission */, null);
+ } catch (PackageManager.NameNotFoundException e) {
+ loge("Package name not found: " + e.getMessage());
+ }
PhoneConfigurationManager.registerForMultiSimConfigChange(
this, EVENT_BIND_DATA_SERVICE, null);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
index 381bc6e..ae773bb 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
@@ -187,7 +187,7 @@
DcTracker dct = mPhone.getDcTracker(mTransportType);
if (dct != null) {
Message msg = dct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- status, 0, redirectUrl);
+ status, mDataConnection.getCid(), redirectUrl);
msg.sendToTarget();
}
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index d2354e1..c30b6eb 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -66,9 +66,10 @@
import android.provider.Telephony;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
@@ -76,7 +77,6 @@
import android.telephony.PcoData;
import android.telephony.Rlog;
import android.telephony.ServiceState;
-import android.telephony.ServiceState.RilRadioTechnology;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
@@ -254,14 +254,6 @@
private static final boolean DATA_STALL_SUSPECTED = true;
private static final boolean DATA_STALL_NOT_SUSPECTED = false;
- private static final String INTENT_RECONNECT_ALARM =
- "com.android.internal.telephony.data-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON =
- "reconnect_alarm_extra_reason";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_TRANSPORT_TYPE =
- "reconnect_alarm_extra_transport_type";
-
private static final String INTENT_DATA_STALL_ALARM =
"com.android.internal.telephony.data-stall";
// Tag for tracking stale alarms
@@ -358,8 +350,6 @@
stopNetStatPoll();
startNetStatPoll();
restartDataStallAlarm();
- } else if (action.startsWith(INTENT_RECONNECT_ALARM)) {
- onActionIntentReconnectAlarm(intent);
} else if (action.equals(INTENT_DATA_STALL_ALARM)) {
onActionIntentDataStallAlarm(intent);
} else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
@@ -491,28 +481,13 @@
}
}
- private void onActionIntentReconnectAlarm(Intent intent) {
- Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT);
- msg.setData(intent.getExtras());
- sendMessage(msg);
- }
-
- private void onDataReconnect(Bundle bundle) {
- String reason = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- String apnType = bundle.getString(INTENT_RECONNECT_ALARM_EXTRA_TYPE);
-
+ private void onDataReconnect(ApnContext apnContextforRetry, int subId) {
int phoneSubId = mPhone.getSubId();
- int currSubId = bundle.getInt(PhoneConstants.SUBSCRIPTION_KEY,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ String apnType = apnContextforRetry.getApnType();
+ String reason = apnContextforRetry.getReason();
- // Stop reconnect if not current subId is not correct.
- // FIXME STOPSHIP - phoneSubId is coming up as -1 way after boot and failing this?
- if (!SubscriptionManager.isValidSubscriptionId(currSubId) || (currSubId != phoneSubId)) {
- return;
- }
-
- int transportType = bundle.getInt(INTENT_RECONNECT_ALARM_EXTRA_TRANSPORT_TYPE, 0);
- if (transportType != mTransportType) {
+ if (!SubscriptionManager.isValidSubscriptionId(subId) || (subId != phoneSubId)) {
+ log("onDataReconnect: invalid subId");
return;
}
@@ -540,8 +515,6 @@
}
// TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, apnContext));
-
- apnContext.setReconnectIntent(null);
}
}
@@ -749,13 +722,6 @@
initApnContexts();
- for (ApnContext apnContext : mApnContexts.values()) {
- // Register the reconnect and restart actions.
- filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
- mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
- }
-
initEmergencyApnSetting();
addEmergencyApnSetting();
@@ -1753,7 +1719,7 @@
// Make sure reconnection alarm is cleaned up if there is no ApnContext
// associated to the connection.
if (dataConnection != null) {
- cancelReconnectAlarm(apnContext);
+ cancelReconnect(apnContext);
}
str = "cleanUpConnectionInternal: X detach=" + detach + " reason="
+ apnContext.getReason();
@@ -1856,24 +1822,6 @@
return null;
}
- /**
- * Cancels the alarm associated with apnContext.
- *
- * @param apnContext on which the alarm should be stopped.
- */
- private void cancelReconnectAlarm(ApnContext apnContext) {
- if (apnContext == null) return;
-
- PendingIntent intent = apnContext.getReconnectIntent();
-
- if (intent != null) {
- AlarmManager am =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
- am.cancel(intent);
- apnContext.setReconnectIntent(null);
- }
- }
-
boolean isPermanentFailure(@DataFailureCause int dcFailCause) {
return (DataFailCause.isPermanentFailure(mPhone.getContext(), dcFailCause,
mPhone.getSubId())
@@ -2198,31 +2146,31 @@
return retry;
}
- private void startAlarmForReconnect(long delay, ApnContext apnContext) {
- String apnType = apnContext.getApnType();
-
- Intent intent = new Intent(INTENT_RECONNECT_ALARM + "." + apnType);
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, apnType);
- intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TRANSPORT_TYPE, mTransportType);
- SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ private void startReconnect(long delay, ApnContext apnContext) {
+ Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
+ mPhone.getSubId(), mTransportType, apnContext);
+ cancelReconnect(apnContext);
+ sendMessageDelayed(msg, delay);
if (DBG) {
- log("startAlarmForReconnect: delay=" + delay + " action=" + intent.getAction()
- + " apn=" + apnContext);
+ log("startReconnect: delay=" + delay + " apn="
+ + apnContext + "reason: " + apnContext.getReason()
+ + " subId: " + mPhone.getSubId());
}
+ }
- PendingIntent alarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0,
- intent, PendingIntent.FLAG_UPDATE_CURRENT);
- apnContext.setReconnectIntent(alarmIntent);
+ /**
+ * Cancels the alarm associated with apnContext.
+ *
+ * @param apnContext on which the alarm should be stopped.
+ */
+ private void cancelReconnect(ApnContext apnContext) {
+ if (apnContext == null) return;
- // Use the exact timer instead of the inexact one to provide better user experience.
- // In some extreme cases, we saw the retry was delayed for few minutes.
- // Note that if the stated trigger time is in the past, the alarm will be triggered
- // immediately.
- mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + delay, alarmIntent);
+ if (DBG) {
+ log("cancelReconnect: apn=" + apnContext);
+ }
+ removeMessages(DctConstants.EVENT_DATA_RECONNECT, apnContext);
}
private void notifyNoData(@DataFailureCause int lastFailCauseCode,
@@ -2903,7 +2851,7 @@
// Wait a bit before trying the next APN, so that
// we're not tying up the RIL command channel
- startAlarmForReconnect(delay, apnContext);
+ startReconnect(delay, apnContext);
} else {
// If we are not going to retry any APN, set this APN context to failed state.
// This would be the final state of a data connection.
@@ -2920,10 +2868,11 @@
*
* @param status One of {@code NetworkAgent.VALID_NETWORK} or
* {@code NetworkAgent.INVALID_NETWORK}.
+ * @param cid context id {@code cid}
* @param redirectUrl If the Internet probe was redirected, this
* is the destination it was redirected to, otherwise {@code null}
*/
- private void onNetworkStatusChanged(int status, String redirectUrl) {
+ private void onNetworkStatusChanged(int status, int cid, String redirectUrl) {
if (!TextUtils.isEmpty(redirectUrl)) {
Intent intent = new Intent(TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, redirectUrl);
@@ -2931,6 +2880,7 @@
log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
} else {
final boolean isValid = status == NetworkAgent.VALID_NETWORK;
+ final DataConnection dc = getDataConnectionByContextId(cid);
if (!mDsRecoveryHandler.isRecoveryOnBadNetworkEnabled()) {
if (DBG) log("Skip data stall recovery on network status change with in threshold");
return;
@@ -2939,7 +2889,9 @@
if (DBG) log("Skip data stall recovery on non WWAN");
return;
}
- mDsRecoveryHandler.processNetworkStatusChanged(isValid);
+ if (dc != null && dc.isValidationRequired()) {
+ mDsRecoveryHandler.processNetworkStatusChanged(isValid);
+ }
}
}
@@ -2996,7 +2948,7 @@
if (delay > 0) {
// Data connection is in IDLE state, so when we reconnect later, we'll rebuild
// the waiting APN list, which will also reset/reconfigure the retry manager.
- startAlarmForReconnect(delay, apnContext);
+ startReconnect(delay, apnContext);
}
} else {
boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
@@ -3291,16 +3243,11 @@
apnList = sortApnListByPreferred(apnList);
if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
return apnList;
- } else {
- if (DBG) log("buildWaitingApns: no preferred APN");
- setPreferredApn(-1);
- mPreferredApn = null;
}
- } else {
- if (DBG) log("buildWaitingApns: no preferred APN");
- setPreferredApn(-1);
- mPreferredApn = null;
}
+ if (DBG) log("buildWaitingApns: no preferred APN");
+ setPreferredApn(-1);
+ mPreferredApn = null;
}
if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
@@ -3588,8 +3535,9 @@
case DctConstants.EVENT_NETWORK_STATUS_CHANGED:
int status = msg.arg1;
+ int cid = msg.arg2;
String url = (String) msg.obj;
- onNetworkStatusChanged(status, url);
+ onNetworkStatusChanged(status, cid, url);
break;
case DctConstants.EVENT_RADIO_AVAILABLE:
@@ -3780,7 +3728,8 @@
break;
}
case DctConstants.EVENT_DATA_RECONNECT:
- onDataReconnect(msg.getData());
+ if (DBG) log("EVENT_DATA_RECONNECT: subId=" + msg.arg1);
+ onDataReconnect((ApnContext) msg.obj, msg.arg1);
break;
case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
@@ -4190,19 +4139,20 @@
return;
}
for (ApnContext apnContext : mApnContexts.values()) {
- ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
- ArrayList<ApnSetting> waitingApns = buildWaitingApns(
- apnContext.getApnType(), getDataRat());
- if (VDBG) log("new waitingApns:" + waitingApns);
- if ((currentWaitingApns != null)
- && ((waitingApns.size() != currentWaitingApns.size())
- // Check if the existing waiting APN list can cover the newly built APN
- // list. If yes, then we don't need to tear down the existing data call.
- // TODO: We probably need to rebuild APN list when roaming status changes.
- || !containsAllApns(currentWaitingApns, waitingApns))) {
- if (VDBG) log("new waiting apn is different for " + apnContext);
- apnContext.setWaitingApns(waitingApns);
- if (!apnContext.isDisconnected()) {
+ if (!apnContext.isDisconnected()) {
+ ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
+ ArrayList<ApnSetting> waitingApns = buildWaitingApns(
+ apnContext.getApnType(), getDataRat());
+ if (VDBG) log("new waitingApns:" + waitingApns);
+ if ((currentWaitingApns != null)
+ && ((waitingApns.size() != currentWaitingApns.size())
+ // Check if the existing waiting APN list can cover the newly built APN
+ // list. If yes, then we don't need to tear down the existing data call.
+ // TODO: We probably need to rebuild APN list when roaming status
+ // changes.
+ || !containsAllApns(currentWaitingApns, waitingApns))) {
+ if (VDBG) log("new waiting apn is different for " + apnContext);
+ apnContext.setWaitingApns(waitingApns);
if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
apnContext.setReason(reason);
cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, apnContext);
diff --git a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index fa9723a..f739c2c 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -30,13 +30,15 @@
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.ApnType;
import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.util.LocalLog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneSwitcher;
import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.SubscriptionMonitor;
import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
@@ -60,7 +62,8 @@
private static final int TELEPHONY_NETWORK_SCORE = 50;
private static final int EVENT_ACTIVE_PHONE_SWITCH = 1;
- private static final int EVENT_SUBSCRIPTION_CHANGED = 2;
+ @VisibleForTesting
+ public static final int EVENT_SUBSCRIPTION_CHANGED = 2;
private static final int EVENT_NETWORK_REQUEST = 3;
private static final int EVENT_NETWORK_RELEASE = 4;
private static final int EVENT_DATA_HANDOVER_NEEDED = 5;
@@ -68,7 +71,6 @@
private final PhoneSwitcher mPhoneSwitcher;
private final SubscriptionController mSubscriptionController;
- private final SubscriptionMonitor mSubscriptionMonitor;
private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);
// Key: network request. Value: the transport of DcTracker it applies to,
@@ -83,11 +85,11 @@
private int mSubscriptionId;
- private final Handler mInternalHandler;
+ @VisibleForTesting
+ public final Handler mInternalHandler;
- public TelephonyNetworkFactory(SubscriptionMonitor subscriptionMonitor, Looper looper,
- Phone phone) {
+ public TelephonyNetworkFactory(Looper looper, Phone phone) {
super(looper, phone.getContext(), "TelephonyNetworkFactory[" + phone.getPhoneId()
+ "]", null);
mPhone = phone;
@@ -100,7 +102,6 @@
setScoreFilter(TELEPHONY_NETWORK_SCORE);
mPhoneSwitcher = PhoneSwitcher.getInstance();
- mSubscriptionMonitor = subscriptionMonitor;
LOG_TAG = "TelephonyNetworkFactory[" + mPhone.getPhoneId() + "]";
mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH,
@@ -109,12 +110,20 @@
EVENT_DATA_HANDOVER_NEEDED);
mSubscriptionId = INVALID_SUBSCRIPTION_ID;
- mSubscriptionMonitor.registerForSubscriptionChanged(mPhone.getPhoneId(), mInternalHandler,
- EVENT_SUBSCRIPTION_CHANGED, null);
+ SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
+ mSubscriptionsChangedListener);
register();
}
+ private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener =
+ new SubscriptionManager.OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ mInternalHandler.sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED);
+ }
+ };
+
private NetworkCapabilities makeNetworkFilter(SubscriptionController subscriptionController,
int phoneId) {
final int subscriptionId = subscriptionController.getSubIdUsingPhoneId(phoneId);
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index af2c61b..27c4f99 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -225,7 +225,7 @@
}
break;
case EVENT_UPDATE_EMERGENCY_NUMBER_TEST_MODE:
- if (msg.obj == null) {
+ if (msg.obj == null && msg.arg1 != RESET_EMERGENCY_NUMBER_TEST_MODE) {
loge("EVENT_UPDATE_EMERGENCY_NUMBER_TEST_MODE: Result from"
+ " executeEmergencyNumberTestModeCommand is null.");
} else {
diff --git a/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java b/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java
index 052d89c..1494480 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmCellBroadcastHandler.java
@@ -26,6 +26,7 @@
import android.os.AsyncResult;
import android.os.Message;
import android.provider.Telephony.CellBroadcasts;
+import android.telephony.CbGeoUtils.Geometry;
import android.telephony.CellLocation;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
@@ -33,7 +34,6 @@
import android.telephony.gsm.GsmCellLocation;
import android.text.format.DateUtils;
-import com.android.internal.telephony.CbGeoUtils.Geometry;
import com.android.internal.telephony.CellBroadcastHandler;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage;
@@ -138,7 +138,7 @@
// cell broadcasts.
int maximumWaitTimeSec = 0;
for (SmsCbMessage msg : cbMessages) {
- maximumWaitTimeSec = Math.max(maximumWaitTimeSec, msg.getMaximumWaitingTime());
+ maximumWaitTimeSec = Math.max(maximumWaitTimeSec, msg.getMaximumWaitingDuration());
}
if (DBG) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index 2c3ed6d..a8cc125 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -539,7 +539,6 @@
context.registerReceiverAsUser(mAppChangedReceiver, UserHandle.ALL, appChangedFilter,
null,
null);
-
context.registerReceiver(mConfigChangedReceiver, new IntentFilter(
CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
context.registerReceiver(mBootCompleted, new IntentFilter(
@@ -1363,7 +1362,7 @@
for (ResolveInfo entry : packageManager.queryIntentServicesAsUser(
serviceIntent,
PackageManager.GET_META_DATA,
- UserHandle.getUserHandleForUid(mContext.getUserId()))) {
+ UserHandle.getUserHandleForUid(UserHandle.myUserId()))) {
ServiceInfo serviceInfo = entry.serviceInfo;
if (serviceInfo != null) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index af26eba..c4b7399 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -27,6 +27,7 @@
import android.os.IInterface;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.telephony.ims.ImsService;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsMmTelFeature;
@@ -639,7 +640,7 @@
try {
if (mPackageManager != null) {
mPackageManager.grantDefaultPermissionsToEnabledImsServices(pkgToGrant,
- mContext.getUserId());
+ UserHandle.myUserId());
}
} catch (RemoteException e) {
Log.w(LOG_TAG, "Unable to grant permissions, binder died.");
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 7a863d0..bf2a00c 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -24,6 +24,7 @@
import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_ALL;
import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_MO;
import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BA_MT;
+import static com.android.internal.telephony.CommandsInterface.CB_FACILITY_BIC_ACR;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ERASURE;
@@ -46,6 +47,7 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.net.NetworkStats;
import android.net.Uri;
import android.os.AsyncResult;
@@ -203,7 +205,10 @@
private ServiceState mSS = new ServiceState();
private RcsFeatureManager mRcsManager;
- private final FeatureConnector<RcsFeatureManager> mRcsManagerConnector;
+ @VisibleForTesting
+ public FeatureConnector<RcsFeatureManager> mRcsManagerConnector;
+ @VisibleForTesting
+ public FeatureConnector.Listener<RcsFeatureManager> mRcsFeatureConnectorListener;
// To redial silently through GSM or CDMA when dialing through IMS fails
private String mLastDialString;
@@ -330,34 +335,9 @@
// Force initial roaming state update later, on EVENT_CARRIER_CONFIG_CHANGED.
// Settings provider or CarrierConfig may not be loaded now.
- mRcsManagerConnector = new FeatureConnector<RcsFeatureManager>(mContext, mPhoneId,
- new FeatureConnector.Listener<RcsFeatureManager>() {
- @Override
- public boolean isSupported() {
- if (!ImsManager.isImsSupportedOnDevice(mContext)) {
- return false;
- }
- if (!RcsFeatureManager.isRcsUceSupportedByCarrier(mContext, mPhoneId)) {
- return false;
- }
- return true;
- }
-
- @Override
- public RcsFeatureManager getFeatureManager() {
- return new RcsFeatureManager(mContext, mPhoneId);
- }
-
- @Override
- public void connectionReady(RcsFeatureManager manager) throws ImsException {
- mRcsManager = manager;
- }
-
- @Override
- public void connectionUnavailable() {
- }
- }, mContext.getMainExecutor(), "ImsPhone");
- mRcsManagerConnector.connect();
+ // Listen to the carrier config changed to initialize RcsFeatureManager
+ IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ mContext.registerReceiver(mCarrierConfigChangedReceiver, filter);
}
//todo: get rid of this function. It is not needed since parentPhone obj never changes
@@ -381,7 +361,75 @@
mDefaultPhone.unregisterForServiceStateChanged(this);
}
- mRcsManagerConnector.disconnect();
+ mContext.unregisterReceiver(mCarrierConfigChangedReceiver);
+
+ if (mRcsManagerConnector != null) {
+ mRcsManagerConnector.disconnect();
+ mRcsManagerConnector = null;
+ }
+ }
+
+ private BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+ Bundle bundle = intent.getExtras();
+ if (bundle == null) {
+ return;
+ }
+ int phoneId = bundle.getInt(CarrierConfigManager.EXTRA_SLOT_INDEX);
+ if (phoneId == mPhoneId) {
+ sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
+ }
+ }
+ }
+ };
+
+ /**
+ * Create RcsManagerConnector to initialize RcsFeatureManager
+ */
+ @VisibleForTesting
+ public void initRcsFeatureManager() {
+ if (mRcsManagerConnector != null) {
+ mRcsManagerConnector.disconnect();
+ mRcsManagerConnector = null;
+ }
+
+ logd("initRcsFeatureManager");
+ mRcsFeatureConnectorListener = new FeatureConnector.Listener<>() {
+ @Override
+ public boolean isSupported() {
+ // Check if Telephony IMS is supported or not
+ if (!ImsManager.isImsSupportedOnDevice(mContext)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public RcsFeatureManager getFeatureManager() {
+ return new RcsFeatureManager(mContext, mPhoneId);
+ }
+
+ @Override
+ public void connectionReady(RcsFeatureManager manager) throws ImsException {
+ logd("RcsFeatureManager is ready");
+ mRcsManager = manager;
+ }
+
+ @Override
+ public void connectionUnavailable() {
+ logd("RcsFeatureManager is unavailable");
+ mRcsManager = null;
+ }
+ };
+
+ mRcsManagerConnector = new FeatureConnector<>(mContext, mPhoneId,
+ mRcsFeatureConnectorListener, mContext.getMainExecutor(), LOG_TAG);
+ mRcsManagerConnector.connect();
}
@UnsupportedAppUsage
@@ -1128,6 +1176,8 @@
return ImsUtInterface.CB_BA_MO;
} else if (CB_FACILITY_BA_MT.equals(facility)) {
return ImsUtInterface.CB_BA_MT;
+ } else if (CB_FACILITY_BIC_ACR.equals(facility)) {
+ return ImsUtInterface.CB_BIC_ACR;
}
return 0;
@@ -1588,6 +1638,12 @@
updateRoamingState(sst.mSS);
}
break;
+ case EVENT_CARRIER_CONFIG_CHANGED:
+ if (DBG) logd("EVENT_CARRIER_CONFIG_CHANGED");
+ if (mRcsManager == null) {
+ initRcsFeatureManager();
+ }
+ break;
default:
super.handleMessage(msg);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 0070e3d..cdc03aa 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -912,6 +912,7 @@
mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
pendingCallClirMode = clirMode;
mPendingCallVideoState = videoState;
+ mPendingIntentExtras = dialArgs.intentExtras;
pendingCallInEcm = true;
}
}
diff --git a/src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java b/src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java
index 5b41d8e..dbadde1 100644
--- a/src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java
@@ -172,16 +172,26 @@
}
private void clearNetworkStateAndRerunDetection(String reason) {
- // Assume any previous NITZ signals received are now invalid.
+ if (mLatestNitzSignal == null) {
+ // The network state is already empty so there's no need to do anything.
+ if (DBG) {
+ Rlog.d(LOG_TAG, reason + ": mLatestNitzSignal was already null. Nothing to do.");
+ }
+ return;
+ }
+
+ // The previous NITZ signal received is now invalid so clear it.
mLatestNitzSignal = null;
+ // countryIsoCode can be assigned null here, in which case the doTimeZoneDetection() call
+ // below will do nothing, which is ok as nothing will have changed.
String countryIsoCode = mCountryIsoCode;
-
if (DBG) {
Rlog.d(LOG_TAG, reason + ": countryIsoCode=" + countryIsoCode);
}
- // Generate a new time zone suggestion and update the service as needed.
+ // Generate a new time zone suggestion (which could be an empty suggestion) and update the
+ // service as needed.
doTimeZoneDetection(countryIsoCode, null /* nitzSignal */, reason);
// Generate a new time suggestion and update the service as needed.
@@ -258,7 +268,7 @@
// will be made after airplane mode is re-enabled as the device re-establishes network
// connectivity.
- // Clear time zone detection state.
+ // Clear country detection state.
mCountryIsoCode = null;
String reason = "handleAirplaneModeChanged(" + on + ")";
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index db581b2..261b60e 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -46,6 +46,7 @@
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.emergency.EmergencyNumber;
@@ -1179,6 +1180,14 @@
}
}
+ // Store different cids to simulate concurrent IMS and default data calls
+ if ((dataProfile.getSupportedApnTypesBitmask() & ApnSetting.TYPE_IMS)
+ == ApnSetting.TYPE_IMS) {
+ mSetupDataCallResult.cid = 0;
+ } else {
+ mSetupDataCallResult.cid = 1;
+ }
+
DataCallResponse response = RIL.convertDataCallResult(mSetupDataCallResult);
if (mDcSuccess) {
resultSuccess(result, response);
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 77278d1..0c2c60b 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -26,6 +26,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
+import android.os.UserHandle;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -319,7 +320,7 @@
dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(EXTRA_ICC_CARD_ADDED, isAdded);
try {
- mContext.startActivity(intent);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
return;
} catch (ActivityNotFoundException e) {
loge("Unable to find ICC hotswap prompt for restart activity: " + e);
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
index 1f72ae8..00b4945 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.os.Handler;
+import android.os.Looper;
import android.telephony.IccOpenLogicalChannelResponse;
import android.telephony.Rlog;
@@ -50,10 +51,16 @@
private static final int STATUS_NO_ERROR = 0x9000;
private static final int SW1_NO_ERROR = 0x91;
+ private static final int WAIT_TIME_MS = 2000;
+
private static void logv(String msg) {
Rlog.v(LOG_TAG, msg);
}
+ private static void logd(String msg) {
+ Rlog.d(LOG_TAG, msg);
+ }
+
private final String mAid;
private final boolean mSupportExtendedApdu;
private final OpenLogicalChannelInvocation mOpenChannel;
@@ -94,10 +101,25 @@
Handler handler) {
synchronized (mChannelLock) {
if (mChannelOpened) {
- AsyncResultHelper.throwException(
- new ApduException("Logical channel has already been opened."),
- resultCallback, handler);
- return;
+ if (!Looper.getMainLooper().equals(Looper.myLooper())) {
+ logd("Logical channel has already been opened. Wait.");
+ try {
+ mChannelLock.wait(WAIT_TIME_MS);
+ } catch (InterruptedException e) {
+ // nothing to do
+ }
+ if (mChannelOpened) {
+ AsyncResultHelper.throwException(
+ new ApduException("The logical channel is still in use."),
+ resultCallback, handler);
+ return;
+ }
+ } else {
+ AsyncResultHelper.throwException(
+ new ApduException("The logical channel is in use."),
+ resultCallback, handler);
+ return;
+ }
}
mChannelOpened = true;
}
@@ -111,6 +133,7 @@
|| status != IccOpenLogicalChannelResponse.STATUS_NO_ERROR) {
synchronized (mChannelLock) {
mChannelOpened = false;
+ mChannelLock.notify();
}
resultCallback.onException(
new ApduException("Failed to open logical channel opened for AID: "
@@ -245,6 +268,7 @@
public void onResult(Boolean aBoolean) {
synchronized (mChannelLock) {
mChannelOpened = false;
+ mChannelLock.notify();
}
if (exception == null) {
diff --git a/src/java/com/android/internal/telephony/util/TelephonyUtils.java b/src/java/com/android/internal/telephony/util/TelephonyUtils.java
index 1048e5c..ea44d98 100644
--- a/src/java/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/src/java/com/android/internal/telephony/util/TelephonyUtils.java
@@ -25,6 +25,8 @@
* This class provides various util functions
*/
public final class TelephonyUtils {
+ public static boolean IS_USER = "user".equals(android.os.Build.TYPE);
+
/** {@hide} */
public static String emptyIfNull(@Nullable String str) {
return str == null ? "" : str;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CbGeoUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CbGeoUtilsTest.java
index 787cb43..f9b3599 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CbGeoUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CbGeoUtilsTest.java
@@ -18,10 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
-import com.android.internal.telephony.CbGeoUtils.Circle;
-import com.android.internal.telephony.CbGeoUtils.Geometry;
-import com.android.internal.telephony.CbGeoUtils.LatLng;
-import com.android.internal.telephony.CbGeoUtils.Polygon;
+import android.telephony.CbGeoUtils;
+import android.telephony.CbGeoUtils.Circle;
+import android.telephony.CbGeoUtils.Geometry;
+import android.telephony.CbGeoUtils.LatLng;
+import android.telephony.CbGeoUtils.Polygon;
import org.junit.Test;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index fc4dcc6..305046c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -61,7 +61,7 @@
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.telephony.TelephonyRegistryManager;
+import android.telephony.TelephonyRegistryManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Telephony.ServiceStateTable;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 5c09525..ae8dd62 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -158,14 +158,6 @@
public void testGetMergedServiceState() throws Exception {
ServiceState imsServiceState = new ServiceState();
- NetworkRegistrationInfo imsCsWwanRegInfo = new NetworkRegistrationInfo.Builder()
- .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
- .setRegistrationState(
- NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
-
NetworkRegistrationInfo imsPsWwanRegInfo = new NetworkRegistrationInfo.Builder()
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
@@ -182,10 +174,11 @@
NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
- imsServiceState.addNetworkRegistrationInfo(imsCsWwanRegInfo);
+ // Only PS states are tracked for IMS.
imsServiceState.addNetworkRegistrationInfo(imsPsWwanRegInfo);
imsServiceState.addNetworkRegistrationInfo(imsPsWlanRegInfo);
+ // Voice reg state in this case is whether or not IMS is registered.
imsServiceState.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
imsServiceState.setIwlanPreferred(true);
@@ -236,6 +229,88 @@
assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mergedServiceState.getDataNetworkType());
}
+ /**
+ * Some vendors do not provide a voice registration for LTE when attached to LTE only (no CSFB
+ * available). In this case, we should still get IN_SERVICE for voice service state, since
+ * IMS is registered.
+ */
+ @Test
+ @SmallTest
+ public void testGetMergedServiceStateNoCsfb() throws Exception {
+ ServiceState imsServiceState = new ServiceState();
+
+ NetworkRegistrationInfo imsPsWwanRegInfo = new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+ .setRegistrationState(
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+ .build();
+
+ NetworkRegistrationInfo imsPsWlanRegInfo = new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
+ .setRegistrationState(
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
+ .build();
+
+ // Only PS states are tracked for IMS.
+ imsServiceState.addNetworkRegistrationInfo(imsPsWwanRegInfo);
+ imsServiceState.addNetworkRegistrationInfo(imsPsWlanRegInfo);
+
+ // Voice reg state in this case is whether or not IMS is registered.
+ imsServiceState.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ imsServiceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
+ imsServiceState.setIwlanPreferred(true);
+ doReturn(imsServiceState).when(mImsPhone).getServiceState();
+
+ replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
+
+ ServiceState serviceState = new ServiceState();
+
+ NetworkRegistrationInfo csWwanRegInfo = new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+ .setRegistrationState(
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
+ .build();
+
+ NetworkRegistrationInfo psWwanRegInfo = new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+ .setRegistrationState(
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+ .build();
+
+ NetworkRegistrationInfo psWlanRegInfo = new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
+ .setRegistrationState(
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
+ .build();
+
+ serviceState.addNetworkRegistrationInfo(csWwanRegInfo);
+ serviceState.addNetworkRegistrationInfo(psWwanRegInfo);
+ serviceState.addNetworkRegistrationInfo(psWlanRegInfo);
+ // No CSFB, voice is OOS for LTE only attach
+ serviceState.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+ serviceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
+ serviceState.setIwlanPreferred(true);
+
+ mSST.mSS = serviceState;
+ mPhoneUT.mSST = mSST;
+
+ ServiceState mergedServiceState = mPhoneUT.getServiceState();
+
+ assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getVoiceRegState());
+ assertEquals(ServiceState.STATE_IN_SERVICE, mergedServiceState.getDataRegState());
+ assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mergedServiceState.getDataNetworkType());
+ }
+
@Test
@SmallTest
public void testGetSubscriberIdForGsmPhone() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
index d195c2e..a2cfea0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
@@ -16,33 +16,51 @@
package com.android.internal.telephony;
-import android.test.AndroidTestCase;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
import android.test.suitebuilder.annotation.SmallTest;
-import org.junit.Ignore;
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.telephony.MccTable.MccMnc;
+
+import org.junit.Test;
import java.util.Locale;
-// TODO try using InstrumentationRegistry.getContext() instead of the default
-// AndroidTestCase context
-public class MccTableTest extends AndroidTestCase {
- private final static String LOG_TAG = "GSM";
+public class MccTableTest {
@SmallTest
- @Ignore
- public void testCountryCode() throws Exception {
- assertEquals("lu", MccTable.countryCodeForMcc(270));
- assertEquals("gr", MccTable.countryCodeForMcc(202));
- assertEquals("fk", MccTable.countryCodeForMcc(750));
- assertEquals("mg", MccTable.countryCodeForMcc(646));
- assertEquals("us", MccTable.countryCodeForMcc(314));
- assertEquals("", MccTable.countryCodeForMcc(300)); // mcc not defined, hence default
- assertEquals("", MccTable.countryCodeForMcc(0)); // mcc not defined, hence default
- assertEquals("", MccTable.countryCodeForMcc(2000)); // mcc not defined, hence default
+ @Test
+ public void testCountryCodeForMcc() throws Exception {
+ checkMccLookupWithNoMnc("lu", 270);
+ checkMccLookupWithNoMnc("gr", 202);
+ checkMccLookupWithNoMnc("fk", 750);
+ checkMccLookupWithNoMnc("mg", 646);
+ checkMccLookupWithNoMnc("us", 314);
+ checkMccLookupWithNoMnc("", 300); // mcc not defined, hence default
+ checkMccLookupWithNoMnc("", 0); // mcc not defined, hence default
+ checkMccLookupWithNoMnc("", 2000); // mcc not defined, hence default
+ }
+
+ private void checkMccLookupWithNoMnc(String expectedCountryIsoCode, int mcc) {
+ assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc));
+ assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc));
+ assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc("" + mcc));
+ assertEquals(expectedCountryIsoCode,
+ MccTable.geoCountryCodeForMccMnc(new MccMnc("" + mcc, "999")));
}
@SmallTest
- @Ignore
+ @Test
+ public void testGeoCountryCodeForMccMnc() throws Exception {
+ // This test is possibly fragile as this data is configurable.
+ assertEquals("gu", MccTable.geoCountryCodeForMccMnc(new MccMnc("310", "370")));
+ }
+
+ @SmallTest
+ @Test
public void testLang() throws Exception {
assertEquals("en", MccTable.defaultLanguageForMcc(311));
assertEquals("de", MccTable.defaultLanguageForMcc(232));
@@ -54,7 +72,7 @@
}
@SmallTest
- @Ignore
+ @Test
public void testLang_India() throws Exception {
assertEquals("en", MccTable.defaultLanguageForMcc(404));
assertEquals("en", MccTable.defaultLanguageForMcc(405));
@@ -62,7 +80,7 @@
}
@SmallTest
- @Ignore
+ @Test
public void testLocale() throws Exception {
assertEquals(Locale.forLanguageTag("en-CA"),
MccTable.getLocaleFromMcc(getContext(), 302, null));
@@ -78,8 +96,12 @@
MccTable.getLocaleFromMcc(getContext(), 466, null));
}
+ private Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
@SmallTest
- @Ignore
+ @Test
public void testSmDigits() throws Exception {
assertEquals(3, MccTable.smallestDigitsMccForMnc(312));
assertEquals(2, MccTable.smallestDigitsMccForMnc(430));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java
index 3702d3e..1f554a8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineImplTest.java
@@ -102,6 +102,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -221,6 +222,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -254,6 +256,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
// A valid NITZ signal for the non-default zone should still be correctly detected.
@@ -268,6 +271,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
// Demonstrate what happens with a bogus NITZ for NZ: because the default zone is boosted
@@ -285,6 +289,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(expectedTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
}
@@ -318,6 +323,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
// A valid NITZ signal for a different zone should also be correctly detected.
@@ -332,6 +338,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
// Demonstrate what happens with a bogus NITZ for US: because the default zone is not
@@ -346,8 +353,9 @@
.verifyNothingWasSetAndReset();
// Check NitzStateMachine state.
- assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
}
@@ -374,6 +382,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -399,6 +408,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -423,6 +433,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -432,6 +443,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -455,6 +467,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode());
@@ -465,6 +478,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -490,6 +504,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -498,6 +513,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -520,6 +536,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Simulate receiving an NITZ signal.
script.nitzReceived(goodNitzSignal);
@@ -534,6 +551,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -568,6 +586,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -576,6 +595,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -606,6 +626,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Simulate receiving an NITZ signal.
script.nitzReceived(badNitzSignal);
@@ -618,6 +639,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -651,6 +673,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -661,6 +684,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -692,6 +716,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate receiving an NITZ signal.
script.nitzReceived(badNitzSignal);
@@ -704,6 +729,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -740,6 +766,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(emulatorNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(emulatorTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -759,6 +786,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate receiving the NITZ signal.
TimestampedValue<NitzData> nitzSignal =
@@ -772,6 +800,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -797,6 +826,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// The time zone should be set (but the country is not valid so it's unlikely to be
// correct).
@@ -805,6 +835,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(nitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -842,7 +873,9 @@
.verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(preflightNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Boarded flight: Airplane mode turned on / time zone detection still enabled.
// The NitzStateMachineImpl must lose all state and stop having an opinion about time zone.
@@ -854,7 +887,9 @@
script.toggleAirplaneMode(true);
// Check state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Verify there's no time zone opinion by toggling auto time zone off and on.
script.toggleTimeZoneDetectionEnabled(false)
@@ -878,7 +913,9 @@
.verifyNothingWasSetAndReset();
// Check the state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Post flight: Device has moved and receives new signals.
@@ -903,7 +940,9 @@
scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(postFlightNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
/**
@@ -944,7 +983,9 @@
.verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(initialNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Simulate losing the network. The NitzStateMachineImpl must lose all NITZ state and stop
// having an opinion about time zone.
@@ -956,7 +997,9 @@
script.incrementTime(timeStepMillis);
// Check state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Verify there's no time zone opinion by toggling auto time zone off and on.
script.toggleTimeZoneDetectionEnabled(false)
@@ -978,7 +1021,9 @@
.verifyNothingWasSetAndReset();
// Check the state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the passage of time and update the device realtime clock.
scenario.incrementTime(timeStepMillis);
@@ -996,7 +1041,9 @@
scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(finalNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
/**
@@ -1037,7 +1084,9 @@
.verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(initialNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Simulate losing the network. The NitzStateMachineImpl must lose all NITZ state but should
// retain country knowledge and so remain opinionated about time zone ID because the country
@@ -1050,7 +1099,9 @@
script.incrementTime(timeStepMillis);
// Check state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Verify there's a time zone opinion by toggling auto time zone off and on.
script.toggleTimeZoneDetectionEnabled(false)
@@ -1072,7 +1123,9 @@
.verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
// Check the state that NitzStateMachine must expose.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
// Simulate the passage of time and update the device realtime clock.
scenario.incrementTime(timeStepMillis);
@@ -1090,7 +1143,9 @@
scenario.getTimeZoneId());
// Check state that NitzStateMachine must expose.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(finalNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
/**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index fe0e74f..9ff0d18 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -54,6 +54,7 @@
import android.os.Messenger;
import android.telephony.PhoneCapability;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -81,8 +82,6 @@
private static final int ACTIVE_PHONE_SWITCH = 1;
@Mock
- private ITelephonyRegistry.Stub mTelRegistryMock;
- @Mock
private ITelephonyRegistry mTelRegistryInterfaceMock;
@Mock
private CommandsInterface mCommandsInterface0;
@@ -106,7 +105,7 @@
CompletableFuture<Boolean> mFuturePhone;
private PhoneSwitcher mPhoneSwitcher;
- private IOnSubscriptionsChangedListener mSubChangedListener;
+ private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener;
private ConnectivityManager mConnectivityManager;
// The messenger of PhoneSwitcher used to receive network requests.
private Messenger mNetworkFactoryMessenger = null;
@@ -121,8 +120,6 @@
PhoneCapability phoneCapability = new PhoneCapability(1, 1, 0, null, false);
doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability();
- mServiceManagerMockedServices.put("telephony.registry", mTelRegistryMock);
- doReturn(mTelRegistryInterfaceMock).when(mTelRegistryMock).queryLocalInterface(any());
doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
doReturn(Call.State.IDLE).when(mInactiveCall).getState();
@@ -623,7 +620,7 @@
processAllMessages();
verify(mFuturePhone).complete(true);
// Make sure the correct broadcast is sent out for the overridden phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(2));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2));
}
@Test
@@ -662,7 +659,7 @@
setMsimDefaultDataSubId(numPhones, 1);
setAllPhonesInactive();
clearInvocations(mMockRadioConfig);
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
// override the phone ID in prep for emergency call
mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone);
@@ -674,13 +671,13 @@
notifyPhoneAsInCall(mPhone2);
notifyPhoneAsInactive(mPhone2);
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
// Verify that the DDS is successfully switched back after 1 second + base ECBM timeout
moveTimeForward(ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS + 1000);
processAllMessages();
verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
// Make sure the correct broadcast is sent out for the phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(1));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1));
}
@Test
@@ -697,7 +694,7 @@
setMsimDefaultDataSubId(numPhones, 1);
setAllPhonesInactive();
clearInvocations(mMockRadioConfig);
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
// override the phone ID in prep for emergency call
mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone);
@@ -718,10 +715,10 @@
processAllMessages();
verify(mMockRadioConfig, never()).setPreferredDataModem(eq(0), any());
// Make sure the correct broadcast is sent out for the phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(2));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(2));
// End ECBM
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
ecbmMessage = getEcbmRegistration(mPhone2);
notifyEcbmEnd(mPhone2, ecbmMessage);
// Verify that the DDS is successfully switched back after 1 second.
@@ -729,7 +726,7 @@
processAllMessages();
verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
// Make sure the correct broadcast is sent out for the phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(1));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1));
}
@Test
@@ -746,7 +743,7 @@
setMsimDefaultDataSubId(numPhones, 1);
setAllPhonesInactive();
clearInvocations(mMockRadioConfig);
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
// override the phone ID in prep for emergency call
mPhoneSwitcher.overrideDefaultDataForEmergency(1, 1, mFuturePhone);
@@ -759,7 +756,7 @@
processAllMessages();
verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
// Make sure the correct broadcast is sent out for the phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(1));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1));
}
@Test
@@ -776,7 +773,7 @@
setMsimDefaultDataSubId(numPhones, 1);
setAllPhonesInactive();
clearInvocations(mMockRadioConfig);
- clearInvocations(mTelRegistryInterfaceMock);
+ clearInvocations(mTelephonyRegistryManager);
// override the phone ID in prep for emergency call
LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
@@ -808,7 +805,7 @@
processAllMessages();
verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
// Make sure the correct broadcast is sent out for the phone ID
- verify(mTelRegistryInterfaceMock).notifyActiveDataSubIdChanged(eq(1));
+ verify(mTelephonyRegistryManager).notifyActiveDataSubIdChanged(eq(1));
}
@Test
@@ -1016,12 +1013,10 @@
initializeConnManagerMock();
mPhoneSwitcher = new PhoneSwitcher(maxActivePhones, numPhones,
- mContext, mSubscriptionController, Looper.myLooper(),
- mTelRegistryMock, mCommandsInterfaces, mPhones);
+ mContext, mSubscriptionController, Looper.myLooper(), mCommandsInterfaces, mPhones);
processAllMessages();
- verify(mTelRegistryMock).addOnSubscriptionsChangedListener(
- eq(mContext.getOpPackageName()), any());
+ verify(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any());
}
/**
@@ -1081,12 +1076,12 @@
*/
private void initializeTelRegistryMock() throws Exception {
doAnswer(invocation -> {
- IOnSubscriptionsChangedListener subChangedListener =
- (IOnSubscriptionsChangedListener) invocation.getArguments()[1];
+ SubscriptionManager.OnSubscriptionsChangedListener subChangedListener =
+ (SubscriptionManager.OnSubscriptionsChangedListener) invocation.getArguments()[0];
mSubChangedListener = subChangedListener;
mSubChangedListener.onSubscriptionsChanged();
return null;
- }).when(mTelRegistryMock).addOnSubscriptionsChangedListener(any(), any());
+ }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(any(), any());
}
/**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index f70830a..fda30f5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -1866,7 +1866,6 @@
}
@Test
- @FlakyTest
public void testSetupDataCall() throws Exception {
DataProfile dp = new DataProfile.Builder()
.setProfileId(PROFILE_ID)
@@ -1910,7 +1909,9 @@
assertEquals(APN_ENABLED, dpi.enabled);
assertEquals(SUPPORTED_APNT_YPES_BITMAK, dpi.supportedApnTypesBitmap);
assertEquals(ROAMING_PROTOCOL, ApnSetting.getProtocolIntFromString(dpi.protocol));
- assertEquals(BEARER_BITMASK, dpi.bearerBitmap);
+ assertEquals(
+ BEARER_BITMASK,
+ ServiceState.convertBearerBitmaskToNetworkTypeBitmask(dpi.bearerBitmap >> 1));
assertEquals(MTU, dpi.mtu);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionMonitorTest.java
deleted file mode 100644
index 215bb16..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionMonitorTest.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (C) 2006 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;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.Rlog;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.mocks.SubscriptionControllerMock;
-import com.android.internal.telephony.mocks.TelephonyRegistryMock;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class SubscriptionMonitorTest extends AndroidTestCase {
- private final static String LOG_TAG = "SubscriptionMonitorTest";
-
- static void failAndStack(String str) {
- fail(str + "\n" + SubscriptionMonitorTest.stack());
- }
-
- static String stack() {
- StringBuilder sb = new StringBuilder();
- for(StackTraceElement e : Thread.currentThread().getStackTrace()) {
- sb.append(e.toString()).append("\n");
- }
- return sb.toString();
- }
-
- private static class TestHandler extends Handler {
- public final static int SUBSCRIPTION_CHANGED = 1;
- public final static int IN_IDLE = 2;
-
- HandlerThread handlerThread;
-
- public TestHandler(Looper looper) {
- super(looper);
- }
-
- public void die() {
- if(handlerThread != null) {
- handlerThread.quit();
- handlerThread = null;
- }
- }
-
- public void blockTilIdle() {
- Object lock = new Object();
- synchronized (lock) {
- Message msg = this.obtainMessage(IN_IDLE, lock);
- msg.sendToTarget();
- try {
- lock.wait();
- } catch (InterruptedException e) {}
- }
- }
-
- public static TestHandler makeHandler() {
- final HandlerThread handlerThread = new HandlerThread("TestHandler");
- handlerThread.start();
- final TestHandler result = new TestHandler(handlerThread.getLooper());
- result.handlerThread = handlerThread;
- return result;
- }
-
- private boolean objectEquals(Object o1, Object o2) {
- if (o1 == null) return (o2 == null);
- return o1.equals(o2);
- }
-
- private void failAndStack(String str) {
- SubscriptionMonitorTest.failAndStack(str);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SUBSCRIPTION_CHANGED: {
- AsyncResult ar = (AsyncResult)(msg.obj);
- if (objectEquals(ar.userObj, mSubscriptionChangedObject.get()) == false) {
- failAndStack("Subscription Changed object is incorrect!");
- }
- mSubscriptionChangedCount.incrementAndGet();
- Rlog.d(LOG_TAG, "SUBSCRIPTION_CHANGED, inc to " +
- mSubscriptionChangedCount.get());
- break;
- }
- case IN_IDLE: {
- Object lock = msg.obj;
- synchronized (lock) {
- lock.notify();
- }
- break;
- }
- }
- }
-
- private final AtomicInteger mSubscriptionChangedCount = new AtomicInteger(0);
- private final AtomicReference<Object> mSubscriptionChangedObject =
- new AtomicReference<Object>();
-
- public void reset() {
- mSubscriptionChangedCount.set(0);
- mSubscriptionChangedObject.set(null);
- }
-
- public void setSubscriptionChangedObject(Object o) {
- mSubscriptionChangedObject.set(o);
- }
-
- public int getSubscriptionChangedCount() {
- return mSubscriptionChangedCount.get();
- }
- }
-
- /**
- * Register and unregister normally.
- * Verify register worked by causing an event.
- * Verify unregister by causing another event.
- */
- @SmallTest
- public void testRegister() throws Exception {
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- // try events before registering
- subController.setSlotSubId(0, 0);
-
- if (testHandler.getSubscriptionChangedCount() != 0) {
- fail("pretest of SubscriptionChangedCount");
- }
-
- testedSubMonitor.registerForSubscriptionChanged(0, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- testHandler.blockTilIdle();
-
- if (testHandler.getSubscriptionChangedCount() != 1) {
- fail("test1 of SubscriptionChangedCount");
- }
-
- subController.setSlotSubId(0, 1);
- testHandler.blockTilIdle();
-
- if (testHandler.getSubscriptionChangedCount() != 2) {
- fail("test2 of SubscriptionChangedCount");
- }
-
- subController.setSlotSubId(0, 0);
- testHandler.blockTilIdle();
-
- if (testHandler.getSubscriptionChangedCount() != 3) {
- fail("test3 of SubscriptionChangedCount, " +
- testHandler.getSubscriptionChangedCount() + " vs 3");
- }
-
- testedSubMonitor.unregisterForSubscriptionChanged(0, testHandler);
-
- subController.setSlotSubId(0, 1);
- testHandler.blockTilIdle();
-
- if (testHandler.getSubscriptionChangedCount() != 3) {
- fail("test4 of SubscriptionChangedCount, " +
- testHandler.getSubscriptionChangedCount() + " vs 3");
- }
-
- testHandler.die();
- }
-
- /**
- * Bad register/unregisters
- *
- * Try phoneId that doesn't exist.
- * Cause an event and verify don't get notified.
- * Try to unregister multiple times.
- */
- @SmallTest
- public void testBadRegister() throws Exception {
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- try {
- testedSubMonitor.registerForSubscriptionChanged(-1, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- fail("IllegalArgumentException expected with bad phoneId");
- } catch (IllegalArgumentException e) {}
- try {
- testedSubMonitor.registerForSubscriptionChanged(numPhones, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- fail("IllegalArgumentException expected with bad phoneId");
- } catch (IllegalArgumentException e) {}
-
- subController.setSlotSubId(0, 0);
-
- if (testHandler.getSubscriptionChangedCount() != 0) {
- fail("getSubscriptionChangedCount reported non-zero!");
- }
-
- testHandler.die();
- }
-
- /**
- * Try to force spurious notifications - register/unregister in tight loop with
- * events happening in the unregistered gap.
- */
- @SmallTest
- public void testSpuriousNotifications() throws Exception {
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- final int PHONE_ID = 0;
- final int FIRST_SUB_ID = 0;
- final int SECOND_SUB_ID = 1;
-
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- final int LOOP_COUNT = 1000;
- for (int i = 0; i < LOOP_COUNT; i++) {
- testedSubMonitor.unregisterForSubscriptionChanged(PHONE_ID, testHandler);
-
- subController.setSlotSubId(PHONE_ID, FIRST_SUB_ID);
- subController.setSlotSubId(PHONE_ID, SECOND_SUB_ID);
-
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- }
- testHandler.blockTilIdle();
-
- // should get one for every registration
- if (testHandler.getSubscriptionChangedCount() != 1 + LOOP_COUNT) {
- fail("getSubscriptionChangedCount reported " +
- testHandler.getSubscriptionChangedCount() + " != " + (1 + LOOP_COUNT));
- }
-
- testHandler.die();
- }
-
- /**
- * Test duplicate registrations - both should survive
- * Also test duplicate unreg - shouldn't crash..
- */
- @SmallTest
- public void testMultiRegUnregistration() throws Exception {
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- final int PHONE_ID = 0;
- final int FIRST_SUB_ID = 0;
- final int SECOND_SUB_ID = 1;
-
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
-
- subController.setSlotSubId(PHONE_ID, FIRST_SUB_ID);
- subController.setSlotSubId(PHONE_ID, SECOND_SUB_ID);
-
- testHandler.blockTilIdle();
-
- // should get 1 for each registration and 4 for the two events
- if (testHandler.getSubscriptionChangedCount() != 6) {
- fail("getSubscriptionChangedCount reported " +
- testHandler.getSubscriptionChangedCount() + " != 6");
- }
-
- testedSubMonitor.unregisterForSubscriptionChanged(PHONE_ID, testHandler);
- testedSubMonitor.unregisterForSubscriptionChanged(PHONE_ID, testHandler);
-
- testHandler.die();
- }
-
- /**
- * Try event flood while registered - verify receive all.
- */
- @SmallTest
- public void testEventFloodNotifications() throws Exception {
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- final int PHONE_ID = 0;
- final int FIRST_SUB_ID = 0;
- final int SECOND_SUB_ID = 1;
-
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
-
- final int LOOP_COUNT = 1;
- for (int i = 0; i < LOOP_COUNT; i++) {
- subController.setSlotSubId(PHONE_ID, FIRST_SUB_ID);
- subController.setSlotSubId(PHONE_ID, SECOND_SUB_ID);
- }
- testHandler.blockTilIdle();
-
- // should get one for registration + 2 per loop
- if (testHandler.getSubscriptionChangedCount() != 1 + (2 * LOOP_COUNT)) {
- fail("getSubscriptionChangedCount reported " +
- testHandler.getSubscriptionChangedCount() + " != " + (1 + (2 * LOOP_COUNT)));
- }
-
- testHandler.die();
- }
-
- @SmallTest
- public void testNoSubChange() throws Exception {
- String TAG = "testNoSubChange";
- final int numPhones = 2;
- final ContextFixture contextFixture = new ContextFixture();
- final Context context = contextFixture.getTestDouble();
- ITelephonyRegistry.Stub telRegistry = new TelephonyRegistryMock();
- SubscriptionControllerMock subController =
- new SubscriptionControllerMock(context, telRegistry, numPhones);
-
- SubscriptionMonitor testedSubMonitor =
- new SubscriptionMonitor(telRegistry, context, subController, numPhones);
-
- TestHandler testHandler = TestHandler.makeHandler();
- Object subChangedObject = new Object();
- testHandler.setSubscriptionChangedObject(subChangedObject);
-
- final int PHONE_ID = 0;
- final int FIRST_SUB_ID = 0;
- final int SECOND_SUB_ID = 1;
-
- testHandler.blockTilIdle();
- Rlog.d(TAG, "1");
-
- testedSubMonitor.registerForSubscriptionChanged(PHONE_ID, testHandler,
- TestHandler.SUBSCRIPTION_CHANGED, subChangedObject);
-
- testHandler.blockTilIdle();
- Rlog.d(TAG, "2");
-
- subController.setSlotSubId(PHONE_ID, FIRST_SUB_ID);
-
- testHandler.blockTilIdle();
- Rlog.d(TAG, "3");
-
- if (testHandler.getSubscriptionChangedCount() != 2) {
- fail("getSubscriptionChangedCount reported " +
- testHandler.getSubscriptionChangedCount() + " != 2");
- }
-
- Rlog.d(TAG, "4");
-
- // cause a notification that subscription info changed
- subController.notifySubscriptionInfoChanged();
- testHandler.blockTilIdle();
-
- Rlog.d(TAG, "5");
-
- if (testHandler.getSubscriptionChangedCount() != 2) {
- fail("getSubscriptionChangedCount reported " +
- testHandler.getSubscriptionChangedCount() + " != 2");
- }
-
- testHandler.die();
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 1c05743..b6516fa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -49,7 +49,7 @@
import android.os.MessageQueue;
import android.os.RegistrantList;
import android.os.ServiceManager;
-import android.os.telephony.TelephonyRegistryManager;
+import android.telephony.TelephonyRegistryManager;
import android.provider.BlockedNumberContract;
import android.provider.DeviceConfig;
import android.provider.Settings;
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 101c719..f6ef326 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -720,21 +720,14 @@
any(Message.class));
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
- // Verify the retry manger schedule another data call setup.
- verify(mAlarmManager, times(1)).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
- anyLong(), any(PendingIntent.class));
-
// This time we'll let RIL command succeed.
mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
- // Simulate the timer expires.
- Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
- intent.putExtra("reconnect_alarm_extra_type", PhoneConstants.APN_TYPE_DEFAULT);
- intent.putExtra("reconnect_alarm_extra_transport_type",
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, 0);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContext.sendBroadcast(intent);
+ //Send event for reconnecting data
+ initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+ mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
+ mPhone.getPhoneId(), AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ mApnContext));
waitForMs(200);
dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
@@ -1361,14 +1354,11 @@
verify(mAlarmManager, times(1)).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
anyLong(), any(PendingIntent.class));
- // Simulate the timer expires.
- Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
- intent.putExtra("reconnect_alarm_extra_type", PhoneConstants.APN_TYPE_DEFAULT);
- intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, 0);
- intent.putExtra("reconnect_alarm_extra_transport_type",
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- mContext.sendBroadcast(intent);
+ //Send event for reconnecting data
+ initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
+ mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
+ mPhone.getPhoneId(), AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ mApnContext));
waitForMs(200);
// Verify if RIL command was sent properly.
@@ -1597,16 +1587,17 @@
eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
+ waitForMs(200);
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
logd("Sending EVENT_NETWORK_STATUS_CHANGED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.VALID_NETWORK, 0, null));
+ NetworkAgent.VALID_NETWORK, 1, null));
waitForMs(200);
logd("Sending EVENT_NETWORK_STATUS_CHANGED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 0, null));
+ NetworkAgent.INVALID_NETWORK, 1, null));
waitForMs(200);
// Verify that its no-op when the new data stall detection feature is disabled
@@ -1638,16 +1629,17 @@
eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
+ waitForMs(200);
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
logd("Sending EVENT_NETWORK_STATUS_CHANGED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.VALID_NETWORK, 0, null));
+ NetworkAgent.VALID_NETWORK, 1, null));
waitForMs(200);
logd("Sending EVENT_NETWORK_STATUS_CHANGED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 0, null));
+ NetworkAgent.INVALID_NETWORK, 1, null));
waitForMs(200);
verify(mSimulatedCommandsVerifier, times(1)).getDataCallList(any(Message.class));
@@ -1680,11 +1672,12 @@
eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
any(Message.class));
+ waitForMs(200);
verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 0, null));
+ NetworkAgent.INVALID_NETWORK, 1, null));
waitForMs(200);
// expected tear down all DataConnections
@@ -1724,7 +1717,7 @@
logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 0, null));
+ NetworkAgent.INVALID_NETWORK, 1, null));
waitForMs(200);
// expected to get preferred network type
@@ -1761,7 +1754,7 @@
logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 0, null));
+ NetworkAgent.INVALID_NETWORK, 1, null));
waitForMs(200);
// expected to get preferred network type
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
index bb604f4..7512ec3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
@@ -53,7 +53,6 @@
import com.android.internal.telephony.mocks.ConnectivityServiceMock;
import com.android.internal.telephony.mocks.PhoneSwitcherMock;
import com.android.internal.telephony.mocks.SubscriptionControllerMock;
-import com.android.internal.telephony.mocks.SubscriptionMonitorMock;
import com.android.internal.telephony.mocks.TelephonyRegistryMock;
import org.junit.After;
@@ -80,7 +79,6 @@
private TelephonyRegistryMock mTelephonyRegistryMock;
private PhoneSwitcherMock mPhoneSwitcherMock;
private SubscriptionControllerMock mSubscriptionControllerMock;
- private SubscriptionMonitorMock mSubscriptionMonitorMock;
private ConnectivityServiceMock mConnectivityServiceMock;
private final ArrayList<NetworkRequest> mNetworkRequestList = new ArrayList<>();
@@ -157,17 +155,14 @@
mTelephonyRegistryMock = new TelephonyRegistryMock();
mSubscriptionControllerMock = new SubscriptionControllerMock(mContext,
mTelephonyRegistryMock, numberOfPhones);
- mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones);
mPhoneSwitcherMock = new PhoneSwitcherMock(
numberOfPhones, Looper.myLooper(), mSubscriptionControllerMock);
- mSubscriptionMonitorMock = new SubscriptionMonitorMock(numberOfPhones);
replaceInstance(SubscriptionController.class, "sInstance", null,
mSubscriptionControllerMock);
replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mPhoneSwitcherMock);
- mTelephonyNetworkFactoryUT = new TelephonyNetworkFactory(mSubscriptionMonitorMock,
- Looper.myLooper(), mPhone);
+ mTelephonyNetworkFactoryUT = new TelephonyNetworkFactory(Looper.myLooper(), mPhone);
monitorTestableLooper(new TestableLooper(
mConnectivityServiceMock.getHandlerThread().getLooper()));
}
@@ -189,7 +184,9 @@
mPhoneSwitcherMock.setPreferredDataPhoneId(phoneId);
mSubscriptionControllerMock.setDefaultDataSubId(subId);
mSubscriptionControllerMock.setSlotSubId(phoneId, subId);
- mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
+ // fake onSubscriptionChangedListener being triggered.
+ mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+ TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
log("addDefaultRequest");
mConnectivityServiceMock.addDefaultRequest();
@@ -261,7 +258,8 @@
mPhoneSwitcherMock.setPreferredDataPhoneId(phoneId);
mSubscriptionControllerMock.setDefaultDataSubId(subId);
mSubscriptionControllerMock.setSlotSubId(phoneId, subId);
- mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
+ mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+ TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
processAllMessages();
assertEquals(0, mNetworkRequestList.size());
@@ -288,7 +286,8 @@
assertEquals(1, mNetworkRequestList.size());
mSubscriptionControllerMock.setSlotSubId(phoneId, unusedSubId);
- mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
+ mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+ TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
processAllMessages();
assertEquals(0, mNetworkRequestList.size());
@@ -297,7 +296,8 @@
assertEquals(0, mNetworkRequestList.size());
mSubscriptionControllerMock.setSlotSubId(phoneId, subId);
- mSubscriptionMonitorMock.notifySubscriptionChanged(phoneId);
+ mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+ TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
processAllMessages();
mSubscriptionControllerMock.setDefaultDataSubId(subId);
@@ -317,7 +317,8 @@
mPhoneSwitcherMock.setPreferredDataPhoneId(0);
mSubscriptionControllerMock.setDefaultDataSubId(0);
mSubscriptionControllerMock.setSlotSubId(0, 0);
- mSubscriptionMonitorMock.notifySubscriptionChanged(0);
+ mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+ TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
mPhoneSwitcherMock.setPhoneActive(0, true);
mConnectivityServiceMock.addDefaultRequest();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
index 30baabb..b297ab0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
@@ -925,11 +925,9 @@
}
private void setupResolver(int numSlots) {
- // all tests call setupResolver before running
when(mMockContext.getPackageManager()).thenReturn(mMockPM);
when(mMockContext.getSystemService(eq(Context.CARRIER_CONFIG_SERVICE))).thenReturn(
mMockCarrierConfigManager);
- when(mMockContext.getPackageManager()).thenReturn(mMockPM);
mCarrierConfigs = new PersistableBundle[numSlots];
for (int i = 0; i < numSlots; i++) {
mCarrierConfigs[i] = new PersistableBundle();
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 0cdc34c..0db3204 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -63,9 +64,11 @@
import androidx.test.filters.FlakyTest;
+import com.android.ims.FeatureConnector;
import com.android.ims.ImsEcbmStateListener;
import com.android.ims.ImsManager;
import com.android.ims.ImsUtInterface;
+import com.android.ims.RcsFeatureManager;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandsInterface;
@@ -832,6 +835,19 @@
assertNotNull(mImsPhoneUT.getServiceStateTracker());
}
+ @Test
+ @SmallTest
+ public void testRcsFeatureManagerInitialization() throws Exception {
+ FeatureConnector<RcsFeatureManager> mockRcsManagerConnector =
+ (FeatureConnector<RcsFeatureManager>) mock(FeatureConnector.class);
+ mImsPhoneUT.mRcsManagerConnector = mockRcsManagerConnector;
+
+ mImsPhoneUT.initRcsFeatureManager();
+
+ verify(mockRcsManagerConnector).disconnect();
+ assertNotNull(mImsPhoneUT.mRcsManagerConnector);
+ }
+
private ServiceState getServiceStateDataAndVoice(int rat, int regState, boolean isRoaming) {
ServiceState ss = new ServiceState();
ss.setStateOutOfService();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionMonitorMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionMonitorMock.java
deleted file mode 100644
index 7579359..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/SubscriptionMonitorMock.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2006 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.mocks;
-
-import android.os.Handler;
-import android.os.Registrant;
-import android.os.RegistrantList;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.SubscriptionMonitor;
-
-public class SubscriptionMonitorMock extends SubscriptionMonitor {
- private final int mNumPhones;
- private final RegistrantList mSubscriptionsChangedRegistrants[];
-
- public SubscriptionMonitorMock(int numPhones) {
- super();
- mNumPhones = numPhones;
- mSubscriptionsChangedRegistrants = new RegistrantList[numPhones];
-
- for (int i = 0; i < numPhones; i++) {
- mSubscriptionsChangedRegistrants[i] = new RegistrantList();
- }
- }
-
- @Override
- public void registerForSubscriptionChanged(int phoneId, Handler h, int what, Object o) {
- validatePhoneId(phoneId);
- Registrant r = new Registrant(h, what, o);
- mSubscriptionsChangedRegistrants[phoneId].add(r);
- r.notifyRegistrant();
- }
-
- @Override
- public void unregisterForSubscriptionChanged(int phoneId, Handler h) {
- validatePhoneId(phoneId);
- mSubscriptionsChangedRegistrants[phoneId].remove(h);
- }
-
- @VisibleForTesting
- public void notifySubscriptionChanged(int phoneId) {
- validatePhoneId(phoneId);
- mSubscriptionsChangedRegistrants[phoneId].notifyRegistrants();
- }
-
- private void validatePhoneId(int phoneId) {
- if (phoneId < 0 || phoneId >= mNumPhones) {
- throw new IllegalArgumentException("Invalid PhoneId");
- }
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NewNitzStateMachineImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NewNitzStateMachineImplTest.java
index 01efb40..9de2186 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NewNitzStateMachineImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NewNitzStateMachineImplTest.java
@@ -322,8 +322,8 @@
// Simulate airplane mode being turned off.
script.toggleAirplaneMode(false);
- // Verify the time zone suggestion was withdrawn.
- script.verifyOnlyTimeZoneWasSuggestedAndReset(EMPTY_TIME_ZONE_SUGGESTION);
+ // Verify nothing was suggested: The last suggestion was empty so nothing has changed.
+ script.verifyNothingWasSuggested();
// Check the state that NitzStateMachine must expose.
assertNull(mNitzStateMachineImpl.getCachedNitzData());