Merge "Mms: Add the retrieve conf type support in MMS PDU composer."
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index b9243f7..215d14e 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -1199,6 +1199,9 @@
// Notification about received SMS
SMS_RECEIVED = 8;
+
+ // CB message received
+ CB_SMS_RECEIVED = 9;
}
// Formats used to encode SMS messages
@@ -1224,6 +1227,51 @@
SMS_IMS = 3;
}
+ message CBMessage {
+ // CB message format
+ optional Format msgFormat = 1;
+
+ // CB message priority
+ optional CBPriority msgPriority = 2;
+
+ // Type of CB msg
+ optional CBMessageType msgType = 3;
+
+ // Service category of CB message
+ optional int32 serviceCategory = 4;
+ }
+
+ enum CBMessageType {
+ // Unknown type
+ TYPE_UNKNOWN = 0;
+
+ // ETWS CB msg
+ ETWS = 1;
+
+ // CMAS CB msg
+ CMAS = 2;
+
+ // CB msg other than ETWS and CMAS
+ OTHER = 3;
+ }
+
+ enum CBPriority {
+ // Unknown priority
+ PRIORITY_UNKNOWN = 0;
+
+ // NORMAL priority
+ NORMAL = 1;
+
+ // Interactive priority
+ INTERACTIVE = 2;
+
+ // Urgent priority
+ URGENT = 3;
+
+ // Emergency priority
+ EMERGENCY = 4;
+ }
+
// Event type
optional Type type = 1;
@@ -1261,6 +1309,9 @@
// Numeric ID
optional int32 ril_request_id = 12;
+
+ // Cellbroadcast message content
+ optional CBMessage cell_broadcast_message = 13;
}
// Time when session has started, in minutes since epoch,
diff --git a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
index 5b53bcf..1513a33 100644
--- a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
+++ b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
@@ -522,6 +522,7 @@
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mURL));
request.setAllowedOverMetered(false);
request.setVisibleInDownloadsUi(false);
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
Long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request);
SharedPreferences.Editor editor = getDefaultSharedPreferences(mContext).edit();
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
index 59fdd0f..2e9170d 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
@@ -30,6 +31,8 @@
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.NotificationChannelController;
@@ -38,6 +41,7 @@
import java.util.Map;
+
/**
* This contains Carrier specific logic based on the states/events
* managed in ServiceStateTracker.
@@ -53,18 +57,70 @@
private static final int UNINITIALIZED_DELAY_VALUE = -1;
private Phone mPhone;
private ServiceStateTracker mSST;
-
+ private final Map<Integer, NotificationType> mNotificationTypeMap = new HashMap<>();
+ private int mPreviousSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
public static final int NOTIFICATION_PREF_NETWORK = 1000;
public static final int NOTIFICATION_EMERGENCY_NETWORK = 1001;
- private final Map<Integer, NotificationType> mNotificationTypeMap = new HashMap<>();
-
public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
this.mPhone = phone;
this.mSST = sst;
phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ // Listen for subscriber changes
+ SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
+ new OnSubscriptionsChangedListener(this.getLooper()) {
+ @Override
+ public void onSubscriptionsChanged() {
+ int subId = mPhone.getSubId();
+ if (mPreviousSubId != subId) {
+ mPreviousSubId = subId;
+ registerPrefNetworkModeObserver();
+ }
+ }
+ });
+
registerNotificationTypes();
+ registerPrefNetworkModeObserver();
+ }
+
+ private ContentObserver mPrefNetworkModeObserver = new ContentObserver(this) {
+ @Override
+ public void onChange(boolean selfChange) {
+ handlePrefNetworkModeChanged();
+ }
+ };
+
+ /**
+ * Return preferred network mode observer
+ */
+ @VisibleForTesting
+ public ContentObserver getContentObserver() {
+ return mPrefNetworkModeObserver;
+ }
+
+ private void registerPrefNetworkModeObserver() {
+ int subId = mPhone.getSubId();
+ unregisterPrefNetworkModeObserver();
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
+ mPhone.getContext().getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.PREFERRED_NETWORK_MODE + subId),
+ true,
+ mPrefNetworkModeObserver);
+ }
+ }
+
+ private void unregisterPrefNetworkModeObserver() {
+ mPhone.getContext().getContentResolver().unregisterContentObserver(
+ mPrefNetworkModeObserver);
+ }
+
+ /**
+ * Returns mNotificationTypeMap
+ */
+ @VisibleForTesting
+ public Map<Integer, NotificationType> getNotificationTypeMap() {
+ return mNotificationTypeMap;
}
private void registerNotificationTypes() {
@@ -152,14 +208,25 @@
private void handleConfigChanges() {
for (Map.Entry<Integer, NotificationType> entry : mNotificationTypeMap.entrySet()) {
NotificationType notificationType = entry.getValue();
- if (evaluateSendingMessage(notificationType)) {
- Message notificationMsg = obtainMessage(notificationType.getTypeId(), null);
- Rlog.i(LOG_TAG, "starting timer for notifications." + notificationType.getTypeId());
- sendMessageDelayed(notificationMsg, getDelay(notificationType));
- } else {
- cancelNotification(notificationType.getTypeId());
- Rlog.i(LOG_TAG, "canceling notifications: " + notificationType.getTypeId());
- }
+ evaluateSendingMessageOrCancelNotification(notificationType);
+ }
+ }
+
+ private void handlePrefNetworkModeChanged() {
+ NotificationType notificationType = mNotificationTypeMap.get(NOTIFICATION_PREF_NETWORK);
+ if (notificationType != null) {
+ evaluateSendingMessageOrCancelNotification(notificationType);
+ }
+ }
+
+ private void evaluateSendingMessageOrCancelNotification(NotificationType notificationType) {
+ if (evaluateSendingMessage(notificationType)) {
+ Message notificationMsg = obtainMessage(notificationType.getTypeId(), null);
+ Rlog.i(LOG_TAG, "starting timer for notifications." + notificationType.getTypeId());
+ sendMessageDelayed(notificationMsg, getDelay(notificationType));
+ } else {
+ cancelNotification(notificationType.getTypeId());
+ Rlog.i(LOG_TAG, "canceling notifications: " + notificationType.getTypeId());
}
}
@@ -240,6 +307,13 @@
}
/**
+ * Dispose the CarrierServiceStateTracker.
+ */
+ public void dispose() {
+ unregisterPrefNetworkModeObserver();
+ }
+
+ /**
* Class that defines the different types of notifications.
*/
public interface NotificationType {
@@ -293,7 +367,7 @@
}
this.mDelay = bundle.getInt(
CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
- Rlog.i(LOG_TAG, "reading time to delay notification emergency: " + mDelay);
+ Rlog.i(LOG_TAG, "reading time to delay notification pref network: " + mDelay);
}
public int getDelay() {
@@ -311,7 +385,7 @@
Rlog.i(LOG_TAG, "PrefNetworkNotification: sendMessage() w/values: "
+ "," + isPhoneStillRegistered() + "," + mDelay + "," + isGlobalMode()
+ "," + mSST.isRadioOn());
- if (mDelay == UNINITIALIZED_DELAY_VALUE || isPhoneStillRegistered() || isGlobalMode()
+ if (mDelay == UNINITIALIZED_DELAY_VALUE || isPhoneStillRegistered() || isGlobalMode()
|| isRadioOffOrAirplaneMode()) {
return false;
}
diff --git a/src/java/com/android/internal/telephony/CellBroadcastHandler.java b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
index 4227148..8fc4642 100644
--- a/src/java/com/android/internal/telephony/CellBroadcastHandler.java
+++ b/src/java/com/android/internal/telephony/CellBroadcastHandler.java
@@ -30,6 +30,12 @@
import android.provider.Telephony;
import android.telephony.SmsCbMessage;
import android.telephony.SubscriptionManager;
+import android.util.LocalLog;
+
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
/**
* Dispatch new Cell Broadcasts to receivers. Acquires a private wakelock until the broadcast
@@ -37,6 +43,8 @@
*/
public class CellBroadcastHandler extends WakeLockStateMachine {
+ private final LocalLog mLocalLog = new LocalLog(100);
+
private CellBroadcastHandler(Context context, Phone phone) {
this("CellBroadcastHandler", context, phone);
}
@@ -82,9 +90,18 @@
String receiverPermission;
int appOp;
+ // Log Cellbroadcast msg received event
+ TelephonyMetrics metrics = TelephonyMetrics.getInstance();
+ metrics.writeNewCBSms(mPhone.getPhoneId(), message.getMessageFormat(),
+ message.getMessagePriority(), message.isCmasMessage(), message.isEtwsMessage(),
+ message.getServiceCategory());
+
+ String msg;
Intent intent;
if (message.isEmergencyMessage()) {
- log("Dispatching emergency SMS CB, SmsCbMessage is: " + message);
+ msg = "Dispatching emergency SMS CB, SmsCbMessage is: " + message;
+ log(msg);
+ mLocalLog.log(msg);
intent = new Intent(Telephony.Sms.Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
// Explicitly send the intent to the default cell broadcast receiver.
intent.setPackage(mContext.getResources().getString(
@@ -92,7 +109,9 @@
receiverPermission = Manifest.permission.RECEIVE_EMERGENCY_BROADCAST;
appOp = AppOpsManager.OP_RECEIVE_EMERGECY_SMS;
} else {
- log("Dispatching SMS CB, SmsCbMessage is: " + message);
+ msg = "Dispatching SMS CB, SmsCbMessage is: " + message;
+ log(msg);
+ mLocalLog.log(msg);
intent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION);
// Send implicit intent since there are various 3rd party carrier apps listen to
// this intent.
@@ -121,4 +140,11 @@
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, receiverPermission, appOp,
mReceiver, getHandler(), Activity.RESULT_OK, null, null);
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("CellBroadcastHandler:");
+ mLocalLog.dump(fd, pw, args);
+ pw.flush();
+ }
}
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index e5b0ae0..8b840de 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -228,7 +228,7 @@
CellIdentity cellIdentity =
convertHalCellIdentityToCellIdentity(voiceRegState.cellIdentity);
- return new NetworkRegistrationState(transportType, domain, regState,
+ return new NetworkRegistrationState(domain, transportType, regState,
accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
cellIdentity, cssSupported, roamingIndicator, systemIsInPrl,
defaultRoamingIndicator);
@@ -248,7 +248,7 @@
CellIdentity cellIdentity =
convertHalCellIdentityToCellIdentity(voiceRegState.cellIdentity);
- return new NetworkRegistrationState(transportType, domain, regState,
+ return new NetworkRegistrationState(domain, transportType, regState,
accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
cellIdentity, cssSupported, roamingIndicator, systemIsInPrl,
defaultRoamingIndicator);
@@ -258,8 +258,8 @@
}
private NetworkRegistrationState createRegistrationStateFromDataRegState(Object result) {
- int transportType = TransportType.WWAN;
int domain = NetworkRegistrationState.DOMAIN_PS;
+ int transportType = TransportType.WWAN;
if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) {
android.hardware.radio.V1_0.DataRegStateResult dataRegState =
@@ -273,7 +273,7 @@
CellIdentity cellIdentity =
convertHalCellIdentityToCellIdentity(dataRegState.cellIdentity);
- return new NetworkRegistrationState(transportType, domain, regState,
+ return new NetworkRegistrationState(domain, transportType, regState,
accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
cellIdentity, maxDataCalls);
} else if (result instanceof android.hardware.radio.V1_2.DataRegStateResult) {
@@ -288,7 +288,7 @@
CellIdentity cellIdentity =
convertHalCellIdentityToCellIdentity(dataRegState.cellIdentity);
- return new NetworkRegistrationState(transportType, domain, regState,
+ return new NetworkRegistrationState(domain, transportType, regState,
accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
cellIdentity, maxDataCalls);
}
@@ -330,7 +330,8 @@
cellIdentity.cellIdentityTdscdma.get(0);
result = new CellIdentityTdscdma(cellIdentityTdscdma.mcc,
cellIdentityTdscdma.mnc, cellIdentityTdscdma.lac,
- cellIdentityTdscdma.cid, cellIdentityTdscdma.cpid);
+ cellIdentityTdscdma.cid, cellIdentityTdscdma.cpid,
+ Integer.MAX_VALUE, null, null);
}
break;
}
@@ -417,6 +418,7 @@
cellIdentityTdscdma.base.lac,
cellIdentityTdscdma.base.cid,
cellIdentityTdscdma.base.cpid,
+ cellIdentityTdscdma.uarfcn,
cellIdentityTdscdma.operatorNames.alphaLong,
cellIdentityTdscdma.operatorNames.alphaShort);
}
diff --git a/src/java/com/android/internal/telephony/ExponentialBackoff.java b/src/java/com/android/internal/telephony/ExponentialBackoff.java
deleted file mode 100644
index 80958c0..0000000
--- a/src/java/com/android/internal/telephony/ExponentialBackoff.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.Looper;
-
-/** The implementation of exponential backoff with jitter applied. */
-public class ExponentialBackoff {
- private int mRetryCounter;
- private long mStartDelayMs;
- private long mMaximumDelayMs;
- private long mCurrentDelayMs;
- private int mMultiplier;
- private Runnable mRunnable;
- private Handler mHandler;
-
- public ExponentialBackoff(
- long initialDelayMs,
- long maximumDelayMs,
- int multiplier,
- @NonNull Looper looper,
- @NonNull Runnable runnable) {
- this(initialDelayMs, maximumDelayMs, multiplier, new Handler(looper), runnable);
- }
-
- public ExponentialBackoff(
- long initialDelayMs,
- long maximumDelayMs,
- int multiplier,
- @NonNull Handler handler,
- @NonNull Runnable runnable) {
- mRetryCounter = 0;
- mStartDelayMs = initialDelayMs;
- mMaximumDelayMs = maximumDelayMs;
- mMultiplier = multiplier;
- mHandler = handler;
- mRunnable = runnable;
- }
-
- /** Starts the backoff, the runnable will be executed after {@link #mStartDelayMs}. */
- public void start() {
- mRetryCounter = 0;
- mCurrentDelayMs = mStartDelayMs;
- mHandler.removeCallbacks(mRunnable);
- mHandler.postDelayed(mRunnable, mCurrentDelayMs);
- }
-
- /** Stops the backoff, all pending messages will be removed from the message queue. */
- public void stop() {
- mRetryCounter = 0;
- mHandler.removeCallbacks(mRunnable);
- }
-
- /** Should call when the retry action has failed and we want to retry after a longer delay. */
- public void notifyFailed() {
- mRetryCounter++;
- long temp = Math.min(
- mMaximumDelayMs, (long) (mStartDelayMs * Math.pow(mMultiplier, mRetryCounter)));
- mCurrentDelayMs = (long) (((1 + Math.random()) / 2) * temp);
- mHandler.removeCallbacks(mRunnable);
- mHandler.postDelayed(mRunnable, mCurrentDelayMs);
- }
-
- /** Returns the delay for the most recently posted message. */
- public long getCurrentDelay() {
- return mCurrentDelayMs;
- }
-}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 4c3bb6a..5dd36ad 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -1114,7 +1114,8 @@
// Check non-emergency voice CS call - shouldn't dial when POWER_OFF
if (mSST != null && mSST.mSS.getState() == ServiceState.STATE_POWER_OFF /* CS POWER_OFF */
&& !VideoProfile.isVideo(dialArgs.videoState) /* voice call */
- && !isEmergency /* non-emergency call */) {
+ && !isEmergency /* non-emergency call */
+ && !(isUt && useImsForUt) /* not UT */) {
throw new CallStateException(
CallStateException.ERROR_POWER_OFF,
"cannot dial voice call in airplane mode");
@@ -1669,7 +1670,13 @@
Message resp;
mVmNumber = voiceMailNumber;
resp = obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
+
IccRecords r = mIccRecords.get();
+
+ if (!isPhoneTypeGsm() && mSimRecords != null) {
+ r = mSimRecords;
+ }
+
if (r != null) {
r.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index f2383f5..d7a45d8 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -40,6 +40,7 @@
import android.telephony.Rlog;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
+import android.util.LocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -50,6 +51,8 @@
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.util.HexDump;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -86,6 +89,8 @@
final private UserManager mUserManager;
protected SmsDispatchersController mDispatchersController;
+ private final LocalLog mCellBroadcastLocalLog = new LocalLog(100);
+
protected Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -788,7 +793,7 @@
} else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA) {
return enableCdmaBroadcastRange(startMessageId, endMessageId);
} else {
- throw new IllegalArgumentException("Not a supportted RAN Type");
+ throw new IllegalArgumentException("Not a supported RAN Type");
}
}
@@ -798,7 +803,7 @@
} else if (ranType == SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA) {
return disableCdmaBroadcastRange(startMessageId, endMessageId);
} else {
- throw new IllegalArgumentException("Not a supportted RAN Type");
+ throw new IllegalArgumentException("Not a supported RAN Type");
}
}
@@ -811,15 +816,21 @@
String client = mContext.getPackageManager().getNameForUid(
Binder.getCallingUid());
+ String msg;
if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
- log("Failed to add GSM cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ msg = "Failed to add GSM cell broadcast channels range " + startMessageId
+ + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
return false;
}
- if (DBG)
- log("Added GSM cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ if (DBG) {
+ msg = "Added GSM cell broadcast channels range " + startMessageId
+ + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
+ }
setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
@@ -835,15 +846,21 @@
String client = mContext.getPackageManager().getNameForUid(
Binder.getCallingUid());
+ String msg;
if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
- log("Failed to remove GSM cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ msg = "Failed to remove GSM cell broadcast channels range " + startMessageId
+ + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
return false;
}
- if (DBG)
- log("Removed GSM cell broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ if (DBG) {
+ msg = "Removed GSM cell broadcast channels range " + startMessageId
+ + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
+ }
setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
@@ -859,15 +876,20 @@
String client = mContext.getPackageManager().getNameForUid(
Binder.getCallingUid());
+ String msg;
if (!mCdmaBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
- log("Failed to add cdma broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ msg = "Failed to add cdma broadcast channels range " + startMessageId + " to "
+ + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
return false;
}
- if (DBG)
- log("Added cdma broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ if (DBG) {
+ msg = "Added cdma broadcast channels range " + startMessageId + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
+ }
setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty());
@@ -883,15 +905,20 @@
String client = mContext.getPackageManager().getNameForUid(
Binder.getCallingUid());
+ String msg;
if (!mCdmaBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
- log("Failed to remove cdma broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ msg = "Failed to remove cdma broadcast channels range " + startMessageId + " to "
+ + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
return false;
}
- if (DBG)
- log("Removed cdma broadcast subscription for MID range " + startMessageId
- + " to " + endMessageId + " from client " + client);
+ if (DBG) {
+ msg = "Removed cdma broadcast channels range " + startMessageId + " to " + endMessageId;
+ log(msg);
+ mCellBroadcastLocalLog.log(msg);
+ }
setCdmaBroadcastActivation(!mCdmaBroadcastRangeManager.isEmpty());
@@ -1335,4 +1362,11 @@
return result != null ? result : destAddr;
}
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("CellBroadcast log:");
+ mCellBroadcastLocalLog.dump(fd, pw, args);
+ pw.println("SMS dispatcher controller log:");
+ mDispatchersController.dump(fd, pw, args);
+ pw.flush();
+ }
}
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index 184798e..5bc62d5 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -16,8 +16,11 @@
package com.android.internal.telephony;
+import android.content.Context;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.provider.Telephony.Sms.Intents;
+import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.aidl.IImsSmsListener;
@@ -26,6 +29,8 @@
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.ImsSmsImplBase;
import android.telephony.ims.stub.ImsSmsImplBase.SendStatusResult;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
import android.util.Pair;
import com.android.ims.ImsException;
@@ -228,6 +233,50 @@
getImsManager().onSmsReady();
}
+ private boolean isLteService() {
+ return ((mPhone.getServiceState().getRilVoiceRadioTechnology() ==
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE) && (mPhone.getServiceState().
+ getState() == ServiceState.STATE_IN_SERVICE));
+ }
+
+ private boolean isLimitedLteService() {
+ return ((mPhone.getServiceState().getRilVoiceRadioTechnology() ==
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE) && mPhone.getServiceState().isEmergencyOnly());
+ }
+
+ private boolean isEmergencySmsPossible() {
+ return isLteService() || isLimitedLteService();
+ }
+
+ public boolean isEmergencySmsSupport(String destAddr) {
+ PersistableBundle b;
+ boolean eSmsCarrierSupport = false;
+ if (!PhoneNumberUtils.isLocalEmergencyNumber(mContext, mPhone.getSubId(), destAddr)) {
+ Rlog.e(TAG, "Emergency Sms is not supported for: " + destAddr);
+ return false;
+ }
+ CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager == null) {
+ Rlog.e(TAG, "configManager is null");
+ return false;
+ }
+ b = configManager.getConfigForSubId(getSubId());
+ if (b == null) {
+ Rlog.e(TAG, "PersistableBundle is null");
+ return false;
+ }
+ eSmsCarrierSupport = b.getBoolean(CarrierConfigManager.
+ KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL);
+ boolean lteOrLimitedLte = isEmergencySmsPossible();
+ Rlog.i(TAG, "isEmergencySmsSupport emergencySmsCarrierSupport: "
+ + eSmsCarrierSupport + " destAddr: " + destAddr + " mIsImsServiceUp: "
+ + mIsImsServiceUp + " lteOrLimitedLte: " + lteOrLimitedLte);
+
+ return eSmsCarrierSupport && mIsImsServiceUp && lteOrLimitedLte;
+ }
+
+
public boolean isAvailable() {
synchronized (mLock) {
Rlog.d(TAG, "isAvailable: up=" + mIsImsServiceUp + ", reg= " + mIsRegistered
@@ -247,8 +296,10 @@
}
@Override
- protected boolean shouldBlockSms() {
- return SMSDispatcherUtil.shouldBlockSms(isCdmaMo(), mPhone);
+ protected boolean shouldBlockSmsForEcbm() {
+ // We should not block outgoing SMS during ECM on IMS. It only applies to outgoing CDMA
+ // SMS.
+ return false;
}
@Override
@@ -278,6 +329,10 @@
+ " mMessageRef=" + tracker.mMessageRef
+ " SS=" + mPhone.getServiceState().getState());
+ // Flag that this Tracker is using the ImsService implementation of SMS over IMS for sending
+ // this message. Any fallbacks will happen over CS only.
+ tracker.mUsesImsServiceForIms = true;
+
HashMap<String, Object> map = tracker.getData();
byte[] pdu = (byte[]) map.get(MAP_KEY_PDU);
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 53072c7..b51498e 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -60,6 +60,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.LocalLog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -69,6 +70,8 @@
import com.android.internal.util.StateMachine;
import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -157,6 +160,9 @@
/** New SMS received as an AsyncResult. */
public static final int EVENT_INJECT_SMS = 8;
+ /** Update the sms tracker */
+ public static final int EVENT_UPDATE_TRACKER = 9;
+
/** Wakelock release delay when returning to idle state. */
private static final int WAKELOCK_TIMEOUT = 3000;
@@ -205,6 +211,8 @@
private UserManager mUserManager;
+ private LocalLog mLocalLog = new LocalLog(64);
+
IDeviceIdleController mDeviceIdleController;
// Delete permanently from raw table
@@ -449,6 +457,7 @@
// if any broadcasts were sent, transition to waiting state
InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj;
if (processMessagePart(inboundSmsTracker)) {
+ sendMessage(obtainMessage(EVENT_UPDATE_TRACKER, msg.obj));
transitionTo(mWaitingState);
} else {
// if event is sent from SmsBroadcastUndelivered.broadcastSms(), and
@@ -474,10 +483,17 @@
}
return HANDLED;
+ case EVENT_UPDATE_TRACKER:
+ logd("process tracker message in DeliveringState " + msg.arg1);
+ return HANDLED;
+
// we shouldn't get this message type in this state, log error and halt.
case EVENT_BROADCAST_COMPLETE:
case EVENT_START_ACCEPTING_SMS:
default:
+ String errorMsg = "Unhandled msg in delivering state, msg.what = " + msg.what;
+ loge(errorMsg);
+ mLocalLog.log(errorMsg);
// let DefaultState handle these unexpected message types
return NOT_HANDLED;
}
@@ -493,6 +509,8 @@
*/
private class WaitingState extends State {
+ private InboundSmsTracker mLastDeliveredSmsTracker;
+
@Override
public void enter() {
if (DBG) log("entering Waiting state");
@@ -512,10 +530,20 @@
switch (msg.what) {
case EVENT_BROADCAST_SMS:
// defer until the current broadcast completes
+ if (mLastDeliveredSmsTracker != null) {
+ String str = "Defer sms broadcast due to undelivered sms, "
+ + " messageCount = " + mLastDeliveredSmsTracker.getMessageCount()
+ + " destPort = " + mLastDeliveredSmsTracker.getDestPort()
+ + " timestamp = " + mLastDeliveredSmsTracker.getTimestamp()
+ + " currentTimestamp = " + System.currentTimeMillis();
+ logd(str);
+ mLocalLog.log(str);
+ }
deferMessage(msg);
return HANDLED;
case EVENT_BROADCAST_COMPLETE:
+ mLastDeliveredSmsTracker = null;
// return to idle after handling all deferred messages
sendMessage(EVENT_RETURN_TO_IDLE);
transitionTo(mDeliveringState);
@@ -525,6 +553,13 @@
// not ready to return to idle; ignore
return HANDLED;
+ case EVENT_UPDATE_TRACKER:
+ for (int i = 1; i < 10; i++) {
+ deferMessage(obtainMessage(EVENT_UPDATE_TRACKER, i, i, msg.obj));
+ }
+ mLastDeliveredSmsTracker = (InboundSmsTracker) msg.obj;
+ return HANDLED;
+
default:
// parent state handles the other message types
return NOT_HANDLED;
@@ -835,8 +870,10 @@
// Do not process null pdu(s). Check for that and return false in that case.
List<byte[]> pduList = Arrays.asList(pdus);
if (pduList.size() == 0 || pduList.contains(null)) {
- loge("processMessagePart: returning false due to " +
- (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)"));
+ String errorMsg = "processMessagePart: returning false due to "
+ + (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)");
+ loge(errorMsg);
+ mLocalLog.log(errorMsg);
return false;
}
@@ -1529,6 +1566,15 @@
}
}
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ super.dump(fd, pw, args);
+ if (mCellBroadcastHandler != null) {
+ mCellBroadcastHandler.dump(fd, pw, args);
+ }
+ mLocalLog.dump(fd, pw, args);
+ }
+
// Some providers send formfeeds in their messages. Convert those formfeeds to newlines.
private static String replaceFormFeeds(String s) {
return s == null ? "" : s.replace('\f', '\n');
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index 96ffe0f..8977b03 100644
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -16,7 +16,7 @@
package com.android.internal.telephony;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
import android.annotation.NonNull;
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
+import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -34,6 +35,7 @@
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.Rlog;
+import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.LocalLog;
@@ -54,19 +56,26 @@
private static final boolean DBG = true;
private static final String TAG = LocaleTracker.class.getSimpleName();
- /** Event to trigger get cell info from the modem */
+ /** Event for getting cell info from the modem */
private static final int EVENT_GET_CELL_INFO = 1;
- /** Event to trigger update operator numeric */
+ /** Event for operator numeric update */
private static final int EVENT_UPDATE_OPERATOR_NUMERIC = 2;
+ /** Event for service state changed */
+ private static final int EVENT_SERVICE_STATE_CHANGED = 3;
+
// Todo: Read this from Settings.
/** The minimum delay to get cell info from the modem */
private static final long CELL_INFO_MIN_DELAY_MS = 2 * SECOND_IN_MILLIS;
// Todo: Read this from Settings.
/** The maximum delay to get cell info from the modem */
- private static final long CELL_INFO_MAX_DELAY_MS = 1 * HOUR_IN_MILLIS;
+ private static final long CELL_INFO_MAX_DELAY_MS = 10 * MINUTE_IN_MILLIS;
+
+ // Todo: Read this from Settings.
+ /** The delay for periodically getting cell info from the modem */
+ private static final long CELL_INFO_PERIODIC_POLLING_DELAY_MS = 10 * MINUTE_IN_MILLIS;
private final Phone mPhone;
@@ -88,6 +97,9 @@
@Nullable
private String mCurrentCountryIso;
+ /** Current service state. Must be one of ServiceState.STATE_XXX. */
+ private int mLastServiceState = -1;
+
private final LocalLog mLocalLog = new LocalLog(50);
/** Broadcast receiver to get SIM card state changed event */
@@ -121,6 +133,10 @@
case EVENT_UPDATE_OPERATOR_NUMERIC:
updateOperatorNumericSync((String) msg.obj);
break;
+ case EVENT_SERVICE_STATE_CHANGED:
+ AsyncResult ar = (AsyncResult) msg.obj;
+ onServiceStateChanged((ServiceState) ar.result);
+ break;
default:
throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what);
}
@@ -140,6 +156,8 @@
final IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
mPhone.getContext().registerReceiver(mBroadcastReceiver, filter);
+
+ mPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
}
/**
@@ -207,6 +225,32 @@
}
/**
+ * Called when service state changed.
+ *
+ * @param serviceState Service state
+ */
+ private void onServiceStateChanged(ServiceState serviceState) {
+ int state = serviceState.getState();
+ if (state != mLastServiceState) {
+ if (state != ServiceState.STATE_POWER_OFF && TextUtils.isEmpty(mOperatorNumeric)) {
+ // When the device is out of airplane mode or powered on, and network's MCC/MNC is
+ // not available, we get cell info from the modem.
+ String msg = "Service state " + ServiceState.rilServiceStateToString(state)
+ + ". Get cell info now.";
+ if (DBG) log(msg);
+ mLocalLog.log(msg);
+ getCellInfo();
+ } else if (state == ServiceState.STATE_POWER_OFF) {
+ // Clear the cell info when the device is in airplane mode.
+ if (mCellInfo != null) mCellInfo.clear();
+ stopCellInfoRetry();
+ }
+ updateLocale();
+ mLastServiceState = state;
+ }
+ }
+
+ /**
* Update MCC/MNC from network service state synchronously. Note if this is called from phone
* process's main thread and if the update operation requires getting cell info from the modem,
* the cached cell info will be used to determine the locale. If the cached cell info is not
@@ -216,13 +260,11 @@
*/
public synchronized void updateOperatorNumericSync(String operatorNumeric) {
// Check if the operator numeric changes.
- String msg = "updateOperatorNumeric. mcc/mnc=" + operatorNumeric;
- if (DBG) log(msg);
- mLocalLog.log(msg);
+ if (DBG) log("updateOperatorNumericSync. mcc/mnc=" + operatorNumeric);
if (!Objects.equals(mOperatorNumeric, operatorNumeric)) {
- if (DBG) {
- log("onUpdateOperatorNumeric: operator numeric changes to " + operatorNumeric);
- }
+ String msg = "Operator numeric changes to " + operatorNumeric;
+ if (DBG) log(msg);
+ mLocalLog.log(msg);
mOperatorNumeric = operatorNumeric;
// If the operator numeric becomes unavailable, we need to get the latest cell info so
@@ -233,9 +275,10 @@
}
getCellInfo();
} else {
- // If operator numeric is available, that means we camp on network. So reset the
- // fail cell info count.
- mFailCellInfoCount = 0;
+ // If operator numeric is available, that means we camp on network. So we should
+ // clear the cell info and stop cell info retry.
+ if (mCellInfo != null) mCellInfo.clear();
+ stopCellInfoRetry();
}
updateLocale();
}
@@ -273,14 +316,25 @@
}
/**
+ * Stop retrying getting cell info from the modem. It cancels any scheduled cell info retrieving
+ * request.
+ */
+ private void stopCellInfoRetry() {
+ mFailCellInfoCount = 0;
+ removeMessages(EVENT_GET_CELL_INFO);
+ }
+
+ /**
* Get cell info from the modem.
*/
private void getCellInfo() {
String msg;
if (!mPhone.getServiceStateTracker().getDesiredPowerState()) {
- msg = "Radio is off. No need to get cell info.";
+ msg = "Radio is off. Stopped cell info retry. Cleared the previous cached cell info.";
+ if (mCellInfo != null) mCellInfo.clear();
if (DBG) log(msg);
mLocalLog.log(msg);
+ stopCellInfoRetry();
return;
}
@@ -294,12 +348,16 @@
// If we can't get a valid cell info. Try it again later.
long delay = getCellInfoDelayTime(++mFailCellInfoCount);
if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs.");
+ removeMessages(EVENT_GET_CELL_INFO);
sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO), delay);
} else {
- mFailCellInfoCount = 0;
- // We successfully got cell info from the modem. Cancel the queued get cell info event
- // if there is any.
- removeMessages(EVENT_GET_CELL_INFO);
+ // We successfully got cell info from the modem. We should stop cell info retry.
+ stopCellInfoRetry();
+
+ // Now we need to get the cell info from the modem periodically even if we already got
+ // the cell info because the user can move.
+ sendMessageDelayed(obtainMessage(EVENT_GET_CELL_INFO),
+ CELL_INFO_PERIODIC_POLLING_DELAY_MS);
}
}
diff --git a/src/java/com/android/internal/telephony/MccTable.java b/src/java/com/android/internal/telephony/MccTable.java
index 4a469a2..fb28194 100644
--- a/src/java/com/android/internal/telephony/MccTable.java
+++ b/src/java/com/android/internal/telephony/MccTable.java
@@ -350,12 +350,25 @@
* @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
*/
private static void setTimezoneFromMccIfNeeded(Context context, int mcc) {
- if (!TimeServiceHelper.isTimeZoneSettingInitializedStatic()) {
- String zoneId = defaultTimeZoneForMcc(mcc);
- if (zoneId != null && zoneId.length() > 0) {
- // Set time zone based on MCC
- TimeServiceHelper.setDeviceTimeZoneStatic(context, zoneId);
- Slog.d(LOG_TAG, "timezone set to " + zoneId);
+ // Switch to use the time service helper associated with the NitzStateMachine impl
+ // being used. This logic will be removed once the old implementation is removed.
+ if (TelephonyComponentFactory.USE_NEW_NITZ_STATE_MACHINE) {
+ if (!NewTimeServiceHelper.isTimeZoneSettingInitializedStatic()) {
+ String zoneId = defaultTimeZoneForMcc(mcc);
+ if (zoneId != null && zoneId.length() > 0) {
+ // Set time zone based on MCC
+ NewTimeServiceHelper.setDeviceTimeZoneStatic(context, zoneId);
+ Slog.d(LOG_TAG, "timezone set to " + zoneId);
+ }
+ }
+ } else {
+ if (!OldTimeServiceHelper.isTimeZoneSettingInitializedStatic()) {
+ String zoneId = defaultTimeZoneForMcc(mcc);
+ if (zoneId != null && zoneId.length() > 0) {
+ // Set time zone based on MCC
+ OldTimeServiceHelper.setDeviceTimeZoneStatic(context, zoneId);
+ Slog.d(LOG_TAG, "timezone set to " + zoneId);
+ }
}
}
}
diff --git a/src/java/com/android/internal/telephony/NewNitzStateMachine.java b/src/java/com/android/internal/telephony/NewNitzStateMachine.java
new file mode 100644
index 0000000..20c729f
--- /dev/null
+++ b/src/java/com/android/internal/telephony/NewNitzStateMachine.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.telephony.Rlog;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.TimestampedValue;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult;
+import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
+import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * {@hide}
+ */
+public final class NewNitzStateMachine implements NitzStateMachine {
+
+ private static final String LOG_TAG = ServiceStateTracker.LOG_TAG;
+ private static final boolean DBG = ServiceStateTracker.DBG;
+
+ // Time detection state.
+
+ /**
+ * The last NITZ-sourced time considered sent to the time detector service. Used to rate-limit
+ * calls to the time detector.
+ */
+ private TimestampedValue<Long> mSavedNitzTime;
+
+ // Time Zone detection state.
+
+ /** We always keep the last NITZ signal received in mLatestNitzSignal. */
+ private TimestampedValue<NitzData> mLatestNitzSignal;
+
+ /**
+ * Records whether the device should have a country code available via
+ * {@link DeviceState#getNetworkCountryIsoForPhone()}. Before this an NITZ signal
+ * received is (almost always) not enough to determine time zone. On test networks the country
+ * code should be available but can still be an empty string but this flag indicates that the
+ * information available is unlikely to improve.
+ */
+ private boolean mGotCountryCode = false;
+
+ /**
+ * The last time zone ID that has been determined. It may not have been set as the device time
+ * zone if automatic time zone detection is disabled but may later be used to set the time zone
+ * if the user enables automatic time zone detection.
+ */
+ private String mSavedTimeZoneId;
+
+ /**
+ * Boolean is {@code true} if NITZ has been used to determine a time zone (which may not
+ * ultimately have been used due to user settings). Cleared by {@link #handleNetworkAvailable()}
+ * and {@link #handleNetworkUnavailable()}. The flag can be used when historic NITZ data may no
+ * longer be valid. {@code false} indicates it is reasonable to try to set the time zone using
+ * less reliable algorithms than NITZ-based detection such as by just using network country
+ * code.
+ */
+ private boolean mNitzTimeZoneDetectionSuccessful = false;
+
+ // Miscellaneous dependencies and helpers not related to detection state.
+ private final LocalLog mTimeLog = new LocalLog(15);
+ private final LocalLog mTimeZoneLog = new LocalLog(15);
+ private final GsmCdmaPhone mPhone;
+ private final DeviceState mDeviceState;
+ private final NewTimeServiceHelper mTimeServiceHelper;
+ private final TimeZoneLookupHelper mTimeZoneLookupHelper;
+ /** Wake lock used while setting time of day. */
+ private final PowerManager.WakeLock mWakeLock;
+ private static final String WAKELOCK_TAG = "NitzStateMachine";
+
+ public NewNitzStateMachine(GsmCdmaPhone phone) {
+ this(phone,
+ new NewTimeServiceHelper(phone.getContext()),
+ new DeviceState(phone),
+ new TimeZoneLookupHelper());
+ }
+
+ @VisibleForTesting
+ public NewNitzStateMachine(GsmCdmaPhone phone, NewTimeServiceHelper timeServiceHelper,
+ DeviceState deviceState, TimeZoneLookupHelper timeZoneLookupHelper) {
+ mPhone = phone;
+
+ Context context = phone.getContext();
+ PowerManager powerManager =
+ (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
+
+ mDeviceState = deviceState;
+ mTimeZoneLookupHelper = timeZoneLookupHelper;
+ mTimeServiceHelper = timeServiceHelper;
+ mTimeServiceHelper.setListener(new NewTimeServiceHelper.Listener() {
+ @Override
+ public void onTimeZoneDetectionChange(boolean enabled) {
+ if (enabled) {
+ handleAutoTimeZoneEnabled();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void handleNetworkCountryCodeSet(boolean countryChanged) {
+ boolean hadCountryCode = mGotCountryCode;
+ mGotCountryCode = true;
+
+ String isoCountryCode = mDeviceState.getNetworkCountryIsoForPhone();
+ if (!TextUtils.isEmpty(isoCountryCode) && !mNitzTimeZoneDetectionSuccessful) {
+ updateTimeZoneFromNetworkCountryCode(isoCountryCode);
+ }
+
+ if (mLatestNitzSignal != null && (countryChanged || !hadCountryCode)) {
+ updateTimeZoneFromCountryAndNitz();
+ }
+ }
+
+ private void updateTimeZoneFromCountryAndNitz() {
+ String isoCountryCode = mDeviceState.getNetworkCountryIsoForPhone();
+ TimestampedValue<NitzData> nitzSignal = mLatestNitzSignal;
+
+ // TimeZone.getDefault() returns a default zone (GMT) even when time zone have never
+ // been set which makes it difficult to tell if it's what the user / time zone detection
+ // has chosen. isTimeZoneSettingInitialized() tells us whether the time zone of the
+ // device has ever been explicit set by the user or code.
+ final boolean isTimeZoneSettingInitialized =
+ mTimeServiceHelper.isTimeZoneSettingInitialized();
+
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeZoneFromCountryAndNitz:"
+ + " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized
+ + " nitzSignal=" + nitzSignal
+ + " isoCountryCode=" + isoCountryCode);
+ }
+
+ try {
+ NitzData nitzData = nitzSignal.getValue();
+
+ String zoneId;
+ if (nitzData.getEmulatorHostTimeZone() != null) {
+ zoneId = nitzData.getEmulatorHostTimeZone().getID();
+ } else if (!mGotCountryCode) {
+ // We don't have a country code so we won't try to look up the time zone.
+ zoneId = null;
+ } else if (TextUtils.isEmpty(isoCountryCode)) {
+ // We have a country code but it's empty. This is most likely because we're on a
+ // test network that's using a bogus MCC (eg, "001"). Obtain a TimeZone based only
+ // on the NITZ parameters: it's only going to be correct in a few cases but it
+ // should at least have the correct offset.
+ OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitz(nitzData);
+ String logMsg = "updateTimeZoneFromCountryAndNitz: lookupByNitz returned"
+ + " lookupResult=" + lookupResult;
+ if (DBG) {
+ Rlog.d(LOG_TAG, logMsg);
+ }
+ // We log this in the time zone log because it has been a source of bugs.
+ mTimeZoneLog.log(logMsg);
+
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
+ } else if (mLatestNitzSignal == null) {
+ if (DBG) {
+ Rlog.d(LOG_TAG,
+ "updateTimeZoneFromCountryAndNitz: No cached NITZ data available,"
+ + " not setting zone");
+ }
+ zoneId = null;
+ } else if (isNitzSignalOffsetInfoBogus(nitzSignal, isoCountryCode)) {
+ String logMsg = "updateTimeZoneFromCountryAndNitz: Received NITZ looks bogus, "
+ + " isoCountryCode=" + isoCountryCode
+ + " nitzSignal=" + nitzSignal;
+ if (DBG) {
+ Rlog.d(LOG_TAG, logMsg);
+ }
+ // We log this in the time zone log because it has been a source of bugs.
+ mTimeZoneLog.log(logMsg);
+
+ zoneId = null;
+ } else {
+ OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitzCountry(
+ nitzData, isoCountryCode);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeZoneFromCountryAndNitz: using"
+ + " lookupByNitzCountry(nitzData, isoCountryCode),"
+ + " nitzData=" + nitzData
+ + " isoCountryCode=" + isoCountryCode
+ + " lookupResult=" + lookupResult);
+ }
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
+ }
+
+ // Log the action taken to the dedicated time zone log.
+ final String tmpLog = "updateTimeZoneFromCountryAndNitz:"
+ + " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized
+ + " isoCountryCode=" + isoCountryCode
+ + " nitzSignal=" + nitzSignal
+ + " zoneId=" + zoneId
+ + " isTimeZoneDetectionEnabled()="
+ + mTimeServiceHelper.isTimeZoneDetectionEnabled();
+ mTimeZoneLog.log(tmpLog);
+
+ // Set state as needed.
+ if (zoneId != null) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeZoneFromCountryAndNitz: zoneId=" + zoneId);
+ }
+ if (mTimeServiceHelper.isTimeZoneDetectionEnabled()) {
+ setAndBroadcastNetworkSetTimeZone(zoneId);
+ } else {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeZoneFromCountryAndNitz: skip changing zone"
+ + " as isTimeZoneDetectionEnabled() is false");
+ }
+ }
+ mSavedTimeZoneId = zoneId;
+ mNitzTimeZoneDetectionSuccessful = true;
+ } else {
+ if (DBG) {
+ Rlog.d(LOG_TAG,
+ "updateTimeZoneFromCountryAndNitz: zoneId == null, do nothing");
+ }
+ }
+ } catch (RuntimeException ex) {
+ Rlog.e(LOG_TAG, "updateTimeZoneFromCountryAndNitz: Processing NITZ data"
+ + " nitzSignal=" + nitzSignal
+ + " isoCountryCode=" + isoCountryCode
+ + " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized
+ + " ex=" + ex);
+ }
+ }
+
+ /**
+ * Returns true if the NITZ signal is definitely bogus, assuming that the country is correct.
+ */
+ private boolean isNitzSignalOffsetInfoBogus(
+ TimestampedValue<NitzData> nitzSignal, String isoCountryCode) {
+
+ if (TextUtils.isEmpty(isoCountryCode)) {
+ // We cannot say for sure.
+ return false;
+ }
+
+ NitzData newNitzData = nitzSignal.getValue();
+ boolean zeroOffsetNitz = newNitzData.getLocalOffsetMillis() == 0 && !newNitzData.isDst();
+ return zeroOffsetNitz && !countryUsesUtc(isoCountryCode, nitzSignal);
+ }
+
+ private boolean countryUsesUtc(
+ String isoCountryCode, TimestampedValue<NitzData> nitzSignal) {
+ return mTimeZoneLookupHelper.countryUsesUtc(
+ isoCountryCode,
+ nitzSignal.getValue().getCurrentTimeInMillis());
+ }
+
+ @Override
+ public void handleNetworkAvailable() {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkAvailable: mNitzTimeZoneDetectionSuccessful="
+ + mNitzTimeZoneDetectionSuccessful
+ + ", Setting mNitzTimeZoneDetectionSuccessful=false");
+ }
+ mNitzTimeZoneDetectionSuccessful = false;
+ }
+
+ @Override
+ public void handleNetworkUnavailable() {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkUnavailable");
+ }
+
+ mGotCountryCode = false;
+ mNitzTimeZoneDetectionSuccessful = false;
+ }
+
+ @Override
+ public void handleNitzReceived(TimestampedValue<NitzData> nitzSignal) {
+ // Always store the latest NITZ signal received.
+ mLatestNitzSignal = nitzSignal;
+
+ updateTimeZoneFromCountryAndNitz();
+ updateTimeFromNitz();
+ }
+
+ private void updateTimeFromNitz() {
+ TimestampedValue<NitzData> nitzSignal = mLatestNitzSignal;
+ try {
+ boolean ignoreNitz = mDeviceState.getIgnoreNitz();
+ if (ignoreNitz) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeFromNitz: Not suggesting system clock because"
+ + " gsm.ignore-nitz is set");
+ }
+ return;
+ }
+
+ // Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values.
+ try {
+ // Acquire the wake lock as we are reading the elapsed realtime clock below.
+ mWakeLock.acquire();
+
+ long elapsedRealtime = mTimeServiceHelper.elapsedRealtime();
+ long millisSinceNitzReceived =
+ elapsedRealtime - nitzSignal.getReferenceTimeMillis();
+ if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeFromNitz: not setting time, unexpected"
+ + " elapsedRealtime=" + elapsedRealtime
+ + " nitzSignal=" + nitzSignal);
+ }
+ return;
+ }
+ } finally {
+ mWakeLock.release();
+ }
+
+ TimestampedValue<Long> newNitzTime = new TimestampedValue<>(
+ nitzSignal.getReferenceTimeMillis(),
+ nitzSignal.getValue().getCurrentTimeInMillis());
+
+ // Perform rate limiting: a NITZ signal received too close to a previous
+ // one will be disregarded unless there is a significant difference between the
+ // UTC times they represent.
+ if (mSavedNitzTime != null) {
+ int nitzUpdateSpacing = mDeviceState.getNitzUpdateSpacingMillis();
+ int nitzUpdateDiff = mDeviceState.getNitzUpdateDiffMillis();
+
+ // Calculate the elapsed time between the new signal and the last signal.
+ long elapsedRealtimeSinceLastSaved = newNitzTime.getReferenceTimeMillis()
+ - mSavedNitzTime.getReferenceTimeMillis();
+
+ // Calculate the UTC difference between the time the two signals hold.
+ long utcTimeDifferenceMillis =
+ newNitzTime.getValue() - mSavedNitzTime.getValue();
+
+ // Ideally the difference between elapsedRealtimeSinceLastSaved and
+ // utcTimeDifferenceMillis would be zero.
+ long millisGained = utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved;
+
+ if (elapsedRealtimeSinceLastSaved <= nitzUpdateSpacing
+ && Math.abs(millisGained) <= nitzUpdateDiff) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeFromNitz: not setting time. NITZ signal is"
+ + " too similar to previous value received "
+ + " mSavedNitzTime=" + mSavedNitzTime
+ + ", nitzSignal=" + nitzSignal
+ + ", nitzUpdateSpacing=" + nitzUpdateSpacing
+ + ", nitzUpdateDiff=" + nitzUpdateDiff);
+ }
+ return;
+ }
+ }
+
+ String logMsg = "updateTimeFromNitz: suggesting system clock update"
+ + " nitzSignal=" + nitzSignal
+ + ", newNitzTime=" + newNitzTime
+ + ", mSavedNitzTime= " + mSavedNitzTime;
+ if (DBG) {
+ Rlog.d(LOG_TAG, logMsg);
+ }
+ mTimeLog.log(logMsg);
+ mTimeServiceHelper.suggestDeviceTime(newNitzTime);
+ TelephonyMetrics.getInstance().writeNITZEvent(
+ mPhone.getPhoneId(), newNitzTime.getValue());
+
+ // Save the last NITZ time signal that was suggested to enable rate limiting.
+ mSavedNitzTime = newNitzTime;
+ } catch (RuntimeException ex) {
+ Rlog.e(LOG_TAG, "updateTimeFromNitz: Processing NITZ data"
+ + " nitzSignal=" + nitzSignal
+ + " ex=" + ex);
+ }
+ }
+
+ private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "setAndBroadcastNetworkSetTimeZone: zoneId=" + zoneId);
+ }
+ mTimeServiceHelper.setDeviceTimeZone(zoneId);
+ if (DBG) {
+ Rlog.d(LOG_TAG,
+ "setAndBroadcastNetworkSetTimeZone: called setDeviceTimeZone()"
+ + " zoneId=" + zoneId);
+ }
+ }
+
+ private void handleAutoTimeZoneEnabled() {
+ String tmpLog = "handleAutoTimeZoneEnabled: Reverting to NITZ TimeZone:"
+ + " mSavedTimeZoneId=" + mSavedTimeZoneId;
+ if (DBG) {
+ Rlog.d(LOG_TAG, tmpLog);
+ }
+ mTimeZoneLog.log(tmpLog);
+ if (mSavedTimeZoneId != null) {
+ setAndBroadcastNetworkSetTimeZone(mSavedTimeZoneId);
+ }
+ }
+
+ @Override
+ public void dumpState(PrintWriter pw) {
+ // Time Detection State
+ pw.println(" mSavedTime=" + mSavedNitzTime);
+
+ // Time Zone Detection State
+ pw.println(" mLatestNitzSignal=" + mLatestNitzSignal);
+ pw.println(" mGotCountryCode=" + mGotCountryCode);
+ pw.println(" mSavedTimeZoneId=" + mSavedTimeZoneId);
+ pw.println(" mNitzTimeZoneDetectionSuccessful=" + mNitzTimeZoneDetectionSuccessful);
+
+ // Miscellaneous
+ pw.println(" mWakeLock=" + mWakeLock);
+ pw.flush();
+ }
+
+ @Override
+ public void dumpLogs(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
+ ipw.println(" Time Logs:");
+ ipw.increaseIndent();
+ mTimeLog.dump(fd, ipw, args);
+ ipw.decreaseIndent();
+
+ ipw.println(" Time zone Logs:");
+ ipw.increaseIndent();
+ mTimeZoneLog.dump(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+
+ /**
+ * Update time zone by network country code, works well on countries which only have one time
+ * zone or multiple zones with the same offset.
+ *
+ * @param iso Country code from network MCC
+ */
+ private void updateTimeZoneFromNetworkCountryCode(String iso) {
+ CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry(
+ iso, mTimeServiceHelper.currentTimeMillis());
+ if (lookupResult != null && lookupResult.allZonesHaveSameOffset) {
+ String logMsg = "updateTimeZoneFromNetworkCountryCode: tz result found"
+ + " iso=" + iso
+ + " lookupResult=" + lookupResult;
+ if (DBG) {
+ Rlog.d(LOG_TAG, logMsg);
+ }
+ mTimeZoneLog.log(logMsg);
+ String zoneId = lookupResult.zoneId;
+ if (mTimeServiceHelper.isTimeZoneDetectionEnabled()) {
+ setAndBroadcastNetworkSetTimeZone(zoneId);
+ }
+ mSavedTimeZoneId = zoneId;
+ } else {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "updateTimeZoneFromNetworkCountryCode: no good zone for"
+ + " iso=" + iso
+ + " lookupResult=" + lookupResult);
+ }
+ }
+ }
+
+ public boolean getNitzTimeZoneDetectionSuccessful() {
+ return mNitzTimeZoneDetectionSuccessful;
+ }
+
+ @Override
+ public NitzData getCachedNitzData() {
+ return mLatestNitzSignal != null ? mLatestNitzSignal.getValue() : null;
+ }
+
+ @Override
+ public String getSavedTimeZoneId() {
+ return mSavedTimeZoneId;
+ }
+
+}
diff --git a/src/java/com/android/internal/telephony/TimeServiceHelper.java b/src/java/com/android/internal/telephony/NewTimeServiceHelper.java
similarity index 79%
copy from src/java/com/android/internal/telephony/TimeServiceHelper.java
copy to src/java/com/android/internal/telephony/NewTimeServiceHelper.java
index 94b094f..1346c5f 100644
--- a/src/java/com/android/internal/telephony/TimeServiceHelper.java
+++ b/src/java/com/android/internal/telephony/NewTimeServiceHelper.java
@@ -17,6 +17,8 @@
package com.android.internal.telephony;
import android.app.AlarmManager;
+import android.app.timedetector.TimeDetector;
+import android.app.timedetector.TimeSignal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -26,24 +28,20 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.TimestampedValue;
/**
* An interface to various time / time zone detection behaviors that should be centralized into a
* new service.
*/
// Non-final to allow mocking.
-public class TimeServiceHelper {
+public class NewTimeServiceHelper {
/**
* Callback interface for automatic detection enable/disable changes.
*/
public interface Listener {
/**
- * Automatic time detection has been enabled or disabled.
- */
- void onTimeDetectionChange(boolean enabled);
-
- /**
* Automatic time zone detection has been enabled or disabled.
*/
void onTimeZoneDetectionChange(boolean enabled);
@@ -53,13 +51,15 @@
private final Context mContext;
private final ContentResolver mCr;
+ private final TimeDetector mTimeDetector;
private Listener mListener;
/** Creates a TimeServiceHelper */
- public TimeServiceHelper(Context context) {
+ public NewTimeServiceHelper(Context context) {
mContext = context;
mCr = context.getContentResolver();
+ mTimeDetector = context.getSystemService(TimeDetector.class);
}
/**
@@ -75,13 +75,6 @@
}
this.mListener = listener;
mCr.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
- new ContentObserver(new Handler()) {
- public void onChange(boolean selfChange) {
- listener.onTimeDetectionChange(isTimeDetectionEnabled());
- }
- });
- mCr.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
new ContentObserver(new Handler()) {
public void onChange(boolean selfChange) {
@@ -113,17 +106,6 @@
}
/**
- * Returns true if automatic time detection is enabled in settings.
- */
- public boolean isTimeDetectionEnabled() {
- try {
- return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME) > 0;
- } catch (Settings.SettingNotFoundException snfe) {
- return true;
- }
- }
-
- /**
* Returns true if automatic time zone detection is enabled in settings.
*/
public boolean isTimeZoneDetectionEnabled() {
@@ -145,17 +127,13 @@
}
/**
- * Set the time and Send out a sticky broadcast so the system can determine
- * if the time was set by the carrier.
+ * Suggest the time to the {@link TimeDetector}.
*
- * @param time time set by network
+ * @param signalTimeMillis the signal time as received from the network
*/
- public void setDeviceTime(long time) {
- SystemClock.setCurrentTimeMillis(time);
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time", time);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ public void suggestDeviceTime(TimestampedValue<Long> signalTimeMillis) {
+ TimeSignal timeSignal = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, signalTimeMillis);
+ mTimeDetector.suggestTime(timeSignal);
}
/**
diff --git a/src/java/com/android/internal/telephony/NitzStateMachine.java b/src/java/com/android/internal/telephony/NitzStateMachine.java
index 8fb36f2..6a5e47a 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachine.java
@@ -21,8 +21,8 @@
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.TelephonyManager;
+import android.util.TimestampedValue;
-import com.android.internal.telephony.util.TimeStampedValue;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -55,7 +55,7 @@
/**
* Handle a new NITZ signal being received.
*/
- void handleNitzReceived(TimeStampedValue<NitzData> nitzSignal);
+ void handleNitzReceived(TimestampedValue<NitzData> nitzSignal);
/**
* Dumps the current in-memory state to the supplied PrintWriter.
diff --git a/src/java/com/android/internal/telephony/OldNitzStateMachine.java b/src/java/com/android/internal/telephony/OldNitzStateMachine.java
index 23d2cc7..bb43f1e 100644
--- a/src/java/com/android/internal/telephony/OldNitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/OldNitzStateMachine.java
@@ -21,12 +21,12 @@
import android.telephony.Rlog;
import android.text.TextUtils;
import android.util.LocalLog;
+import android.util.TimestampedValue;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult;
import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.util.TimeStampedValue;
import com.android.internal.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -47,12 +47,12 @@
* not have been used to set the device time, but it can be used if auto time detection is
* re-enabled.
*/
- private TimeStampedValue<Long> mSavedNitzTime;
+ private TimestampedValue<Long> mSavedNitzTime;
// Time Zone detection state.
/** We always keep the last NITZ signal received in mLatestNitzSignal. */
- private TimeStampedValue<NitzData> mLatestNitzSignal;
+ private TimestampedValue<NitzData> mLatestNitzSignal;
/**
* Records whether the device should have a country code available via
@@ -85,7 +85,7 @@
private final LocalLog mTimeZoneLog = new LocalLog(15);
private final GsmCdmaPhone mPhone;
private final DeviceState mDeviceState;
- private final TimeServiceHelper mTimeServiceHelper;
+ private final OldTimeServiceHelper mTimeServiceHelper;
private final TimeZoneLookupHelper mTimeZoneLookupHelper;
/** Wake lock used while setting time of day. */
private final PowerManager.WakeLock mWakeLock;
@@ -93,13 +93,13 @@
public OldNitzStateMachine(GsmCdmaPhone phone) {
this(phone,
- new TimeServiceHelper(phone.getContext()),
+ new OldTimeServiceHelper(phone.getContext()),
new DeviceState(phone),
new TimeZoneLookupHelper());
}
@VisibleForTesting
- public OldNitzStateMachine(GsmCdmaPhone phone, TimeServiceHelper timeServiceHelper,
+ public OldNitzStateMachine(GsmCdmaPhone phone, OldTimeServiceHelper timeServiceHelper,
DeviceState deviceState, TimeZoneLookupHelper timeZoneLookupHelper) {
mPhone = phone;
@@ -111,7 +111,7 @@
mDeviceState = deviceState;
mTimeZoneLookupHelper = timeZoneLookupHelper;
mTimeServiceHelper = timeServiceHelper;
- mTimeServiceHelper.setListener(new TimeServiceHelper.Listener() {
+ mTimeServiceHelper.setListener(new OldTimeServiceHelper.Listener() {
@Override
public void onTimeDetectionChange(boolean enabled) {
if (enabled) {
@@ -145,7 +145,7 @@
private void updateTimeZoneFromCountryAndNitz() {
String isoCountryCode = mDeviceState.getNetworkCountryIsoForPhone();
- TimeStampedValue<NitzData> nitzSignal = mLatestNitzSignal;
+ TimestampedValue<NitzData> nitzSignal = mLatestNitzSignal;
// TimeZone.getDefault() returns a default zone (GMT) even when time zone have never
// been set which makes it difficult to tell if it's what the user / time zone detection
@@ -162,7 +162,7 @@
}
try {
- NitzData nitzData = nitzSignal.mValue;
+ NitzData nitzData = nitzSignal.getValue();
String zoneId;
if (nitzData.getEmulatorHostTimeZone() != null) {
@@ -260,23 +260,23 @@
* Returns true if the NITZ signal is definitely bogus, assuming that the country is correct.
*/
private boolean isNitzSignalOffsetInfoBogus(
- TimeStampedValue<NitzData> nitzSignal, String isoCountryCode) {
+ TimestampedValue<NitzData> nitzSignal, String isoCountryCode) {
if (TextUtils.isEmpty(isoCountryCode)) {
// We cannot say for sure.
return false;
}
- NitzData newNitzData = nitzSignal.mValue;
+ NitzData newNitzData = nitzSignal.getValue();
boolean zeroOffsetNitz = newNitzData.getLocalOffsetMillis() == 0 && !newNitzData.isDst();
return zeroOffsetNitz && !countryUsesUtc(isoCountryCode, nitzSignal);
}
private boolean countryUsesUtc(
- String isoCountryCode, TimeStampedValue<NitzData> nitzSignal) {
+ String isoCountryCode, TimestampedValue<NitzData> nitzSignal) {
return mTimeZoneLookupHelper.countryUsesUtc(
isoCountryCode,
- nitzSignal.mValue.getCurrentTimeInMillis());
+ nitzSignal.getValue().getCurrentTimeInMillis());
}
@Override
@@ -300,7 +300,7 @@
}
@Override
- public void handleNitzReceived(TimeStampedValue<NitzData> nitzSignal) {
+ public void handleNitzReceived(TimestampedValue<NitzData> nitzSignal) {
// Always store the latest NITZ signal received.
mLatestNitzSignal = nitzSignal;
@@ -309,7 +309,7 @@
}
private void updateTimeFromNitz() {
- TimeStampedValue<NitzData> nitzSignal = mLatestNitzSignal;
+ TimestampedValue<NitzData> nitzSignal = mLatestNitzSignal;
try {
boolean ignoreNitz = mDeviceState.getIgnoreNitz();
if (ignoreNitz) {
@@ -327,7 +327,8 @@
// Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values.
long elapsedRealtime = mTimeServiceHelper.elapsedRealtime();
- long millisSinceNitzReceived = elapsedRealtime - nitzSignal.mElapsedRealtime;
+ long millisSinceNitzReceived =
+ elapsedRealtime - nitzSignal.getReferenceTimeMillis();
if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
if (DBG) {
Rlog.d(LOG_TAG, "updateTimeFromNitz: not setting time, unexpected"
@@ -339,7 +340,7 @@
// Adjust the NITZ time by the delay since it was received to get the time now.
long adjustedCurrentTimeMillis =
- nitzSignal.mValue.getCurrentTimeInMillis() + millisSinceNitzReceived;
+ nitzSignal.getValue().getCurrentTimeInMillis() + millisSinceNitzReceived;
long gained = adjustedCurrentTimeMillis - mTimeServiceHelper.currentTimeMillis();
if (mTimeServiceHelper.isTimeDetectionEnabled()) {
@@ -354,7 +355,7 @@
setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis);
} else {
long elapsedRealtimeSinceLastSaved = mTimeServiceHelper.elapsedRealtime()
- - mSavedNitzTime.mElapsedRealtime;
+ - mSavedNitzTime.getReferenceTimeMillis();
int nitzUpdateSpacing = mDeviceState.getNitzUpdateSpacingMillis();
int nitzUpdateDiff = mDeviceState.getNitzUpdateDiffMillis();
if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing
@@ -381,8 +382,9 @@
// Save the last NITZ time signal used so we can return to it later
// if auto-time detection is toggled.
- mSavedNitzTime = new TimeStampedValue<>(
- adjustedCurrentTimeMillis, nitzSignal.mElapsedRealtime);
+ mSavedNitzTime = new TimestampedValue<>(
+ nitzSignal.getReferenceTimeMillis(),
+ nitzSignal.getValue().getCurrentTimeInMillis());
} finally {
mWakeLock.release();
}
@@ -434,8 +436,8 @@
String msg = "mSavedNitzTime: Reverting to NITZ time"
+ " elapsedRealtime=" + elapsedRealtime
+ " mSavedNitzTime=" + mSavedNitzTime;
- long adjustedCurrentTimeMillis =
- mSavedNitzTime.mValue + (elapsedRealtime - mSavedNitzTime.mElapsedRealtime);
+ long adjustedCurrentTimeMillis = mSavedNitzTime.getValue()
+ + (elapsedRealtime - mSavedNitzTime.getReferenceTimeMillis());
setAndBroadcastNetworkSetTime(msg, adjustedCurrentTimeMillis);
} finally {
mWakeLock.release();
@@ -521,7 +523,7 @@
@Override
public NitzData getCachedNitzData() {
- return mLatestNitzSignal != null ? mLatestNitzSignal.mValue : null;
+ return mLatestNitzSignal != null ? mLatestNitzSignal.getValue() : null;
}
@Override
diff --git a/src/java/com/android/internal/telephony/TimeServiceHelper.java b/src/java/com/android/internal/telephony/OldTimeServiceHelper.java
similarity index 98%
rename from src/java/com/android/internal/telephony/TimeServiceHelper.java
rename to src/java/com/android/internal/telephony/OldTimeServiceHelper.java
index 94b094f..9c7a763 100644
--- a/src/java/com/android/internal/telephony/TimeServiceHelper.java
+++ b/src/java/com/android/internal/telephony/OldTimeServiceHelper.java
@@ -32,7 +32,7 @@
* new service.
*/
// Non-final to allow mocking.
-public class TimeServiceHelper {
+public class OldTimeServiceHelper {
/**
* Callback interface for automatic detection enable/disable changes.
@@ -57,7 +57,7 @@
private Listener mListener;
/** Creates a TimeServiceHelper */
- public TimeServiceHelper(Context context) {
+ public OldTimeServiceHelper(Context context) {
mContext = context;
mCr = context.getContentResolver();
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index fdf1311..899f1fc 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -1420,8 +1420,6 @@
*/
public void registerForServiceStateChanged(
Handler h, int what, Object obj) {
- checkCorrectThread(h);
-
mServiceStateRegistrants.add(h, what, obj);
}
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 9ba5695..9f7ea05 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -29,6 +29,7 @@
import android.hardware.radio.V1_0.CellInfoCdma;
import android.hardware.radio.V1_0.CellInfoGsm;
import android.hardware.radio.V1_0.CellInfoLte;
+import android.hardware.radio.V1_0.CellInfoTdscdma;
import android.hardware.radio.V1_0.CellInfoType;
import android.hardware.radio.V1_0.CellInfoWcdma;
import android.hardware.radio.V1_0.DataProfileInfo;
@@ -3098,7 +3099,7 @@
try {
radioProxy.sendImsSms(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
- SmsSession.Event.Format.SMS_FORMAT_3GPP);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP2);
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
}
@@ -3951,6 +3952,7 @@
appendPrimitiveArrayToArrayList(
packetData.dstAddress.getAddress(), req.destinationAddress);
req.destinationPort = packetData.dstPort;
+ req.maxKeepaliveIntervalMillis = intervalMillis;
radioProxy11.startKeepalive(rr.mSerial, req);
} catch (RemoteException | RuntimeException e) {
@@ -5278,7 +5280,7 @@
private static void writeToParcelForWcdma(
Parcel p, int lac, int cid, int psc, int uarfcn, String mcc, String mnc,
- String al, String as, int ss, int ber) {
+ String al, String as, int ss, int ber, int rscp, int ecno) {
p.writeInt(CellIdentity.TYPE_WCDMA);
p.writeString(mcc);
p.writeString(mnc);
@@ -5290,6 +5292,25 @@
p.writeInt(uarfcn);
p.writeInt(ss);
p.writeInt(ber);
+ p.writeInt(rscp);
+ p.writeInt(ecno);
+ }
+
+ private static void writeToParcelForTdscdma(
+ Parcel p, int lac, int cid, int cpid, int uarfcn, String mcc, String mnc,
+ String al, String as, int ss, int ber, int rscp) {
+ p.writeInt(CellIdentity.TYPE_TDSCDMA);
+ p.writeString(mcc);
+ p.writeString(mnc);
+ p.writeString(al);
+ p.writeString(as);
+ p.writeInt(lac);
+ p.writeInt(cid);
+ p.writeInt(cpid);
+ p.writeInt(uarfcn);
+ p.writeInt(ss);
+ p.writeInt(ber);
+ p.writeInt(rscp);
}
/**
@@ -5383,10 +5404,29 @@
EMPTY_ALPHA_LONG,
EMPTY_ALPHA_SHORT,
cellInfoWcdma.signalStrengthWcdma.signalStrength,
- cellInfoWcdma.signalStrengthWcdma.bitErrorRate);
+ cellInfoWcdma.signalStrengthWcdma.bitErrorRate,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE);
break;
}
+ case CellInfoType.TD_SCDMA: {
+ CellInfoTdscdma cellInfoTdscdma = record.tdscdma.get(0);
+ writeToParcelForTdscdma(
+ p,
+ cellInfoTdscdma.cellIdentityTdscdma.lac,
+ cellInfoTdscdma.cellIdentityTdscdma.cid,
+ cellInfoTdscdma.cellIdentityTdscdma.cpid,
+ Integer.MAX_VALUE,
+ cellInfoTdscdma.cellIdentityTdscdma.mcc,
+ cellInfoTdscdma.cellIdentityTdscdma.mnc,
+ EMPTY_ALPHA_LONG,
+ EMPTY_ALPHA_SHORT,
+ Integer.MAX_VALUE,
+ Integer.MAX_VALUE,
+ convertTdscdmaRscpTo1_2(cellInfoTdscdma.signalStrengthTdscdma.rscp));
+ break;
+ }
default:
throw new RuntimeException("unexpected cellinfotype: " + record.cellInfoType);
}
@@ -5491,7 +5531,28 @@
cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaLong,
cellInfoWcdma.cellIdentityWcdma.operatorNames.alphaShort,
cellInfoWcdma.signalStrengthWcdma.base.signalStrength,
- cellInfoWcdma.signalStrengthWcdma.base.bitErrorRate);
+ cellInfoWcdma.signalStrengthWcdma.base.bitErrorRate,
+ cellInfoWcdma.signalStrengthWcdma.rscp,
+ cellInfoWcdma.signalStrengthWcdma.ecno);
+ break;
+ }
+
+ case CellInfoType.TD_SCDMA: {
+ android.hardware.radio.V1_2.CellInfoTdscdma cellInfoTdscdma =
+ record.tdscdma.get(0);
+ writeToParcelForTdscdma(
+ p,
+ cellInfoTdscdma.cellIdentityTdscdma.base.lac,
+ cellInfoTdscdma.cellIdentityTdscdma.base.cid,
+ cellInfoTdscdma.cellIdentityTdscdma.base.cpid,
+ cellInfoTdscdma.cellIdentityTdscdma.uarfcn,
+ cellInfoTdscdma.cellIdentityTdscdma.base.mcc,
+ cellInfoTdscdma.cellIdentityTdscdma.base.mnc,
+ cellInfoTdscdma.cellIdentityTdscdma.operatorNames.alphaLong,
+ cellInfoTdscdma.cellIdentityTdscdma.operatorNames.alphaShort,
+ cellInfoTdscdma.signalStrengthTdscdma.signalStrength,
+ cellInfoTdscdma.signalStrengthTdscdma.bitErrorRate,
+ cellInfoTdscdma.signalStrengthTdscdma.rscp);
break;
}
@@ -5508,19 +5569,22 @@
return response;
}
+ private static int convertTdscdmaRscpTo1_2(int rscp) {
+ // The HAL 1.0 range is 25..120; the ASU/ HAL 1.2 range is 0..96;
+ // yes, this means the range in 1.0 cannot express -24dBm = 96
+ if (rscp >= 25 && rscp <= 120) {
+ // First we flip the sign to convert from the HALs -rscp to the actual RSCP value.
+ int rscpDbm = -rscp;
+ // Then to convert from RSCP to ASU, we apply the offset which aligns 0 ASU to -120dBm.
+ return rscpDbm + 120;
+ }
+ return Integer.MAX_VALUE;
+ }
+
/** Convert HAL 1.0 Signal Strength to android SignalStrength */
@VisibleForTesting
public static SignalStrength convertHalSignalStrength(
android.hardware.radio.V1_0.SignalStrength signalStrength) {
- int tdscdmaRscp_1_2 = 255; // 255 is the value for unknown/unreported ASU.
- // The HAL 1.0 range is 25..120; the ASU/ HAL 1.2 range is 0..96;
- // yes, this means the range in 1.0 cannot express -24dBm = 96
- if (signalStrength.tdScdma.rscp >= 25 && signalStrength.tdScdma.rscp <= 120) {
- // First we flip the sign to convert from the HALs -rscp to the actual RSCP value.
- int rscpDbm = -signalStrength.tdScdma.rscp;
- // Then to convert from RSCP to ASU, we apply the offset which aligns 0 ASU to -120dBm.
- tdscdmaRscp_1_2 = rscpDbm + 120;
- }
return new SignalStrength(
signalStrength.gw.signalStrength,
signalStrength.gw.bitErrorRate,
@@ -5534,7 +5598,7 @@
signalStrength.lte.rsrq,
signalStrength.lte.rssnr,
signalStrength.lte.cqi,
- tdscdmaRscp_1_2);
+ convertTdscdmaRscpTo1_2(signalStrength.tdScdma.rscp));
}
/** Convert HAL 1.2 Signal Strength to android SignalStrength */
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index e790ab6..0fc5279 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -1328,12 +1328,12 @@
} else {
ret = new KeepaliveStatus(keepaliveStatus.sessionHandle, convertedStatus);
}
+ // If responseInfo.error is NONE, response function sends the response message
+ // even if result is actually an error.
+ sendMessageResponse(rr.mResult, ret);
break;
case RadioError.REQUEST_NOT_SUPPORTED:
ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED);
- // The request is unsupported, which is ok. We'll report it to the higher
- // layer and treat it as acceptable in the RIL.
- responseInfo.error = RadioError.NONE;
break;
case RadioError.NO_RESOURCES:
ret = new KeepaliveStatus(KeepaliveStatus.ERROR_NO_RESOURCES);
@@ -1342,7 +1342,7 @@
ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN);
break;
}
- sendMessageResponse(rr.mResult, ret);
+ // If responseInfo.error != NONE, the processResponseDone sends the response message.
mRil.processResponseDone(rr, responseInfo, ret);
}
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index 5e2850d..3745182 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -102,7 +102,7 @@
/** Ratchets RATs and cell bandwidths if oldSS and newSS have the same RAT family. */
public void ratchet(ServiceState oldSS, ServiceState newSS, boolean locationChange) {
- if (isSameRatFamily(oldSS, newSS)) {
+ if (!locationChange && isSameRatFamily(oldSS, newSS)) {
updateBandwidths(oldSS.getCellBandwidths(), newSS);
}
// temporarily disable rat ratchet on location change.
@@ -137,6 +137,10 @@
private boolean isSameRatFamily(ServiceState ss1, ServiceState ss2) {
synchronized (mRatFamilyMap) {
+ // Either the two technologies are the same or their families must be non-null
+ // and the same.
+ if (ss1.getRilDataRadioTechnology() == ss2.getRilDataRadioTechnology()) return true;
+ if (mRatFamilyMap.get(ss1.getRilDataRadioTechnology()) == null) return false;
return mRatFamilyMap.get(ss1.getRilDataRadioTechnology())
== mRatFamilyMap.get(ss2.getRilDataRadioTechnology());
}
diff --git a/src/java/com/android/internal/telephony/RetryManager.java b/src/java/com/android/internal/telephony/RetryManager.java
index 23c3498..0b4bc3c 100644
--- a/src/java/com/android/internal/telephony/RetryManager.java
+++ b/src/java/com/android/internal/telephony/RetryManager.java
@@ -22,11 +22,10 @@
import android.os.SystemProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
+import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.Pair;
-import com.android.internal.telephony.dataconnection.ApnSetting;
-
import java.util.ArrayList;
import java.util.Random;
@@ -506,7 +505,9 @@
if (++index == mWaitingApns.size()) index = 0;
// Stop if we find the non-failed APN.
- if (mWaitingApns.get(index).permanentFailed == false) break;
+ if (!mWaitingApns.get(index).getPermanentFailed()) {
+ break;
+ }
// If we've already cycled through all the APNs, that means there is no APN we can try
if (index == mCurrentApnIndex) return null;
@@ -553,7 +554,9 @@
if (++index >= mWaitingApns.size()) index = 0;
// Stop if we find the non-failed APN.
- if (mWaitingApns.get(index).permanentFailed == false) break;
+ if (!mWaitingApns.get(index).getPermanentFailed()) {
+ break;
+ }
// If we've already cycled through all the APNs, that means all APNs have
// permanently failed
@@ -594,7 +597,7 @@
* */
public void markApnPermanentFailed(ApnSetting apn) {
if (apn != null) {
- apn.permanentFailed = true;
+ apn.setPermanentFailed(true);
}
}
@@ -627,7 +630,7 @@
configureRetry();
for (ApnSetting apn : mWaitingApns) {
- apn.permanentFailed = false;
+ apn.setPermanentFailed(false);
}
log("Setting " + mWaitingApns.size() + " waiting APNs.");
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 5952c19..1e5afc7 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -628,7 +628,7 @@
* Send an SMS PDU. Usually just calls {@link sendRawPdu}.
*/
private void sendSubmitPdu(SmsTracker tracker) {
- if (shouldBlockSms()) {
+ if (shouldBlockSmsForEcbm()) {
Rlog.d(TAG, "Block SMS in Emergency Callback mode");
tracker.onFailed(mContext, SmsManager.RESULT_ERROR_NO_SERVICE, 0/*errorCode*/);
} else {
@@ -637,9 +637,9 @@
}
/**
- * @return true if MO SMS should be blocked.
+ * @return true if MO SMS should be blocked for Emergency Callback Mode.
*/
- protected abstract boolean shouldBlockSms();
+ protected abstract boolean shouldBlockSmsForEcbm();
/**
* Called when SMS send completes. Broadcasts a sentIntent on success.
@@ -1454,7 +1454,13 @@
// fields need to be public for derived SmsDispatchers
private final HashMap<String, Object> mData;
public int mRetryCount;
- public int mImsRetry; // nonzero indicates initial message was sent over Ims
+ // IMS retry counter. Nonzero indicates initial message was sent over IMS channel in RIL and
+ // counts how many retries have been made on the IMS channel.
+ // Used in older implementations where the message is sent over IMS using the RIL.
+ public int mImsRetry;
+ // Tag indicating that this SMS is being handled by the ImsSmsDispatcher. This tracker
+ // should not try to use SMS over IMS over the RIL interface in this case when falling back.
+ public boolean mUsesImsServiceForIms;
public int mMessageRef;
public boolean mExpectMore;
public int mValidityPeriod;
@@ -1504,6 +1510,7 @@
mFormat = format;
mExpectMore = expectMore;
mImsRetry = 0;
+ mUsesImsServiceForIms = false;
mMessageRef = 0;
mUnsentPartCount = unsentPartCount;
mAnyPartFailed = anyPartFailed;
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index a90b4cb..84ec0dc 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -80,6 +80,7 @@
import android.util.Pair;
import android.util.SparseArray;
import android.util.TimeUtils;
+import android.util.TimestampedValue;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
@@ -94,7 +95,6 @@
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.util.NotificationChannelController;
-import com.android.internal.telephony.util.TimeStampedValue;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
@@ -130,6 +130,7 @@
private static final long LAST_CELL_INFO_LIST_MAX_AGE_MS = 2000;
private long mLastCellInfoListTime;
private List<CellInfo> mLastCellInfoList = null;
+ private List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = null;
private SignalStrength mSignalStrength;
@@ -581,11 +582,17 @@
}
// If we are previously in service, we need to notify that we are out of service now.
+ if (mSS != null && mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE) {
+ mNetworkDetachedRegistrants.notifyRegistrants();
+ }
+
+ // If we are previously in service, we need to notify that we are out of service now.
if (mSS != null && mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
mDetachedRegistrants.notifyRegistrants();
}
mSS = new ServiceState();
+ mSS.setStateOutOfService();
mNewSS = new ServiceState();
mLastCellInfoListTime = 0;
mLastCellInfoList = null;
@@ -670,6 +677,10 @@
mCi.unregisterForImsNetworkStateChanged(this);
mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
CARRIER_ACTION_SET_RADIO_ENABLED);
+ if (mCSST != null) {
+ mCSST.dispose();
+ mCSST = null;
+ }
}
public boolean getDesiredPowerState() {
@@ -1449,6 +1460,7 @@
+ list);
}
mPhone.notifyPhysicalChannelConfiguration(list);
+ mLastPhysicalChannelConfigList = list;
// only notify if bandwidths changed
if (RatRatcheter.updateBandwidths(getBandwidthsFromConfigs(list), mSS)) {
@@ -1648,9 +1660,9 @@
mPollingContext[0]--;
if (mPollingContext[0] == 0) {
+ mNewSS.setEmergencyOnly(mEmergencyOnly);
if (mPhone.isPhoneTypeGsm()) {
updateRoamingState();
- mNewSS.setEmergencyOnly(mEmergencyOnly);
} else {
boolean namMatch = false;
if (!isSidsAllZeros() && isHomeSid(mNewSS.getCdmaSystemId())) {
@@ -1788,10 +1800,11 @@
mNewSS.setCssIndicator(cssIndicator);
mNewSS.setRilVoiceRadioTechnology(newVoiceRat);
mNewSS.addNetworkRegistrationState(networkRegState);
- setChannelNumberFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
+ setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
//Denial reason if registrationState = 3
- int reasonForDenial = networkRegState.getReasonForDenial();
+ int reasonForDenial = networkRegState.getRejectCause();
+ mEmergencyOnly = networkRegState.isEmergencyEnabled();
if (mPhone.isPhoneTypeGsm()) {
mGsmRoaming = regCodeIsRoaming(registrationState);
@@ -1799,7 +1812,6 @@
boolean isVoiceCapable = mPhone.getContext().getResources()
.getBoolean(com.android.internal.R.bool.config_voice_capable);
- mEmergencyOnly = networkRegState.isEmergencyEnabled();
} else {
int roamingIndicator = voiceSpecificStates.roamingIndicator;
@@ -1864,11 +1876,18 @@
mNewSS.setDataRegState(serviceState);
mNewSS.setRilDataRadioTechnology(newDataRat);
mNewSS.addNetworkRegistrationState(networkRegState);
- setChannelNumberFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
+
+ // When we receive OOS reset the PhyChanConfig list so that non-return-to-idle
+ // implementers of PhyChanConfig unsol will not carry forward a CA report
+ // (2 or more cells) to a new cell if they camp for emergency service only.
+ if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) {
+ mLastPhysicalChannelConfigList = null;
+ }
+ setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
if (mPhone.isPhoneTypeGsm()) {
- mNewReasonDataDenied = networkRegState.getReasonForDenial();
+ mNewReasonDataDenied = networkRegState.getRejectCause();
mNewMaxDataCalls = dataSpecificStates.maxDataCalls;
mDataRoaming = regCodeIsRoaming(registrationState);
// Save the data roaming state reported by modem registration before resource
@@ -2003,7 +2022,22 @@
}
}
- private void setChannelNumberFromCellIdentity(ServiceState ss, CellIdentity cellIdentity) {
+ private static boolean isValidLteBandwidthKhz(int bandwidth) {
+ // Valid bandwidths, see 3gpp 36.101 sec. 5.6
+ switch (bandwidth) {
+ case 1400:
+ case 3000:
+ case 5000:
+ case 10000:
+ case 15000:
+ case 20000:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void setPhyCellInfoFromCellIdentity(ServiceState ss, CellIdentity cellIdentity) {
if (cellIdentity == null) {
if (DBG) {
log("Could not set ServiceState channel number. CellIdentity null");
@@ -2015,6 +2049,49 @@
if (VDBG) {
log("Setting channel number: " + cellIdentity.getChannelNumber());
}
+
+ if (cellIdentity instanceof CellIdentityLte) {
+ CellIdentityLte cl = (CellIdentityLte) cellIdentity;
+ int[] bandwidths = null;
+ // Prioritize the PhysicalChannelConfig list because we might already be in carrier
+ // aggregation by the time poll state is performed.
+ if (!ArrayUtils.isEmpty(mLastPhysicalChannelConfigList)) {
+ bandwidths = getBandwidthsFromConfigs(mLastPhysicalChannelConfigList);
+ for (int bw : bandwidths) {
+ if (!isValidLteBandwidthKhz(bw)) {
+ loge("Invalid LTE Bandwidth in RegistrationState, " + bw);
+ bandwidths = null;
+ break;
+ }
+ }
+ }
+ // If we don't have a PhysicalChannelConfig[] list, then pull from CellIdentityLte.
+ // This is normal if we're in idle mode and the PhysicalChannelConfig[] has already
+ // been updated. This is also a fallback in case the PhysicalChannelConfig info
+ // is invalid (ie, broken).
+ // Also, for vendor implementations that do not report return-to-idle, we should
+ // prioritize the bandwidth report in the CellIdentity, because the physical channel
+ // config report may be stale in the case where a single carrier was used previously
+ // and we transition to camped-for-emergency (since we never have a physical
+ // channel active). In the normal case of single-carrier non-return-to-idle, the
+ // values *must* be the same, so it doesn't matter which is chosen.
+ if (bandwidths == null || bandwidths.length == 1) {
+ final int cbw = cl.getBandwidth();
+ if (isValidLteBandwidthKhz(cbw)) {
+ bandwidths = new int[] {cbw};
+ } else if (cbw == Integer.MAX_VALUE) {
+ // Bandwidth is unreported; c'est la vie. This is not an error because
+ // pre-1.2 HAL implementations do not support bandwidth reporting.
+ } else {
+ loge("Invalid LTE Bandwidth in RegistrationState, " + cbw);
+ }
+ }
+ if (bandwidths != null) {
+ ss.setCellBandwidths(bandwidths);
+ }
+ } else {
+ if (VDBG) log("Skipping bandwidth update for Non-LTE cell.");
+ }
}
/**
@@ -2154,8 +2231,32 @@
mNewSS.setCdmaEriIconIndex(EriInfo.ROAMING_INDICATOR_OFF);
}
+ private void updateOperatorNameFromCarrierConfig() {
+ // Brand override gets a priority over carrier config. If brand override is not available,
+ // override the operator name in home network. Also do this only for CDMA. This is temporary
+ // and should be fixed in a proper way in a later release.
+ if (!mPhone.isPhoneTypeGsm() && !mSS.getRoaming()) {
+ boolean hasBrandOverride = mUiccController.getUiccCard(getPhoneId()) != null
+ && mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() != null;
+ if (!hasBrandOverride) {
+ PersistableBundle config = getCarrierConfig();
+ if (config.getBoolean(
+ CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL)) {
+ String operator = config.getString(
+ CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING);
+ log("updateOperatorNameFromCarrierConfig: changing from "
+ + mSS.getOperatorAlpha() + " to " + operator);
+ // override long and short operator name, keeping numeric the same
+ mSS.setOperatorName(operator, operator, mSS.getOperatorNumeric());
+ }
+ }
+ }
+ }
+
protected void updateSpnDisplay() {
updateOperatorNameFromEri();
+ // carrier config gets a priority over ERI
+ updateOperatorNameFromCarrierConfig();
String wfcVoiceSpnFormat = null;
String wfcDataSpnFormat = null;
@@ -2929,6 +3030,9 @@
if (hasRilDataRadioTechnologyChanged || hasRilVoiceRadioTechnologyChanged) {
logRatChange();
+
+ updateRatTypeForSignalStrength();
+ notifySignalStrength();
}
if (hasDataRegStateChanged || hasRilDataRadioTechnologyChanged) {
@@ -3454,8 +3558,8 @@
NitzData newNitzData = NitzData.parse(nitzString);
if (newNitzData != null) {
try {
- TimeStampedValue<NitzData> nitzSignal =
- new TimeStampedValue<>(newNitzData, nitzReceiveTime);
+ TimestampedValue<NitzData> nitzSignal =
+ new TimestampedValue<>(nitzReceiveTime, newNitzData);
mNitzState.handleNitzReceived(nitzSignal);
} finally {
if (DBG) {
@@ -3585,8 +3689,8 @@
return;
} else {
icon = com.android.internal.R.drawable.stat_notify_mmcc_indication_icn;
- // if using the single SIM resource, mSubId will be ignored
- title = context.getString(resId, mSubId);
+ // if using the single SIM resource, simNumber will be ignored
+ title = context.getString(resId, simNumber);
details = null;
}
break;
@@ -4024,18 +4128,6 @@
* @return true if the signal strength changed and a notification was sent.
*/
protected boolean onSignalStrengthResult(AsyncResult ar) {
- boolean isGsm = false;
- int dataRat = mSS.getRilDataRadioTechnology();
- int voiceRat = mSS.getRilVoiceRadioTechnology();
-
- // Override isGsm based on currently camped data and voice RATs
- // Set isGsm to true if the RAT belongs to GSM family and not IWLAN
- if ((dataRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
- && ServiceState.isGsm(dataRat))
- || (voiceRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
- && ServiceState.isGsm(voiceRat))) {
- isGsm = true;
- }
// This signal is used for both voice and data radio signal so parse
// all fields
@@ -4043,12 +4135,6 @@
if ((ar.exception == null) && (ar.result != null)) {
mSignalStrength = (SignalStrength) ar.result;
mSignalStrength.validateInput();
- if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN
- && voiceRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
- mSignalStrength.fixType();
- } else {
- mSignalStrength.setGsm(isGsm);
- }
mSignalStrength.setLteRsrpBoost(mSS.getLteEarfcnRsrpBoost());
PersistableBundle config = getCarrierConfig();
@@ -4062,14 +4148,39 @@
CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY));
} else {
log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
- mSignalStrength = new SignalStrength(isGsm);
+ mSignalStrength = new SignalStrength(true);
}
+ updateRatTypeForSignalStrength();
boolean ssChanged = notifySignalStrength();
return ssChanged;
}
+ private void updateRatTypeForSignalStrength() {
+ if (mSignalStrength != null) {
+ boolean isGsm = false;
+ int dataRat = mSS.getRilDataRadioTechnology();
+ int voiceRat = mSS.getRilVoiceRadioTechnology();
+
+ // Override isGsm based on currently camped data and voice RATs
+ // Set isGsm to true if the RAT belongs to GSM family and not IWLAN
+ if ((dataRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
+ && ServiceState.isGsm(dataRat))
+ || (voiceRat != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
+ && ServiceState.isGsm(voiceRat))) {
+ isGsm = true;
+ }
+
+ if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN
+ && voiceRat == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
+ mSignalStrength.fixType();
+ } else {
+ mSignalStrength.setGsm(isGsm);
+ }
+ }
+ }
+
/**
* Hang up all voice call and turn off radio. Implemented by derived class.
*/
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index f3cd1c7..d8906e7 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -41,6 +41,8 @@
import com.android.internal.telephony.gsm.GsmInboundSmsHandler;
import com.android.internal.telephony.gsm.GsmSMSDispatcher;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -449,7 +451,7 @@
PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
String callingPkg, boolean persistMessage, int priority,
boolean expectMore, int validityPeriod) {
- if (mImsSmsDispatcher.isAvailable()) {
+ if (mImsSmsDispatcher.isAvailable() || mImsSmsDispatcher.isEmergencySmsSupport(destAddr)) {
mImsSmsDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent,
messageUri, callingPkg, persistMessage, SMS_MESSAGE_PRIORITY_NOT_SPECIFIED,
false /*expectMore*/, SMS_MESSAGE_PERIOD_NOT_SPECIFIED);
@@ -627,4 +629,9 @@
public interface SmsInjectionCallback {
void onSmsInjectedResult(int result);
}
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mGsmInboundSmsHandler.dump(fd, pw, args);
+ mCdmaInboundSmsHandler.dump(fd, pw, args);
+ }
}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 1f81569..dc8d9fa 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -66,10 +66,18 @@
}
/**
+ * Sets the NitzStateMachine implementation to use during implementation. This boolean
+ * should be removed once the new implementation is stable.
+ */
+ static final boolean USE_NEW_NITZ_STATE_MACHINE = true;
+
+ /**
* Returns a new {@link NitzStateMachine} instance.
*/
public NitzStateMachine makeNitzStateMachine(GsmCdmaPhone phone) {
- return new OldNitzStateMachine(phone);
+ return USE_NEW_NITZ_STATE_MACHINE
+ ? new NewNitzStateMachine(phone)
+ : new OldNitzStateMachine(phone);
}
public SimActivationTracker makeSimActivationTracker(Phone phone) {
@@ -104,8 +112,8 @@
* Create a new UiccProfile object.
*/
public UiccProfile makeUiccProfile(Context context, CommandsInterface ci, IccCardStatus ics,
- int phoneId, UiccCard uiccCard) {
- return new UiccProfile(context, ci, ics, phoneId, uiccCard);
+ int phoneId, UiccCard uiccCard, Object lock) {
+ return new UiccProfile(context, ci, ics, phoneId, uiccCard, lock);
}
public EriManager makeEriManager(Phone phone, Context context, int eriFileSource) {
diff --git a/src/java/com/android/internal/telephony/UiccSmsController.java b/src/java/com/android/internal/telephony/UiccSmsController.java
index 59449b8..b888c7f 100644
--- a/src/java/com/android/internal/telephony/UiccSmsController.java
+++ b/src/java/com/android/internal/telephony/UiccSmsController.java
@@ -24,7 +24,6 @@
import android.content.Context;
import android.net.Uri;
import android.os.Binder;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Telephony.Sms.Intents;
import android.telephony.Rlog;
@@ -33,13 +32,17 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
* UiccSmsController to provide an inter-process communication to
* access Sms in Icc.
*/
-public class UiccSmsController extends ISms.Stub {
+public class UiccSmsController extends ISmsBaseImpl {
static final String LOG_TAG = "RIL_UiccSmsController";
protected UiccSmsController() {
@@ -59,7 +62,7 @@
@Override
public boolean
updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status,
- byte[] pdu) throws android.os.RemoteException {
+ byte[] pdu) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null) {
return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu);
@@ -72,7 +75,7 @@
@Override
public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status,
- byte[] pdu, byte[] smsc) throws android.os.RemoteException {
+ byte[] pdu, byte[] smsc) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null) {
return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc);
@@ -84,8 +87,7 @@
}
@Override
- public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage)
- throws android.os.RemoteException {
+ public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null) {
return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage);
@@ -176,7 +178,7 @@
public void sendMultipartText(String callingPackage, String destAddr, String scAddr,
List<String> parts, List<PendingIntent> sentIntents,
- List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
+ List<PendingIntent> deliveryIntents) {
sendMultipartTextForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr,
scAddr, parts, sentIntents, deliveryIntents,
true /* persistMessageForNonDefaultSmsApp */);
@@ -185,8 +187,7 @@
@Override
public void sendMultipartTextForSubscriber(int subId, String callingPackage, String destAddr,
String scAddr, List<String> parts, List<PendingIntent> sentIntents,
- List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp)
- throws android.os.RemoteException {
+ List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null ) {
iccSmsIntMgr.sendMultipartText(callingPackage, destAddr, scAddr, parts, sentIntents,
@@ -215,15 +216,14 @@
}
@Override
- public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)
- throws android.os.RemoteException {
+ public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) {
return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
ranType);
}
@Override
public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
- int endMessageId, int ranType) throws android.os.RemoteException {
+ int endMessageId, int ranType) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null ) {
return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType);
@@ -235,15 +235,15 @@
}
@Override
- public boolean disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)
- throws android.os.RemoteException {
+ public boolean disableCellBroadcastForSubscriber(int subId,
+ int messageIdentifier, int ranType) {
return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
ranType);
}
@Override
public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
- int endMessageId, int ranType) throws android.os.RemoteException {
+ int endMessageId, int ranType) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null ) {
return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType);
@@ -382,7 +382,7 @@
@Override
public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress,
- PendingIntent sentIntent, PendingIntent deliveryIntent) throws RemoteException {
+ PendingIntent sentIntent, PendingIntent deliveryIntent) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null) {
iccSmsIntMgr.sendStoredText(callingPkg, messageUri, scAddress, sentIntent,
@@ -395,8 +395,8 @@
@Override
public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri,
- String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)
- throws RemoteException {
+ String scAddress, List<PendingIntent> sentIntents,
+ List<PendingIntent> deliveryIntents) {
IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
if (iccSmsIntMgr != null ) {
iccSmsIntMgr.sendStoredMultipartText(callingPkg, messageUri, scAddress, sentIntents,
@@ -413,6 +413,23 @@
return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent);
}
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ IndentingPrintWriter indentingPW =
+ new IndentingPrintWriter(pw, " " /* singleIndent */);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ int subId = phone.getSubId();
+ indentingPW.println(String.format("SmsManager for subId = %d:", subId));
+ indentingPW.increaseIndent();
+ if (getIccSmsInterfaceManager(subId) != null) {
+ getIccSmsInterfaceManager(subId).dump(fd, indentingPW, args);
+ }
+ indentingPW.decreaseIndent();
+ }
+ indentingPW.flush();
+ }
+
+
private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) {
if (intent != null) {
try {
diff --git a/src/java/com/android/internal/telephony/cat/AppInterface.java b/src/java/com/android/internal/telephony/cat/AppInterface.java
index 1f2d3a0..9410b98 100755
--- a/src/java/com/android/internal/telephony/cat/AppInterface.java
+++ b/src/java/com/android/internal/telephony/cat/AppInterface.java
@@ -78,6 +78,7 @@
SEND_SS(0x11),
SEND_USSD(0x12),
SEND_SMS(0x13),
+ RUN_AT(0x34),
SEND_DTMF(0x14),
SET_UP_EVENT_LIST(0x05),
SET_UP_IDLE_MODE_TEXT(0x28),
diff --git a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 62d8869..cbad866 100644
--- a/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
+++ b/src/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -82,6 +82,8 @@
case SET_UP_IDLE_MODE_TEXT:
case SEND_DTMF:
case SEND_SMS:
+ case REFRESH:
+ case RUN_AT:
case SEND_SS:
case SEND_USSD:
mTextMsg = ((DisplayTextParams) cmdParams).mTextMsg;
@@ -121,7 +123,6 @@
mSetupEventListSettings.eventList = ((SetEventListParams) cmdParams).mEventInfo;
break;
case PROVIDE_LOCAL_INFORMATION:
- case REFRESH:
default:
break;
}
diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java
index e5f4b90..1084454 100644
--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -395,11 +395,6 @@
break;
case DISPLAY_TEXT:
break;
- case REFRESH:
- // ME side only handles refresh commands which meant to remove IDLE
- // MODE TEXT.
- cmdParams.mCmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
- break;
case SET_UP_IDLE_MODE_TEXT:
resultCode = cmdParams.mLoadIconFailed ? ResultCode.PRFRMD_ICON_NOT_DISPLAYED
: ResultCode.OK;
@@ -440,6 +435,13 @@
case GET_INPUT:
case GET_INKEY:
break;
+ case REFRESH:
+ case RUN_AT:
+ if (STK_DEFAULT.equals(((DisplayTextParams)cmdParams).mTextMsg.text)) {
+ // Remove the default text which was temporarily added and shall not be shown
+ ((DisplayTextParams)cmdParams).mTextMsg.text = null;
+ }
+ break;
case SEND_DTMF:
case SEND_SMS:
case SEND_SS:
diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index 232f808..049e668 100644
--- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
+++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -61,12 +61,6 @@
static final int LOAD_SINGLE_ICON = 1;
static final int LOAD_MULTI_ICONS = 2;
- // Command Qualifier values for refresh command
- static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00;
- static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02;
- static final int REFRESH_NAA_INIT = 0x03;
- static final int REFRESH_UICC_RESET = 0x04;
-
// Command Qualifier values for PLI command
static final int DTTZ_SETTING = 0x03;
static final int LANGUAGE_SETTING = 0x04;
@@ -188,6 +182,8 @@
break;
case SEND_DTMF:
case SEND_SMS:
+ case REFRESH:
+ case RUN_AT:
case SEND_SS:
case SEND_USSD:
cmdPending = processEventNotify(cmdDet, ctlvs);
@@ -196,10 +192,6 @@
case SET_UP_CALL:
cmdPending = processSetupCall(cmdDet, ctlvs);
break;
- case REFRESH:
- processRefresh(cmdDet, ctlvs);
- cmdPending = false;
- break;
case LAUNCH_BROWSER:
cmdPending = processLaunchBrowser(cmdDet, ctlvs);
break;
@@ -585,32 +577,6 @@
}
/**
- * Processes REFRESH proactive command from the SIM card.
- *
- * @param cmdDet Command Details container object.
- * @param ctlvs List of ComprehensionTlv objects following Command Details
- * object and Device Identities object within the proactive command
- */
- private boolean processRefresh(CommandDetails cmdDet,
- List<ComprehensionTlv> ctlvs) {
-
- CatLog.d(this, "process Refresh");
-
- // REFRESH proactive command is rerouted by the baseband and handled by
- // the telephony layer. IDLE TEXT should be removed for a REFRESH command
- // with "initialization" or "reset"
- switch (cmdDet.commandQualifier) {
- case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE:
- case REFRESH_NAA_INIT_AND_FILE_CHANGE:
- case REFRESH_NAA_INIT:
- case REFRESH_UICC_RESET:
- mCmdParams = new DisplayTextParams(cmdDet, null);
- break;
- }
- return false;
- }
-
- /**
* Processes SELECT_ITEM proactive command from the SIM card.
*
* @param cmdDet Command Details container object.
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index 5a40c4e..e2c178a 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -20,7 +20,6 @@
import android.content.Context;
import android.content.res.Resources;
import android.os.Message;
-import android.os.SystemProperties;
import android.provider.Telephony.Sms.Intents;
import android.telephony.SmsCbMessage;
@@ -33,7 +32,6 @@
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SmsStorageMonitor;
import com.android.internal.telephony.TelephonyComponentFactory;
-import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.WspTypeDecoder;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.util.HexDump;
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index f000caa..bbaa3ca 100755
--- a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -16,12 +16,7 @@
package com.android.internal.telephony.cdma;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Intent;
import android.os.Message;
-import android.provider.Telephony.Sms;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -73,8 +68,9 @@
}
@Override
- protected boolean shouldBlockSms() {
- return SMSDispatcherUtil.shouldBlockSms(isCdmaMo(), mPhone);
+ protected boolean shouldBlockSmsForEcbm() {
+ // We only block outgoing SMS during ECBM when using CDMA.
+ return mPhone.isInEcm() && isCdmaMo() && !isIms();
}
@Override
@@ -123,6 +119,7 @@
+ " mRetryCount=" + tracker.mRetryCount
+ " mImsRetry=" + tracker.mImsRetry
+ " mMessageRef=" + tracker.mMessageRef
+ + " mUsesImsServiceForIms=" + tracker.mUsesImsServiceForIms
+ " SS=" + mPhone.getServiceState().getState());
int ss = mPhone.getServiceState().getState();
@@ -146,8 +143,11 @@
// sms over cdma is used:
// if sms over IMS is not supported AND
// this is not a retry case after sms over IMS failed
- // indicated by mImsRetry > 0
- if (0 == tracker.mImsRetry && !isIms() || imsSmsDisabled) {
+ // indicated by mImsRetry > 0 OR
+ // SMS over IMS is disabled because of the network type OR
+ // SMS over IMS is being handled by the ImsSmsDispatcher implementation and has indicated
+ // that the message should fall back to sending over CS.
+ if (0 == tracker.mImsRetry && !isIms() || imsSmsDisabled || tracker.mUsesImsServiceForIms) {
mCi.sendCdmaSms(pdu, reply);
} else {
mCi.sendImsCdmaSms(pdu, tracker.mImsRetry, tracker.mMessageRef, reply);
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index 1b42d4a..f068acd 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -22,6 +22,8 @@
import android.net.NetworkConfig;
import android.net.NetworkRequest;
import android.telephony.Rlog;
+import android.telephony.data.ApnSetting;
+import android.telephony.data.ApnSetting.ApnType;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.SparseIntArray;
@@ -29,7 +31,6 @@
import com.android.internal.R;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RetryManager;
import com.android.internal.util.IndentingPrintWriter;
@@ -129,6 +130,14 @@
}
/**
+ * Gets the APN type bitmask.
+ * @return The APN type bitmask
+ */
+ public int getApnTypeBitmask() {
+ return ApnSetting.getApnTypesBitmaskFromString(mApnType);
+ }
+
+ /**
* Get the data call async channel.
* @return The data call async channel
*/
@@ -392,8 +401,8 @@
String provisioningApn = mPhone.getContext().getResources()
.getString(R.string.mobile_provisioning_apn);
if (!TextUtils.isEmpty(provisioningApn) &&
- (mApnSetting != null) && (mApnSetting.apn != null)) {
- return (mApnSetting.apn.equals(provisioningApn));
+ (mApnSetting != null) && (mApnSetting.getApnName() != null)) {
+ return (mApnSetting.getApnName().equals(provisioningApn));
} else {
return false;
}
@@ -418,7 +427,7 @@
} else {
mLocalLogs.add(log);
mNetworkRequests.add(networkRequest);
- mDcTracker.setEnabled(apnIdForApnName(mApnType), true);
+ mDcTracker.setEnabled(ApnSetting.getApnTypesBitmaskFromString(mApnType), true);
}
}
}
@@ -438,7 +447,7 @@
log.log("ApnContext.releaseNetwork left with " + mNetworkRequests.size() +
" requests.");
if (mNetworkRequests.size() == 0) {
- mDcTracker.setEnabled(apnIdForApnName(mApnType), false);
+ mDcTracker.setEnabled(ApnSetting.getApnTypesBitmaskFromString(mApnType), false);
}
}
}
@@ -540,88 +549,78 @@
return mRetryManager.getRetryAfterDisconnectDelay();
}
- public static int apnIdForType(int networkType) {
+ public static int getApnTypeFromNetworkType(int networkType) {
switch (networkType) {
- case ConnectivityManager.TYPE_MOBILE:
- return DctConstants.APN_DEFAULT_ID;
- case ConnectivityManager.TYPE_MOBILE_MMS:
- return DctConstants.APN_MMS_ID;
- case ConnectivityManager.TYPE_MOBILE_SUPL:
- return DctConstants.APN_SUPL_ID;
- case ConnectivityManager.TYPE_MOBILE_DUN:
- return DctConstants.APN_DUN_ID;
- case ConnectivityManager.TYPE_MOBILE_FOTA:
- return DctConstants.APN_FOTA_ID;
- case ConnectivityManager.TYPE_MOBILE_IMS:
- return DctConstants.APN_IMS_ID;
- case ConnectivityManager.TYPE_MOBILE_CBS:
- return DctConstants.APN_CBS_ID;
- case ConnectivityManager.TYPE_MOBILE_IA:
- return DctConstants.APN_IA_ID;
- case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
- return DctConstants.APN_EMERGENCY_ID;
- default:
- return DctConstants.APN_INVALID_ID;
+ case ConnectivityManager.TYPE_MOBILE:
+ return ApnSetting.TYPE_DEFAULT;
+ case ConnectivityManager.TYPE_MOBILE_MMS:
+ return ApnSetting.TYPE_MMS;
+ case ConnectivityManager.TYPE_MOBILE_SUPL:
+ return ApnSetting.TYPE_SUPL;
+ case ConnectivityManager.TYPE_MOBILE_DUN:
+ return ApnSetting.TYPE_DUN;
+ case ConnectivityManager.TYPE_MOBILE_FOTA:
+ return ApnSetting.TYPE_FOTA;
+ case ConnectivityManager.TYPE_MOBILE_IMS:
+ return ApnSetting.TYPE_IMS;
+ case ConnectivityManager.TYPE_MOBILE_CBS:
+ return ApnSetting.TYPE_CBS;
+ case ConnectivityManager.TYPE_MOBILE_IA:
+ return ApnSetting.TYPE_IA;
+ case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
+ return ApnSetting.TYPE_EMERGENCY;
+ default:
+ return ApnSetting.TYPE_NONE;
}
}
- public static int apnIdForNetworkRequest(NetworkRequest nr) {
+ static @ApnType int getApnTypeFromNetworkRequest(NetworkRequest nr) {
NetworkCapabilities nc = nr.networkCapabilities;
// For now, ignore the bandwidth stuff
if (nc.getTransportTypes().length > 0 &&
nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
- return DctConstants.APN_INVALID_ID;
+ return ApnSetting.TYPE_NONE;
}
// in the near term just do 1-1 matches.
// TODO - actually try to match the set of capabilities
- int apnId = DctConstants.APN_INVALID_ID;
+ int apnType = ApnSetting.TYPE_NONE;
boolean error = false;
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- apnId = DctConstants.APN_DEFAULT_ID;
+ apnType = ApnSetting.TYPE_DEFAULT;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_MMS_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_MMS;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_SUPL_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_SUPL;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_DUN_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_DUN;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_FOTA_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_FOTA;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_IMS_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_IMS;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_CBS_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_CBS;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_IA_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
-
- Rlog.d(SLOG_TAG, "RCS APN type not yet supported");
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
-
- Rlog.d(SLOG_TAG, "XCAP APN type not yet supported");
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_IA;
}
if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
- if (apnId != DctConstants.APN_INVALID_ID) error = true;
- apnId = DctConstants.APN_EMERGENCY_ID;
+ if (apnType != ApnSetting.TYPE_NONE) error = true;
+ apnType = ApnSetting.TYPE_EMERGENCY;
}
if (error) {
// TODO: If this error condition is removed, the framework's handling of
@@ -630,66 +629,10 @@
// NetworkCapabilities.maybeMarkCapabilitiesRestricted currently works.
Rlog.d(SLOG_TAG, "Multiple apn types specified in request - result is unspecified!");
}
- if (apnId == DctConstants.APN_INVALID_ID) {
+ if (apnType == ApnSetting.TYPE_NONE) {
Rlog.d(SLOG_TAG, "Unsupported NetworkRequest in Telephony: nr=" + nr);
}
- return apnId;
- }
-
- // TODO - kill The use of these strings
- public static int apnIdForApnName(String type) {
- switch (type) {
- case PhoneConstants.APN_TYPE_DEFAULT:
- return DctConstants.APN_DEFAULT_ID;
- case PhoneConstants.APN_TYPE_MMS:
- return DctConstants.APN_MMS_ID;
- case PhoneConstants.APN_TYPE_SUPL:
- return DctConstants.APN_SUPL_ID;
- case PhoneConstants.APN_TYPE_DUN:
- return DctConstants.APN_DUN_ID;
- case PhoneConstants.APN_TYPE_HIPRI:
- return DctConstants.APN_HIPRI_ID;
- case PhoneConstants.APN_TYPE_IMS:
- return DctConstants.APN_IMS_ID;
- case PhoneConstants.APN_TYPE_FOTA:
- return DctConstants.APN_FOTA_ID;
- case PhoneConstants.APN_TYPE_CBS:
- return DctConstants.APN_CBS_ID;
- case PhoneConstants.APN_TYPE_IA:
- return DctConstants.APN_IA_ID;
- case PhoneConstants.APN_TYPE_EMERGENCY:
- return DctConstants.APN_EMERGENCY_ID;
- default:
- return DctConstants.APN_INVALID_ID;
- }
- }
-
- private static String apnNameForApnId(int id) {
- switch (id) {
- case DctConstants.APN_DEFAULT_ID:
- return PhoneConstants.APN_TYPE_DEFAULT;
- case DctConstants.APN_MMS_ID:
- return PhoneConstants.APN_TYPE_MMS;
- case DctConstants.APN_SUPL_ID:
- return PhoneConstants.APN_TYPE_SUPL;
- case DctConstants.APN_DUN_ID:
- return PhoneConstants.APN_TYPE_DUN;
- case DctConstants.APN_HIPRI_ID:
- return PhoneConstants.APN_TYPE_HIPRI;
- case DctConstants.APN_IMS_ID:
- return PhoneConstants.APN_TYPE_IMS;
- case DctConstants.APN_FOTA_ID:
- return PhoneConstants.APN_TYPE_FOTA;
- case DctConstants.APN_CBS_ID:
- return PhoneConstants.APN_TYPE_CBS;
- case DctConstants.APN_IA_ID:
- return PhoneConstants.APN_TYPE_IA;
- case DctConstants.APN_EMERGENCY_ID:
- return PhoneConstants.APN_TYPE_EMERGENCY;
- default:
- Rlog.d(SLOG_TAG, "Unknown id (" + id + ") in apnIdToType");
- return PhoneConstants.APN_TYPE_DEFAULT;
- }
+ return apnType;
}
@Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnSetting.java b/src/java/com/android/internal/telephony/dataconnection/ApnSetting.java
deleted file mode 100644
index 6f1c8a6..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/ApnSetting.java
+++ /dev/null
@@ -1,832 +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.dataconnection;
-
-import android.content.Context;
-import android.hardware.radio.V1_0.ApnTypes;
-import android.os.PersistableBundle;
-import android.provider.Telephony.Carriers;
-import android.telephony.CarrierConfigManager;
-import android.telephony.Rlog;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.uicc.IccRecords;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * This class represents a apn setting for create PDP link
- */
-public class ApnSetting {
-
- static final String LOG_TAG = "ApnSetting";
-
- private static final boolean DBG = false;
- private static final boolean VDBG = false;
-
- static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*";
- static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*";
- static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*";
- static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*";
- static final String TAG = "ApnSetting";
-
- public final String carrier;
- public final String apn;
- public final String proxy;
- public final String port;
- public final String mmsc;
- public final String mmsProxy;
- public final String mmsPort;
- public final String user;
- public final String password;
- public final int authType;
- public final String[] types;
- public final int typesBitmap;
- public final int id;
- public final String numeric;
- public final String protocol;
- public final String roamingProtocol;
- public final int mtu;
-
- /**
- * Current status of APN
- * true : enabled APN, false : disabled APN.
- */
- public final boolean carrierEnabled;
- /**
- * Radio Access Technology info
- * To check what values can hold, refer to ServiceState.java.
- * This should be spread to other technologies,
- * but currently only used for LTE(14) and EHRPD(13).
- *
- * @deprecated use {@code networkTypeBitmask} instead
- */
- @Deprecated
- private final int bearer;
- /**
- * Radio Access Technology info
- * To check what values can hold, refer to ServiceState.java. This is a bitmask of radio
- * technologies in ServiceState.
- * This should be spread to other technologies,
- * but currently only used for LTE(14) and EHRPD(13).
- *
- * @deprecated use {@code networkTypeBitmask} instead
- */
- @Deprecated
- public final int bearerBitmask;
-
- /**
- * Radio Technology (Network Type) info
- * To check what values can hold, refer to TelephonyManager.java. This is a bitmask of radio
- * technologies ({@code NETWORK_TYPE_} constants) in {@link TelephonyManager}.
- */
- public final int networkTypeBitmask;
-
- /* ID of the profile in the modem */
- public final int profileId;
- public final boolean modemCognitive;
- public final int maxConns;
- public final int waitTime;
- public final int maxConnsTime;
-
- /**
- * MVNO match type. Possible values:
- * "spn": Service provider name.
- * "imsi": IMSI.
- * "gid": Group identifier level 1.
- * "iccid": ICCID
- */
- public final String mvnoType;
- /**
- * MVNO data. Examples:
- * "spn": A MOBILE, BEN NL
- * "imsi": 302720x94, 2060188
- * "gid": 4E, 33
- * "iccid": 898603 etc.
- */
- public final String mvnoMatchData;
-
- /**
- * The APN set id.
- *
- * APNs that are part of the same set should be preferred together, e.g. if the
- * user selects a default APN with apnSetId=1, then we will prefer all APNs with apnSetId=1.
- *
- * If the apnSetId=Carriers.NO_SET_SET (=0) then the APN is not part of a set.
- */
- public final int apnSetId;
-
- /**
- * Indicates this APN setting is permanently failed and cannot be
- * retried by the retry manager anymore.
- * */
- public boolean permanentFailed = false;
-
- /**
- * @deprecated this constructor is no longer supported. Use the other constructor which takes
- * a network type bitmask instead of the deprecated bearer bitmask and bearer field.
- * */
- @Deprecated
- public ApnSetting(int id, String numeric, String carrier, String apn,
- String proxy, String port,
- String mmsc, String mmsProxy, String mmsPort,
- String user, String password, int authType, String[] types,
- String protocol, String roamingProtocol, boolean carrierEnabled, int bearer,
- int bearerBitmask, int profileId, boolean modemCognitive, int maxConns,
- int waitTime, int maxConnsTime, int mtu, String mvnoType,
- String mvnoMatchData) {
- this.id = id;
- this.numeric = numeric;
- this.carrier = carrier;
- this.apn = apn;
- this.proxy = proxy;
- this.port = port;
- this.mmsc = mmsc;
- this.mmsProxy = mmsProxy;
- this.mmsPort = mmsPort;
- this.user = user;
- this.password = password;
- this.authType = authType;
- this.types = new String[types.length];
- int apnBitmap = 0;
- for (int i = 0; i < types.length; i++) {
- this.types[i] = types[i].toLowerCase();
- apnBitmap |= getApnBitmask(this.types[i]);
- }
- this.typesBitmap = apnBitmap;
- this.protocol = protocol;
- this.roamingProtocol = roamingProtocol;
- this.carrierEnabled = carrierEnabled;
- this.bearer = bearer;
- this.bearerBitmask = (bearerBitmask | ServiceState.getBitmaskForTech(bearer));
- this.profileId = profileId;
- this.modemCognitive = modemCognitive;
- this.maxConns = maxConns;
- this.waitTime = waitTime;
- this.maxConnsTime = maxConnsTime;
- this.mtu = mtu;
- this.mvnoType = mvnoType;
- this.mvnoMatchData = mvnoMatchData;
- this.apnSetId = Carriers.NO_SET_SET;
- this.networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
- this.bearerBitmask);
- }
-
- // Constructor with default apn set id
- public ApnSetting(int id, String numeric, String carrier, String apn,
- String proxy, String port,
- String mmsc, String mmsProxy, String mmsPort,
- String user, String password, int authType, String[] types,
- String protocol, String roamingProtocol, boolean carrierEnabled,
- int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns,
- int waitTime, int maxConnsTime, int mtu, String mvnoType,
- String mvnoMatchData) {
- this(id, numeric, carrier, apn, proxy, port, mmsc, mmsProxy, mmsPort, user, password,
- authType, types, protocol, roamingProtocol, carrierEnabled, networkTypeBitmask,
- profileId, modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType,
- mvnoMatchData, Carriers.NO_SET_SET);
- }
-
- public ApnSetting(int id, String numeric, String carrier, String apn,
- String proxy, String port,
- String mmsc, String mmsProxy, String mmsPort,
- String user, String password, int authType, String[] types,
- String protocol, String roamingProtocol, boolean carrierEnabled,
- int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns,
- int waitTime, int maxConnsTime, int mtu, String mvnoType,
- String mvnoMatchData, int apnSetId) {
- this.id = id;
- this.numeric = numeric;
- this.carrier = carrier;
- this.apn = apn;
- this.proxy = proxy;
- this.port = port;
- this.mmsc = mmsc;
- this.mmsProxy = mmsProxy;
- this.mmsPort = mmsPort;
- this.user = user;
- this.password = password;
- this.authType = authType;
- this.types = new String[types.length];
- int apnBitmap = 0;
- for (int i = 0; i < types.length; i++) {
- this.types[i] = types[i].toLowerCase();
- apnBitmap |= getApnBitmask(this.types[i]);
- }
- this.typesBitmap = apnBitmap;
- this.protocol = protocol;
- this.roamingProtocol = roamingProtocol;
- this.carrierEnabled = carrierEnabled;
- this.bearer = 0;
- this.bearerBitmask =
- ServiceState.convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
- this.networkTypeBitmask = networkTypeBitmask;
- this.profileId = profileId;
- this.modemCognitive = modemCognitive;
- this.maxConns = maxConns;
- this.waitTime = waitTime;
- this.maxConnsTime = maxConnsTime;
- this.mtu = mtu;
- this.mvnoType = mvnoType;
- this.mvnoMatchData = mvnoMatchData;
- this.apnSetId = apnSetId;
- }
-
- public ApnSetting(ApnSetting apn) {
- this(apn.id, apn.numeric, apn.carrier, apn.apn, apn.proxy, apn.port, apn.mmsc, apn.mmsProxy,
- apn.mmsPort, apn.user, apn.password, apn.authType, apn.types, apn.protocol,
- apn.roamingProtocol, apn.carrierEnabled, apn.networkTypeBitmask, apn.profileId,
- apn.modemCognitive, apn.maxConns, apn.waitTime, apn.maxConnsTime,
- apn.mtu, apn.mvnoType, apn.mvnoMatchData, apn.apnSetId);
- }
-
- /**
- * Creates an ApnSetting object from a string.
- *
- * @param data the string to read.
- *
- * The string must be in one of two formats (newlines added for clarity,
- * spaces are optional):
- *
- * v1 format:
- * <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
- * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
- * <type>[| <type>...],
- *
- * v2 format:
- * [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
- * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
- * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
- *
- * v3 format:
- * [ApnSettingV3] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
- * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
- * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
- * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
- * <mvnoType>, <mvnoMatchData>
- *
- * v4 format:
- * [ApnSettingV4] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
- * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
- * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
- * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
- * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>
- *
- * v5 format:
- * [ApnSettingV5] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
- * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
- * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
- * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
- * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>
- *
- * Note that the strings generated by toString() do not contain the username
- * and password and thus cannot be read by this method.
- */
- public static ApnSetting fromString(String data) {
- if (data == null) return null;
-
- int version;
- // matches() operates on the whole string, so append .* to the regex.
- if (data.matches(V5_FORMAT_REGEX + ".*")) {
- version = 5;
- data = data.replaceFirst(V5_FORMAT_REGEX, "");
- } else if (data.matches(V4_FORMAT_REGEX + ".*")) {
- version = 4;
- data = data.replaceFirst(V4_FORMAT_REGEX, "");
- } else if (data.matches(V3_FORMAT_REGEX + ".*")) {
- version = 3;
- data = data.replaceFirst(V3_FORMAT_REGEX, "");
- } else if (data.matches(V2_FORMAT_REGEX + ".*")) {
- version = 2;
- data = data.replaceFirst(V2_FORMAT_REGEX, "");
- } else {
- version = 1;
- }
-
- String[] a = data.split("\\s*,\\s*");
- if (a.length < 14) {
- return null;
- }
-
- int authType;
- try {
- authType = Integer.parseInt(a[12]);
- } catch (NumberFormatException e) {
- authType = 0;
- }
-
- String[] typeArray;
- String protocol, roamingProtocol;
- boolean carrierEnabled;
- int bearerBitmask = 0;
- int networkTypeBitmask = 0;
- int profileId = 0;
- boolean modemCognitive = false;
- int maxConns = 0;
- int waitTime = 0;
- int maxConnsTime = 0;
- int mtu = PhoneConstants.UNSET_MTU;
- String mvnoType = "";
- String mvnoMatchData = "";
- int apnSetId = Carriers.NO_SET_SET;
- if (version == 1) {
- typeArray = new String[a.length - 13];
- System.arraycopy(a, 13, typeArray, 0, a.length - 13);
- protocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
- roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP;
- carrierEnabled = true;
- } else {
- if (a.length < 18) {
- return null;
- }
- typeArray = a[13].split("\\s*\\|\\s*");
- protocol = a[14];
- roamingProtocol = a[15];
- carrierEnabled = Boolean.parseBoolean(a[16]);
-
- bearerBitmask = ServiceState.getBitmaskFromString(a[17]);
-
- if (a.length > 22) {
- modemCognitive = Boolean.parseBoolean(a[19]);
- try {
- profileId = Integer.parseInt(a[18]);
- maxConns = Integer.parseInt(a[20]);
- waitTime = Integer.parseInt(a[21]);
- maxConnsTime = Integer.parseInt(a[22]);
- } catch (NumberFormatException e) {
- }
- }
- if (a.length > 23) {
- try {
- mtu = Integer.parseInt(a[23]);
- } catch (NumberFormatException e) {
- }
- }
- if (a.length > 25) {
- mvnoType = a[24];
- mvnoMatchData = a[25];
- }
- if (a.length > 26) {
- networkTypeBitmask = ServiceState.getBitmaskFromString(a[26]);
- }
- if (a.length > 27) {
- apnSetId = Integer.parseInt(a[27]);
- }
- }
-
- // If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be
- // ignored.
- if (networkTypeBitmask == 0) {
- networkTypeBitmask =
- ServiceState.convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask);
- }
- return new ApnSetting(-1, a[10] + a[11], a[0], a[1], a[2], a[3], a[7], a[8], a[9], a[4],
- a[5], authType, typeArray, protocol, roamingProtocol, carrierEnabled,
- networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime, maxConnsTime,
- mtu, mvnoType, mvnoMatchData, apnSetId);
- }
-
- /**
- * Creates an array of ApnSetting objects from a string.
- *
- * @param data the string to read.
- *
- * Builds on top of the same format used by fromString, but allows for multiple entries
- * separated by "; ".
- */
- public static List<ApnSetting> arrayFromString(String data) {
- List<ApnSetting> retVal = new ArrayList<ApnSetting>();
- if (TextUtils.isEmpty(data)) {
- return retVal;
- }
- String[] apnStrings = data.split("\\s*;\\s*");
- for (String apnString : apnStrings) {
- ApnSetting apn = fromString(apnString);
- if (apn != null) {
- retVal.add(apn);
- }
- }
- return retVal;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV5] ")
- .append(carrier)
- .append(", ").append(id)
- .append(", ").append(numeric)
- .append(", ").append(apn)
- .append(", ").append(proxy)
- .append(", ").append(mmsc)
- .append(", ").append(mmsProxy)
- .append(", ").append(mmsPort)
- .append(", ").append(port)
- .append(", ").append(authType).append(", ");
- for (int i = 0; i < types.length; i++) {
- sb.append(types[i]);
- if (i < types.length - 1) {
- sb.append(" | ");
- }
- }
- sb.append(", ").append(protocol);
- sb.append(", ").append(roamingProtocol);
- sb.append(", ").append(carrierEnabled);
- sb.append(", ").append(bearer);
- sb.append(", ").append(bearerBitmask);
- sb.append(", ").append(profileId);
- sb.append(", ").append(modemCognitive);
- sb.append(", ").append(maxConns);
- sb.append(", ").append(waitTime);
- sb.append(", ").append(maxConnsTime);
- sb.append(", ").append(mtu);
- sb.append(", ").append(mvnoType);
- sb.append(", ").append(mvnoMatchData);
- sb.append(", ").append(permanentFailed);
- sb.append(", ").append(networkTypeBitmask);
- sb.append(", ").append(apnSetId);
- return sb.toString();
- }
-
- /**
- * Returns true if there are MVNO params specified.
- */
- public boolean hasMvnoParams() {
- return !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData);
- }
-
- public boolean canHandleType(String type) {
- if (!carrierEnabled) return false;
- boolean wildcardable = true;
- if (PhoneConstants.APN_TYPE_IA.equalsIgnoreCase(type)) wildcardable = false;
- for (String t : types) {
- // DEFAULT handles all, and HIPRI is handled by DEFAULT
- if (t.equalsIgnoreCase(type) ||
- (wildcardable && t.equalsIgnoreCase(PhoneConstants.APN_TYPE_ALL)) ||
- (t.equalsIgnoreCase(PhoneConstants.APN_TYPE_DEFAULT) &&
- type.equalsIgnoreCase(PhoneConstants.APN_TYPE_HIPRI))) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean iccidMatches(String mvnoData, String iccId) {
- String[] mvnoIccidList = mvnoData.split(",");
- for (String mvnoIccid : mvnoIccidList) {
- if (iccId.startsWith(mvnoIccid)) {
- Log.d(TAG, "mvno icc id match found");
- return true;
- }
- }
- return false;
- }
-
- private static boolean imsiMatches(String imsiDB, String imsiSIM) {
- // Note: imsiDB value has digit number or 'x' character for seperating USIM information
- // for MVNO operator. And then digit number is matched at same order and 'x' character
- // could replace by any digit number.
- // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
- // that means first 6 digits, 8th and 9th digit
- // should be set in USIM for GG Operator.
- int len = imsiDB.length();
- int idxCompare = 0;
-
- if (len <= 0) return false;
- if (len > imsiSIM.length()) return false;
-
- for (int idx=0; idx<len; idx++) {
- char c = imsiDB.charAt(idx);
- if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
- continue;
- } else {
- return false;
- }
- }
- return true;
- }
-
- public static boolean mvnoMatches(IccRecords r, String mvnoType, String mvnoMatchData) {
- if (mvnoType.equalsIgnoreCase("spn")) {
- if ((r.getServiceProviderName() != null) &&
- r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) {
- return true;
- }
- } else if (mvnoType.equalsIgnoreCase("imsi")) {
- String imsiSIM = r.getIMSI();
- if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
- return true;
- }
- } else if (mvnoType.equalsIgnoreCase("gid")) {
- String gid1 = r.getGid1();
- int mvno_match_data_length = mvnoMatchData.length();
- if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) &&
- gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
- return true;
- }
- } else if (mvnoType.equalsIgnoreCase("iccid")) {
- String iccId = r.getIccId();
- if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Check if this APN type is metered.
- *
- * @param type The APN type
- * @param phone The phone object
- * @return True if the APN type is metered, otherwise false.
- */
- public static boolean isMeteredApnType(String type, Phone phone) {
- if (phone == null) {
- return true;
- }
-
- boolean isRoaming = phone.getServiceState().getDataRoaming();
- boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology()
- == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
- int subId = phone.getSubId();
-
- String carrierConfig;
- // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then
- // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use
- // the normal metered APN list.
- if (isIwlan) {
- carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS;
- } else if (isRoaming) {
- carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS;
- } else {
- carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS;
- }
-
- if (DBG) {
- Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan);
- }
-
- CarrierConfigManager configManager = (CarrierConfigManager)
- phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager == null) {
- Rlog.e(LOG_TAG, "Carrier config service is not available");
- return true;
- }
-
- PersistableBundle b = configManager.getConfigForSubId(subId);
- if (b == null) {
- Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId);
- return true;
- }
-
- String[] meteredApnTypes = b.getStringArray(carrierConfig);
- if (meteredApnTypes == null) {
- Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId);
- return true;
- }
-
- HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes));
- if (DBG) {
- Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are "
- + Arrays.toString(meteredApnSet.toArray()));
- }
-
- // If all types of APN are metered, then this APN setting must be metered.
- if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) {
- if (DBG) Rlog.d(LOG_TAG, "All APN types are metered.");
- return true;
- }
-
- if (meteredApnSet.contains(type)) {
- if (DBG) Rlog.d(LOG_TAG, type + " is metered.");
- return true;
- } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) {
- // Assuming no configuration error, if at least one APN type is
- // metered, then this APN setting is metered.
- if (meteredApnSet.size() > 0) {
- if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered.");
- return true;
- }
- }
-
- if (DBG) Rlog.d(LOG_TAG, type + " is not metered.");
- return false;
- }
-
- /**
- * Check if this APN setting is metered.
- *
- * @param phone The phone object
- * @return True if this APN setting is metered, otherwise false.
- */
- public boolean isMetered(Phone phone) {
- if (phone == null) {
- return true;
- }
-
- for (String type : types) {
- // If one of the APN type is metered, then this APN setting is metered.
- if (isMeteredApnType(type, phone)) {
- return true;
- }
- }
- return false;
- }
-
- // TODO - if we have this function we should also have hashCode.
- // Also should handle changes in type order and perhaps case-insensitivity
- @Override
- public boolean equals(Object o) {
- if (o instanceof ApnSetting == false) {
- return false;
- }
-
- ApnSetting other = (ApnSetting) o;
-
- return carrier.equals(other.carrier)
- && id == other.id
- && numeric.equals(other.numeric)
- && apn.equals(other.apn)
- && proxy.equals(other.proxy)
- && mmsc.equals(other.mmsc)
- && mmsProxy.equals(other.mmsProxy)
- && TextUtils.equals(mmsPort, other.mmsPort)
- && port.equals(other.port)
- && TextUtils.equals(user, other.user)
- && TextUtils.equals(password, other.password)
- && authType == other.authType
- && Arrays.deepEquals(types, other.types)
- && typesBitmap == other.typesBitmap
- && protocol.equals(other.protocol)
- && roamingProtocol.equals(other.roamingProtocol)
- && carrierEnabled == other.carrierEnabled
- && bearer == other.bearer
- && bearerBitmask == other.bearerBitmask
- && profileId == other.profileId
- && modemCognitive == other.modemCognitive
- && maxConns == other.maxConns
- && waitTime == other.waitTime
- && maxConnsTime == other.maxConnsTime
- && mtu == other.mtu
- && mvnoType.equals(other.mvnoType)
- && mvnoMatchData.equals(other.mvnoMatchData)
- && networkTypeBitmask == other.networkTypeBitmask
- && apnSetId == other.apnSetId;
- }
-
- /**
- * Compare two APN settings
- *
- * Note: This method does not compare 'id', 'bearer', 'bearerBitmask', 'networkTypeBitmask'.
- * We only use this for determining if tearing a data call is needed when conditions change. See
- * cleanUpConnectionsOnUpdatedApns in DcTracker.
- *
- * @param o the other object to compare
- * @param isDataRoaming True if the device is on data roaming
- * @return True if the two APN settings are same
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean equals(Object o, boolean isDataRoaming) {
- if (!(o instanceof ApnSetting)) {
- return false;
- }
-
- ApnSetting other = (ApnSetting) o;
-
- return carrier.equals(other.carrier)
- && numeric.equals(other.numeric)
- && apn.equals(other.apn)
- && proxy.equals(other.proxy)
- && mmsc.equals(other.mmsc)
- && mmsProxy.equals(other.mmsProxy)
- && TextUtils.equals(mmsPort, other.mmsPort)
- && port.equals(other.port)
- && TextUtils.equals(user, other.user)
- && TextUtils.equals(password, other.password)
- && authType == other.authType
- && Arrays.deepEquals(types, other.types)
- && typesBitmap == other.typesBitmap
- && (isDataRoaming || protocol.equals(other.protocol))
- && (!isDataRoaming || roamingProtocol.equals(other.roamingProtocol))
- && carrierEnabled == other.carrierEnabled
- && profileId == other.profileId
- && modemCognitive == other.modemCognitive
- && maxConns == other.maxConns
- && waitTime == other.waitTime
- && maxConnsTime == other.maxConnsTime
- && mtu == other.mtu
- && mvnoType.equals(other.mvnoType)
- && mvnoMatchData.equals(other.mvnoMatchData)
- && apnSetId == other.apnSetId;
- }
-
- /**
- * Check if neither mention DUN and are substantially similar
- *
- * @param other The other APN settings to compare
- * @return True if two APN settings are similar
- */
- public boolean similar(ApnSetting other) {
- return (!this.canHandleType(PhoneConstants.APN_TYPE_DUN)
- && !other.canHandleType(PhoneConstants.APN_TYPE_DUN)
- && Objects.equals(this.apn, other.apn)
- && !typeSameAny(this, other)
- && xorEquals(this.proxy, other.proxy)
- && xorEquals(this.port, other.port)
- && xorEquals(this.protocol, other.protocol)
- && xorEquals(this.roamingProtocol, other.roamingProtocol)
- && this.carrierEnabled == other.carrierEnabled
- && this.bearerBitmask == other.bearerBitmask
- && this.profileId == other.profileId
- && Objects.equals(this.mvnoType, other.mvnoType)
- && Objects.equals(this.mvnoMatchData, other.mvnoMatchData)
- && xorEquals(this.mmsc, other.mmsc)
- && xorEquals(this.mmsProxy, other.mmsProxy)
- && xorEquals(this.mmsPort, other.mmsPort))
- && this.networkTypeBitmask == other.networkTypeBitmask
- && this.apnSetId == other.apnSetId;
- }
-
- // check whether the types of two APN same (even only one type of each APN is same)
- private boolean typeSameAny(ApnSetting first, ApnSetting second) {
- if (VDBG) {
- StringBuilder apnType1 = new StringBuilder(first.apn + ": ");
- for (int index1 = 0; index1 < first.types.length; index1++) {
- apnType1.append(first.types[index1]);
- apnType1.append(",");
- }
-
- StringBuilder apnType2 = new StringBuilder(second.apn + ": ");
- for (int index1 = 0; index1 < second.types.length; index1++) {
- apnType2.append(second.types[index1]);
- apnType2.append(",");
- }
- Rlog.d(LOG_TAG, "APN1: is " + apnType1);
- Rlog.d(LOG_TAG, "APN2: is " + apnType2);
- }
-
- for (int index1 = 0; index1 < first.types.length; index1++) {
- for (int index2 = 0; index2 < second.types.length; index2++) {
- if (first.types[index1].equals(PhoneConstants.APN_TYPE_ALL)
- || second.types[index2].equals(PhoneConstants.APN_TYPE_ALL)
- || first.types[index1].equals(second.types[index2])) {
- if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return true");
- return true;
- }
- }
- }
-
- if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return false");
- return false;
- }
-
- // equal or one is not specified
- private boolean xorEquals(String first, String second) {
- return (Objects.equals(first, second)
- || TextUtils.isEmpty(first)
- || TextUtils.isEmpty(second));
- }
-
- // Helper function to convert APN string into a 32-bit bitmask.
- private static int getApnBitmask(String apn) {
- switch (apn) {
- case PhoneConstants.APN_TYPE_DEFAULT: return ApnTypes.DEFAULT;
- case PhoneConstants.APN_TYPE_MMS: return ApnTypes.MMS;
- case PhoneConstants.APN_TYPE_SUPL: return ApnTypes.SUPL;
- case PhoneConstants.APN_TYPE_DUN: return ApnTypes.DUN;
- case PhoneConstants.APN_TYPE_HIPRI: return ApnTypes.HIPRI;
- case PhoneConstants.APN_TYPE_FOTA: return ApnTypes.FOTA;
- case PhoneConstants.APN_TYPE_IMS: return ApnTypes.IMS;
- case PhoneConstants.APN_TYPE_CBS: return ApnTypes.CBS;
- case PhoneConstants.APN_TYPE_IA: return ApnTypes.IA;
- case PhoneConstants.APN_TYPE_EMERGENCY: return ApnTypes.EMERGENCY;
- case PhoneConstants.APN_TYPE_ALL: return ApnTypes.ALL;
- default: return ApnTypes.NONE;
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java b/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
new file mode 100644
index 0000000..e9a6fc8
--- /dev/null
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2018 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.dataconnection;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.Rlog;
+import android.telephony.ServiceState;
+import android.telephony.data.ApnSetting;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.uicc.IccRecords;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+/**
+ * This class represents a apn setting for create PDP link
+ */
+public class ApnSettingUtils {
+
+ static final String LOG_TAG = "ApnSetting";
+
+ private static final boolean DBG = false;
+
+ private static boolean iccidMatches(String mvnoData, String iccId) {
+ String[] mvnoIccidList = mvnoData.split(",");
+ for (String mvnoIccid : mvnoIccidList) {
+ if (iccId.startsWith(mvnoIccid)) {
+ Log.d(LOG_TAG, "mvno icc id match found");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean imsiMatches(String imsiDB, String imsiSIM) {
+ // Note: imsiDB value has digit number or 'x' character for seperating USIM information
+ // for MVNO operator. And then digit number is matched at same order and 'x' character
+ // could replace by any digit number.
+ // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
+ // that means first 6 digits, 8th and 9th digit
+ // should be set in USIM for GG Operator.
+ int len = imsiDB.length();
+
+ if (len <= 0) return false;
+ if (len > imsiSIM.length()) return false;
+
+ for (int idx = 0; idx < len; idx++) {
+ char c = imsiDB.charAt(idx);
+ if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
+ continue;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check if MVNO type and data match IccRecords.
+ *
+ * @param r the IccRecords
+ * @param mvnoType the MVNO type
+ * @param mvnoMatchData the MVNO match data
+ * @return {@code true} if MVNO type and data match IccRecords, {@code false} otherwise.
+ */
+ public static boolean mvnoMatches(IccRecords r, int mvnoType, String mvnoMatchData) {
+ if (mvnoType == ApnSetting.MVNO_TYPE_SPN) {
+ if ((r.getServiceProviderName() != null)
+ && r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) {
+ return true;
+ }
+ } else if (mvnoType == ApnSetting.MVNO_TYPE_IMSI) {
+ String imsiSIM = r.getIMSI();
+ if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
+ return true;
+ }
+ } else if (mvnoType == ApnSetting.MVNO_TYPE_GID) {
+ String gid1 = r.getGid1();
+ int mvno_match_data_length = mvnoMatchData.length();
+ if ((gid1 != null) && (gid1.length() >= mvno_match_data_length)
+ && gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
+ return true;
+ }
+ } else if (mvnoType == ApnSetting.MVNO_TYPE_ICCID) {
+ String iccId = r.getIccId();
+ if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if this APN type is metered.
+ *
+ * @param type the APN type
+ * @param phone the phone object
+ * @return {@code true} if the APN type is metered, {@code false} otherwise.
+ */
+ public static boolean isMeteredApnType(String type, Phone phone) {
+ if (phone == null) {
+ return true;
+ }
+
+ boolean isRoaming = phone.getServiceState().getDataRoaming();
+ boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology()
+ == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
+ int subId = phone.getSubId();
+
+ String carrierConfig;
+ // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then
+ // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use
+ // the normal metered APN list.
+ if (isIwlan) {
+ carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS;
+ } else if (isRoaming) {
+ carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS;
+ } else {
+ carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS;
+ }
+
+ if (DBG) {
+ Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan);
+ }
+
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager == null) {
+ Rlog.e(LOG_TAG, "Carrier config service is not available");
+ return true;
+ }
+
+ PersistableBundle b = configManager.getConfigForSubId(subId);
+ if (b == null) {
+ Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId);
+ return true;
+ }
+
+ String[] meteredApnTypes = b.getStringArray(carrierConfig);
+ if (meteredApnTypes == null) {
+ Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId);
+ return true;
+ }
+
+ HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes));
+ if (DBG) {
+ Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are "
+ + Arrays.toString(meteredApnSet.toArray()));
+ }
+
+ // If all types of APN are metered, then this APN setting must be metered.
+ if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) {
+ if (DBG) Rlog.d(LOG_TAG, "All APN types are metered.");
+ return true;
+ }
+
+ if (meteredApnSet.contains(type)) {
+ if (DBG) Rlog.d(LOG_TAG, type + " is metered.");
+ return true;
+ } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) {
+ // Assuming no configuration error, if at least one APN type is
+ // metered, then this APN setting is metered.
+ if (meteredApnSet.size() > 0) {
+ if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered.");
+ return true;
+ }
+ }
+
+ if (DBG) Rlog.d(LOG_TAG, type + " is not metered.");
+ return false;
+ }
+
+ /**
+ * Check if this APN setting is metered.
+ *
+ * @param phone The phone object
+ * @return True if this APN setting is metered, otherwise false.
+ */
+ public static boolean isMetered(ApnSetting apn, Phone phone) {
+ if (phone == null) {
+ return true;
+ }
+
+ String[] types = ApnSetting.getApnTypesStringFromBitmask(
+ apn.getApnTypeBitmask()).split(",");
+
+ for (String type : types) {
+ // If one of the APN type is metered, then this APN setting is metered.
+ if (isMeteredApnType(type, phone)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 83ca909..00af9fe 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -43,6 +43,7 @@
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
@@ -443,9 +444,9 @@
return;
}
- if (apn != null && apn.mtu != PhoneConstants.UNSET_MTU) {
- lp.setMtu(apn.mtu);
- if (DBG) log("MTU set by APN to: " + apn.mtu);
+ if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) {
+ lp.setMtu(apn.getMtu());
+ if (DBG) log("MTU set by APN to: " + apn.getMtu());
return;
}
@@ -502,9 +503,12 @@
* @param cp is the connection parameters
*/
private void onConnect(ConnectionParams cp) {
- if (DBG) log("onConnect: carrier='" + mApnSetting.carrier
- + "' APN='" + mApnSetting.apn
- + "' proxy='" + mApnSetting.proxy + "' port='" + mApnSetting.port + "'");
+ if (DBG) {
+ log("onConnect: carrier='" + mApnSetting.getEntryName()
+ + "' APN='" + mApnSetting.getApnName()
+ + "' proxy='" + mApnSetting.getProxyAddressAsString()
+ + "' port='" + mApnSetting.getProxyPort() + "'");
+ }
if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.onConnect");
// Check if we should fake an error.
@@ -783,12 +787,12 @@
// Do not apply the race condition workaround for MMS APN
// if Proxy is an IP-address.
// Otherwise, the default APN will not be restored anymore.
- if (!mApnSetting.types[0].equals(PhoneConstants.APN_TYPE_MMS)
- || !isIpAddress(mApnSetting.mmsProxy)) {
+ if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) {
log(String.format(
- "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s",
- mApnSetting.types[0], PhoneConstants.APN_TYPE_MMS, mApnSetting.mmsProxy,
- isIpAddress(mApnSetting.mmsProxy)));
+ "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s",
+ mApnSetting.getApnTypeBitmask(), PhoneConstants.APN_TYPE_MMS,
+ mApnSetting.getMmsProxyAddressAsString(),
+ isIpAddress(mApnSetting.getMmsProxyAddressAsString())));
return false;
}
}
@@ -922,7 +926,7 @@
// Do we need a restricted network to satisfy the request?
// Is this network metered? If not, then don't add restricted
- if (!mApnSetting.isMetered(mPhone)) {
+ if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
return;
}
@@ -935,10 +939,12 @@
result.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
if (mApnSetting != null) {
- for (String type : mApnSetting.types) {
+ final String[] types = ApnSetting.getApnTypesStringFromBitmask(
+ mApnSetting.getApnTypeBitmask()).split(",");
+ for (String type : types) {
if (!mRestrictedNetworkOverride
&& (mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly)
- && ApnSetting.isMeteredApnType(type, mPhone)) {
+ && ApnSettingUtils.isMeteredApnType(type, mPhone)) {
log("Dropped the metered " + type + " for the unmetered data call.");
continue;
}
@@ -999,7 +1005,7 @@
// 2. The non-restricted data and is intended for unmetered use only.
if (((mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly)
&& !mRestrictedNetworkOverride)
- || !mApnSetting.isMetered(mPhone)) {
+ || !ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
} else {
result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
@@ -1170,7 +1176,7 @@
// only NOT be set only if we're in DcInactiveState.
mApnSetting = apnContext.getApnSetting();
}
- if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnType())) {
+ if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnTypeBitmask())) {
if (DBG) {
log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp
+ " dc=" + DataConnection.this);
@@ -1683,7 +1689,7 @@
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED,
mNetworkInfo.getReason(), null);
- mNetworkInfo.setExtraInfo(mApnSetting.apn);
+ mNetworkInfo.setExtraInfo(mApnSetting.getApnName());
updateTcpBufferSizes(mRilRat);
final NetworkMisc misc = new NetworkMisc();
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java b/src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java
index ad0b4ed..06bb7de 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcAsyncChannel.java
@@ -20,6 +20,7 @@
import android.net.NetworkCapabilities;
import android.net.ProxyInfo;
import android.os.Message;
+import android.telephony.data.ApnSetting;
import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcRequest.java b/src/java/com/android/internal/telephony/dataconnection/DcRequest.java
index 79cfcec..bf2a6af 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcRequest.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcRequest.java
@@ -15,22 +15,10 @@
*/
package com.android.internal.telephony.dataconnection;
-import static com.android.internal.telephony.DctConstants.APN_CBS_ID;
-import static com.android.internal.telephony.DctConstants.APN_DEFAULT_ID;
-import static com.android.internal.telephony.DctConstants.APN_DUN_ID;
-import static com.android.internal.telephony.DctConstants.APN_EMERGENCY_ID;
-import static com.android.internal.telephony.DctConstants.APN_FOTA_ID;
-import static com.android.internal.telephony.DctConstants.APN_IA_ID;
-import static com.android.internal.telephony.DctConstants.APN_IMS_ID;
-import static com.android.internal.telephony.DctConstants.APN_INVALID_ID;
-import static com.android.internal.telephony.DctConstants.APN_MMS_ID;
-import static com.android.internal.telephony.DctConstants.APN_SUPL_ID;
-
import android.content.Context;
-import android.net.NetworkCapabilities;
import android.net.NetworkConfig;
import android.net.NetworkRequest;
-import android.telephony.Rlog;
+import android.telephony.data.ApnSetting.ApnType;
import java.util.HashMap;
@@ -39,17 +27,17 @@
public final NetworkRequest networkRequest;
public final int priority;
- public final int apnId;
+ public final @ApnType int apnType;
public DcRequest(NetworkRequest nr, Context context) {
initApnPriorities(context);
networkRequest = nr;
- apnId = apnIdForNetworkRequest(networkRequest);
- priority = priorityForApnId(apnId);
+ apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
+ priority = priorityForApnType(apnType);
}
public String toString() {
- return networkRequest.toString() + ", priority=" + priority + ", apnId=" + apnId;
+ return networkRequest.toString() + ", priority=" + priority + ", apnType=" + apnType;
}
public int hashCode() {
@@ -67,78 +55,6 @@
return o.priority - priority;
}
- private int apnIdForNetworkRequest(NetworkRequest nr) {
- NetworkCapabilities nc = nr.networkCapabilities;
- // For now, ignore the bandwidth stuff
- if (nc.getTransportTypes().length > 0 &&
- nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
- return APN_INVALID_ID;
- }
-
- // in the near term just do 1-1 matches.
- // TODO - actually try to match the set of capabilities
- int apnId = APN_INVALID_ID;
-
- boolean error = false;
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_DEFAULT_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_MMS_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_SUPL_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_DUN_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_FOTA_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_IMS_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_CBS_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_IA_ID;
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_INVALID_ID;
- loge("RCS APN type not yet supported");
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_INVALID_ID;
- loge("XCAP APN type not yet supported");
- }
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
- if (apnId != APN_INVALID_ID) error = true;
- apnId = APN_EMERGENCY_ID;
- }
- if (error) {
- // TODO: If this error condition is removed, the framework's handling of
- // NET_CAPABILITY_NOT_RESTRICTED will need to be updated so requests for
- // say FOTA and INTERNET are marked as restricted. This is not how
- // NetworkCapabilities.maybeMarkCapabilitiesRestricted currently works.
- loge("Multiple apn types specified in request - result is unspecified!");
- }
- if (apnId == APN_INVALID_ID) {
- loge("Unsupported NetworkRequest in Telephony: nr=" + nr);
- }
- return apnId;
- }
-
private static final HashMap<Integer, Integer> sApnPriorityMap =
new HashMap<Integer, Integer>();
@@ -149,19 +65,15 @@
com.android.internal.R.array.networkAttributes);
for (String networkConfigString : networkConfigStrings) {
NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
- final int apnId = ApnContext.apnIdForType(networkConfig.type);
- sApnPriorityMap.put(apnId, networkConfig.priority);
+ final int apnType = ApnContext.getApnTypeFromNetworkType(networkConfig.type);
+ sApnPriorityMap.put(apnType, networkConfig.priority);
}
}
}
}
- private int priorityForApnId(int apnId) {
- Integer priority = sApnPriorityMap.get(apnId);
+ private int priorityForApnType(int apnType) {
+ Integer priority = sApnPriorityMap.get(apnType);
return (priority != null ? priority.intValue() : 0);
}
-
- private void loge(String s) {
- Rlog.e(LOG_TAG, s);
- }
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index a79e8f2..50130c8 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -36,7 +36,6 @@
import android.net.NetworkCapabilities;
import android.net.NetworkConfig;
import android.net.NetworkRequest;
-import android.net.NetworkUtils;
import android.net.ProxyInfo;
import android.net.TrafficStats;
import android.net.Uri;
@@ -65,6 +64,7 @@
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataProfile;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
@@ -98,7 +98,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map.Entry;
@@ -123,7 +122,7 @@
private final AlarmManager mAlarmManager;
/* Currently requested APN type (TODO: This should probably be a parameter not a member) */
- private String mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
+ private int mRequestedApnType = ApnSetting.TYPE_DEFAULT;
// All data enabling/disabling related settings
private final DataEnabledSettings mDataEnabledSettings;
@@ -217,6 +216,7 @@
private AsyncChannel mReplyAc = new AsyncChannel();
private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
+ private final LocalLog mApnSettingsInitializationLog = new LocalLog(50);
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
@Override
@@ -354,10 +354,21 @@
return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
}
- public void updateTxRxSum() {
+ /**
+ * Get Tcp Tx/Rx packet count from TrafficStats
+ */
+ public void updateTcpTxRxSum() {
this.txPkts = TrafficStats.getMobileTcpTxPackets();
this.rxPkts = TrafficStats.getMobileTcpRxPackets();
}
+
+ /**
+ * Get total Tx/Rx packet count from TrafficStats
+ */
+ public void updateTotalTxRxSum() {
+ this.txPkts = TrafficStats.getMobileTxPackets();
+ this.rxPkts = TrafficStats.getMobileRxPackets();
+ }
}
private void onActionIntentReconnectAlarm(Intent intent) {
@@ -504,7 +515,7 @@
private final ConcurrentHashMap<String, ApnContext> mApnContexts =
new ConcurrentHashMap<String, ApnContext>();
- private final SparseArray<ApnContext> mApnContextsById = new SparseArray<ApnContext>();
+ private final SparseArray<ApnContext> mApnContextsByType = new SparseArray<ApnContext>();
private int mDisconnectPendingCount = 0;
@@ -732,7 +743,7 @@
mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
mApnContexts.clear();
- mApnContextsById.clear();
+ mApnContextsByType.clear();
mPrioritySortedApnContexts.clear();
unregisterForAllEvents();
@@ -825,7 +836,7 @@
// data connection.
apnContext.setReason(Phone.REASON_DATA_ENABLED);
cleanUpConnection(true, apnContext);
- } else if (apnContext.getApnSetting().isMetered(mPhone)
+ } else if (ApnSettingUtils.isMetered(apnContext.getApnSetting(), mPhone)
&& (netCaps != null && netCaps.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED))) {
if (DBG) {
@@ -869,40 +880,19 @@
}
public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
- final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
- final ApnContext apnContext = mApnContextsById.get(apnId);
+ final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
+ final ApnContext apnContext = mApnContextsByType.get(apnType);
log.log("DcTracker.requestNetwork for " + networkRequest + " found " + apnContext);
if (apnContext != null) apnContext.requestNetwork(networkRequest, log);
}
public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
- final int apnId = ApnContext.apnIdForNetworkRequest(networkRequest);
- final ApnContext apnContext = mApnContextsById.get(apnId);
+ final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
+ final ApnContext apnContext = mApnContextsByType.get(apnType);
log.log("DcTracker.releaseNetwork for " + networkRequest + " found " + apnContext);
if (apnContext != null) apnContext.releaseNetwork(networkRequest, log);
}
- public boolean isApnSupported(String name) {
- if (name == null) {
- loge("isApnSupported: name=null");
- return false;
- }
- ApnContext apnContext = mApnContexts.get(name);
- if (apnContext == null) {
- loge("Request for unsupported mobile name: " + name);
- return false;
- }
- return true;
- }
-
- public int getApnPriority(String name) {
- ApnContext apnContext = mApnContexts.get(name);
- if (apnContext == null) {
- loge("Request for unsupported mobile name: " + name);
- }
- return apnContext.priority;
- }
-
// Turn telephony radio on or off.
private void setRadio(boolean on) {
final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
@@ -973,7 +963,7 @@
private ApnContext addApnContext(String type, NetworkConfig networkConfig) {
ApnContext apnContext = new ApnContext(mPhone, type, LOG_TAG, networkConfig, this);
mApnContexts.put(type, apnContext);
- mApnContextsById.put(ApnContext.apnIdForApnName(type), apnContext);
+ mApnContextsByType.put(ApnSetting.getApnTypesBitmaskFromString(type), apnContext);
mPrioritySortedApnContexts.add(apnContext);
return apnContext;
}
@@ -1077,7 +1067,7 @@
if (apnContext != null) {
ApnSetting apnSetting = apnContext.getApnSetting();
if (apnSetting != null) {
- return apnSetting.apn;
+ return apnSetting.getApnName();
}
}
return null;
@@ -1091,9 +1081,10 @@
* Assumes there is less than one {@link ApnSetting} can support the given apn type.
*/
public DctConstants.State getState(String apnType) {
+ final int apnTypeBitmask = ApnSetting.getApnTypesBitmaskFromString(apnType);
for (DataConnection dc : mDataConnections.values()) {
ApnSetting apnSetting = dc.getApnSetting();
- if (apnSetting != null && apnSetting.canHandleType(apnType)) {
+ if (apnSetting != null && apnSetting.canHandleType(apnTypeBitmask)) {
if (dc.isActive()) {
return DctConstants.State.CONNECTED;
} else if (dc.isActivating()) {
@@ -1258,7 +1249,7 @@
SubscriptionManager.getDefaultDataSubscriptionId());
boolean isMeteredApnType = apnContext == null
- || ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone);
+ || ApnSettingUtils.isMeteredApnType(apnContext.getApnType(), mPhone);
PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
// Note this is explicitly not using mPhone.getState. See b/19090488.
@@ -1562,7 +1553,7 @@
// Use ApnSetting to decide metered or non-metered.
// Tear down all metered data connections.
ApnSetting apnSetting = apnContext.getApnSetting();
- if (apnSetting != null && apnSetting.isMetered(mPhone)) {
+ if (apnSetting != null && ApnSettingUtils.isMetered(apnSetting, mPhone)) {
if (apnContext.isDisconnected() == false) didDisconnect = true;
if (DBG) log("clean up metered ApnContext Type: " + apnContext.getApnType());
apnContext.setReason(reason);
@@ -1585,7 +1576,7 @@
stopDataStallAlarm();
// TODO: Do we need mRequestedApnType?
- mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
+ mRequestedApnType = ApnSetting.TYPE_DEFAULT;
log("cleanUpConnection: mDisconnectPendingCount = " + mDisconnectPendingCount);
if (tearDown && mDisconnectPendingCount == 0) {
@@ -1749,7 +1740,7 @@
if (dunCandidates.isEmpty()) {
if (!ArrayUtils.isEmpty(mAllApnSettings)) {
for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(PhoneConstants.APN_TYPE_DUN)) {
+ if (apn.canHandleType(ApnSetting.TYPE_DUN)) {
dunCandidates.add(apn);
}
}
@@ -1758,14 +1749,14 @@
}
for (ApnSetting dunSetting : dunCandidates) {
- if (!ServiceState.bitmaskHasTech(dunSetting.networkTypeBitmask,
+ if (!ServiceState.bitmaskHasTech(dunSetting.getNetworkTypeBitmask(),
ServiceState.rilRadioTechnologyToNetworkType(bearer))) {
continue;
}
- if (dunSetting.numeric.equals(operator)) {
+ if (dunSetting.getOperatorNumeric().equals(operator)) {
if (dunSetting.hasMvnoParams()) {
- if (r != null && ApnSetting.mvnoMatches(r, dunSetting.mvnoType,
- dunSetting.mvnoMatchData)) {
+ if (r != null && ApnSettingUtils.mvnoMatches(r, dunSetting.getMvnoType(),
+ dunSetting.getMvnoMatchData())) {
retDunSettings.add(dunSetting);
}
} else if (mMvnoMatched == false) {
@@ -1828,73 +1819,11 @@
}
}
- /**
- * @param types comma delimited list of APN types
- * @return array of APN types
- */
- private String[] parseTypes(String types) {
- String[] result;
- // If unset, set to DEFAULT.
- if (types == null || types.equals("")) {
- result = new String[1];
- result[0] = PhoneConstants.APN_TYPE_ALL;
- } else {
- result = types.split(",");
- }
- return result;
- }
-
boolean isPermanentFailure(DcFailCause dcFailCause) {
return (dcFailCause.isPermanentFailure(mPhone.getContext(), mPhone.getSubId()) &&
(mAttached.get() == false || dcFailCause != DcFailCause.SIGNAL_LOST));
}
- private ApnSetting makeApnSetting(Cursor cursor) {
- String[] types = parseTypes(
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE)));
- int networkTypeBitmask = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.NETWORK_TYPE_BITMASK));
-
- ApnSetting apn = new ApnSetting(
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
- NetworkUtils.trimV4AddrZeros(
- cursor.getString(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.AUTH_TYPE)),
- types,
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROTOCOL)),
- cursor.getString(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.ROAMING_PROTOCOL)),
- cursor.getInt(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.CARRIER_ENABLED)) == 1,
- networkTypeBitmask,
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROFILE_ID)),
- cursor.getInt(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.MODEM_COGNITIVE)) == 1,
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS)),
- cursor.getInt(cursor.getColumnIndexOrThrow(
- Telephony.Carriers.WAIT_TIME)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MAX_CONNS_TIME)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_TYPE)),
- cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MVNO_MATCH_DATA)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)));
- return apn;
- }
-
private ArrayList<ApnSetting> createApnList(Cursor cursor) {
ArrayList<ApnSetting> mnoApns = new ArrayList<ApnSetting>();
ArrayList<ApnSetting> mvnoApns = new ArrayList<ApnSetting>();
@@ -1902,13 +1831,14 @@
if (cursor.moveToFirst()) {
do {
- ApnSetting apn = makeApnSetting(cursor);
+ ApnSetting apn = ApnSetting.makeApnSetting(cursor);
if (apn == null) {
continue;
}
if (apn.hasMvnoParams()) {
- if (r != null && ApnSetting.mvnoMatches(r, apn.mvnoType, apn.mvnoMatchData)) {
+ if (r != null && ApnSettingUtils.mvnoMatches(r, apn.getMvnoType(),
+ apn.getMvnoMatchData())) {
mvnoApns.add(apn);
}
} else {
@@ -1982,7 +1912,7 @@
return false;
}
- int profileId = apnSetting.profileId;
+ int profileId = apnSetting.getProfileId();
if (profileId == 0) {
profileId = getApnProfileID(apnContext.getApnType());
}
@@ -2067,7 +1997,7 @@
log("setInitialApn: E mPreferredApn=" + mPreferredApn);
- if (mPreferredApn != null && mPreferredApn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
+ if (mPreferredApn != null && mPreferredApn.canHandleType(ApnSetting.TYPE_IA)) {
iaApnSetting = mPreferredApn;
} else if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
firstApnSetting = mAllApnSettings.get(0);
@@ -2075,13 +2005,13 @@
// Search for Initial APN setting and the first apn that can handle default
for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(PhoneConstants.APN_TYPE_IA)) {
+ if (apn.canHandleType(ApnSetting.TYPE_IA)) {
// The Initial Attach APN is highest priority so use it if there is one
log("setInitialApn: iaApnSetting=" + apn);
iaApnSetting = apn;
break;
} else if ((defaultApnSetting == null)
- && (apn.canHandleType(PhoneConstants.APN_TYPE_DEFAULT))) {
+ && (apn.canHandleType(ApnSetting.TYPE_DEFAULT))) {
// Use the first default apn if no better choice
log("setInitialApn: defaultApnSetting=" + apn);
defaultApnSetting = apn;
@@ -2357,24 +2287,6 @@
mAutoAttachOnCreation.set(false);
}
- private void onSetDependencyMet(String apnType, boolean met) {
- // don't allow users to tweak hipri to work around default dependency not met
- if (PhoneConstants.APN_TYPE_HIPRI.equals(apnType)) return;
-
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext == null) {
- loge("onSetDependencyMet: ApnContext not found in onSetDependencyMet(" +
- apnType + ", " + met + ")");
- return;
- }
- applyNewState(apnContext, apnContext.isEnabled(), met);
- if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType)) {
- // tie actions on default to similar actions on HIPRI regarding dependencyMet
- apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_HIPRI);
- if (apnContext != null) applyNewState(apnContext, apnContext.isEnabled(), met);
- }
- }
-
public void setPolicyDataEnabled(boolean enabled) {
if (DBG) log("setPolicyDataEnabled: " + enabled);
Message msg = obtainMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE);
@@ -2479,10 +2391,10 @@
}
private DcAsyncChannel checkForCompatibleConnectedApnContext(ApnContext apnContext) {
- String apnType = apnContext.getApnType();
+ int apnType = apnContext.getApnTypeBitmask();
ArrayList<ApnSetting> dunSettings = null;
- if (PhoneConstants.APN_TYPE_DUN.equals(apnType)) {
+ if (ApnSetting.TYPE_DUN == apnType) {
dunSettings = sortApnListByPreferred(fetchDunApns());
}
if (DBG) {
@@ -2555,17 +2467,17 @@
return null;
}
- public void setEnabled(int id, boolean enable) {
+ public void setEnabled(int apnType, boolean enable) {
Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);
- msg.arg1 = id;
+ msg.arg1 = apnType;
msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);
sendMessage(msg);
}
- private void onEnableApn(int apnId, int enabled) {
- ApnContext apnContext = mApnContextsById.get(apnId);
+ private void onEnableApn(int apnType, int enabled) {
+ ApnContext apnContext = mApnContextsByType.get(apnType);
if (apnContext == null) {
- loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");
+ loge("onEnableApn(" + apnType + ", " + enabled + "): NO ApnContext");
return;
}
// TODO change our retry manager to use the appropriate numbers for the new APN
@@ -2910,18 +2822,20 @@
} else {
ApnSetting apn = apnContext.getApnSetting();
if (DBG) {
- log("onDataSetupComplete: success apn=" + (apn == null ? "unknown" : apn.apn));
+ log("onDataSetupComplete: success apn=" + (apn == null ? "unknown"
+ : apn.getApnName()));
}
- if (apn != null && apn.proxy != null && apn.proxy.length() != 0) {
+ if (apn != null && !TextUtils.isEmpty(apn.getProxyAddressAsString())) {
try {
- String port = apn.port;
- if (TextUtils.isEmpty(port)) port = "8080";
- ProxyInfo proxy = new ProxyInfo(apn.proxy,
- Integer.parseInt(port), null);
+ int port = apn.getProxyPort();
+ if (port == -1) {
+ port = 8080;
+ }
+ ProxyInfo proxy = new ProxyInfo(apn.getProxyAddressAsString(), port, null);
dcac.setLinkPropertiesHttpProxySync(proxy);
} catch (NumberFormatException e) {
- loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" +
- apn.port + "): " + e);
+ loge("onDataSetupComplete: NumberFormatException making ProxyProperties ("
+ + apn.getProxyPort() + "): " + e);
}
}
@@ -2936,7 +2850,7 @@
if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
mPreferredApn = apn;
if (mPreferredApn != null) {
- setPreferredApn(mPreferredApn.id);
+ setPreferredApn(mPreferredApn.getId());
}
}
} else {
@@ -3019,7 +2933,7 @@
if (DBG) {
ApnSetting apn = apnContext.getApnSetting();
log(String.format("onDataSetupComplete: error apn=%s cause=%s",
- (apn == null ? "unknown" : apn.apn), cause));
+ (apn == null ? "unknown" : apn.getApnName()), cause));
}
if (cause.isEventLoggable()) {
// Log this failure to the Event Logs.
@@ -3029,7 +2943,8 @@
}
ApnSetting apn = apnContext.getApnSetting();
mPhone.notifyPreciseDataConnectionFailed(apnContext.getReason(),
- apnContext.getApnType(), apn != null ? apn.apn : "unknown", cause.toString());
+ apnContext.getApnType(), apn != null ? apn.getApnName()
+ : "unknown", cause.toString());
// Compose broadcast intent send to the specific carrier signaling receivers
Intent intent = new Intent(TelephonyIntents
@@ -3257,9 +3172,9 @@
setupDataOnConnectableApns(Phone.REASON_VOICE_CALL_ENDED);
}
- private void onCleanUpConnection(boolean tearDown, int apnId, String reason) {
+ private void onCleanUpConnection(boolean tearDown, int apnType, String reason) {
if (DBG) log("onCleanUpConnection");
- ApnContext apnContext = mApnContextsById.get(apnId);
+ ApnContext apnContext = mApnContextsByType.get(apnType);
if (apnContext != null) {
apnContext.setReason(reason);
cleanUpConnection(tearDown, apnContext);
@@ -3305,7 +3220,7 @@
if (mAllApnSettings != null && !mAllApnSettings.isEmpty()) {
ArrayList<DataProfile> dps = new ArrayList<DataProfile>();
for (ApnSetting apn : mAllApnSettings) {
- if (apn.modemCognitive) {
+ if (apn.getModemCognitive()) {
DataProfile dp = createDataProfile(apn);
if (!dps.contains(dp)) {
dps.add(dp);
@@ -3343,8 +3258,14 @@
if (cursor != null) {
if (cursor.getCount() > 0) {
mAllApnSettings = createApnList(cursor);
+ } else {
+ if (DBG) log("createAllApnList: cursor count is 0");
+ mApnSettingsInitializationLog.log("no APN in db for carrier: " + operator);
}
cursor.close();
+ } else {
+ if (DBG) log("createAllApnList: cursor is null");
+ mApnSettingsInitializationLog.log("cursor is null for carrier: " + operator);
}
}
@@ -3354,12 +3275,13 @@
if (mAllApnSettings.isEmpty()) {
if (DBG) log("createAllApnList: No APN found for carrier: " + operator);
+ mApnSettingsInitializationLog.log("no APN found for carrier: " + operator);
mPreferredApn = null;
// TODO: What is the right behavior?
//notifyNoData(DataConnection.FailCause.MISSING_UNKNOWN_APN);
} else {
mPreferredApn = getPreferredApn();
- if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
+ if (mPreferredApn != null && !mPreferredApn.getOperatorNumeric().equals(operator)) {
mPreferredApn = null;
setPreferredApn(-1);
}
@@ -3396,36 +3318,33 @@
}
private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
- int id = dest.id;
- ArrayList<String> resultTypes = new ArrayList<String>();
- resultTypes.addAll(Arrays.asList(dest.types));
- for (String srcType : src.types) {
- if (resultTypes.contains(srcType) == false) resultTypes.add(srcType);
- if (srcType.equals(PhoneConstants.APN_TYPE_DEFAULT)) id = src.id;
+ int id = dest.getId();
+ if ((src.getApnTypeBitmask() & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
+ id = src.getId();
}
- String mmsc = (TextUtils.isEmpty(dest.mmsc) ? src.mmsc : dest.mmsc);
- String mmsProxy = (TextUtils.isEmpty(dest.mmsProxy) ? src.mmsProxy : dest.mmsProxy);
- String mmsPort = (TextUtils.isEmpty(dest.mmsPort) ? src.mmsPort : dest.mmsPort);
- String proxy = (TextUtils.isEmpty(dest.proxy) ? src.proxy : dest.proxy);
- String port = (TextUtils.isEmpty(dest.port) ? src.port : dest.port);
- String protocol = src.protocol.equals("IPV4V6") ? src.protocol : dest.protocol;
- String roamingProtocol = src.roamingProtocol.equals("IPV4V6") ? src.roamingProtocol :
- dest.roamingProtocol;
- int networkTypeBitmask = (dest.networkTypeBitmask == 0 || src.networkTypeBitmask == 0)
- ? 0 : (dest.networkTypeBitmask | src.networkTypeBitmask);
- if (networkTypeBitmask == 0) {
- int bearerBitmask = (dest.bearerBitmask == 0 || src.bearerBitmask == 0)
- ? 0 : (dest.bearerBitmask | src.bearerBitmask);
- networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
- bearerBitmask);
- }
+ final int resultApnType = src.getApnTypeBitmask() | dest.getApnTypeBitmask();
+ Uri mmsc = (dest.getMmsc() == null ? src.getMmsc() : dest.getMmsc());
+ String mmsProxy = TextUtils.isEmpty(dest.getMmsProxyAddressAsString())
+ ? src.getMmsProxyAddressAsString() : dest.getMmsProxyAddressAsString();
+ int mmsPort = dest.getMmsProxyPort() == -1 ? src.getMmsProxyPort() : dest.getMmsProxyPort();
+ String proxy = TextUtils.isEmpty(dest.getProxyAddressAsString())
+ ? src.getProxyAddressAsString() : dest.getProxyAddressAsString();
+ int port = dest.getProxyPort() == -1 ? src.getProxyPort() : dest.getProxyPort();
+ int protocol = src.getProtocol() == ApnSetting.PROTOCOL_IPV4V6 ? src.getProtocol()
+ : dest.getProtocol();
+ int roamingProtocol = src.getRoamingProtocol() == ApnSetting.PROTOCOL_IPV4V6
+ ? src.getRoamingProtocol() : dest.getRoamingProtocol();
+ int networkTypeBitmask = (dest.getNetworkTypeBitmask() == 0
+ || src.getNetworkTypeBitmask() == 0)
+ ? 0 : (dest.getNetworkTypeBitmask() | src.getNetworkTypeBitmask());
- return new ApnSetting(id, dest.numeric, dest.carrier, dest.apn,
- proxy, port, mmsc, mmsProxy, mmsPort, dest.user, dest.password,
- dest.authType, resultTypes.toArray(new String[0]), protocol,
- roamingProtocol, dest.carrierEnabled, networkTypeBitmask, dest.profileId,
- (dest.modemCognitive || src.modemCognitive), dest.maxConns, dest.waitTime,
- dest.maxConnsTime, dest.mtu, dest.mvnoType, dest.mvnoMatchData, dest.apnSetId);
+ return ApnSetting.makeApnSetting(id, dest.getOperatorNumeric(), dest.getEntryName(),
+ dest.getApnName(), proxy, port, mmsc, mmsProxy, mmsPort, dest.getUser(),
+ dest.getPassword(), dest.getAuthType(), resultApnType, protocol, roamingProtocol,
+ dest.isEnabled(), networkTypeBitmask, dest.getProfileId(),
+ (dest.getModemCognitive() || src.getModemCognitive()), dest.getMaxConns(),
+ dest.getWaitTime(), dest.getMaxConnsTime(), dest.getMtu(), dest.getMvnoType(),
+ dest.getMvnoMatchData(), dest.getApnSetId());
}
/** Return the DC AsyncChannel for the new data connection */
@@ -3468,7 +3387,8 @@
if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
- if (requestedApnType.equals(PhoneConstants.APN_TYPE_DUN)) {
+ int requestedApnTypeBitmask = ApnSetting.getApnTypesBitmaskFromString(requestedApnType);
+ if (requestedApnTypeBitmask == ApnSetting.TYPE_DUN) {
ArrayList<ApnSetting> dunApns = fetchDunApns();
if (dunApns.size() > 0) {
for (ApnSetting dun : dunApns) {
@@ -3507,13 +3427,13 @@
}
if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
- mPreferredApn.canHandleType(requestedApnType)) {
+ mPreferredApn.canHandleType(requestedApnTypeBitmask)) {
if (DBG) {
log("buildWaitingApns: Preferred APN:" + operator + ":"
- + mPreferredApn.numeric + ":" + mPreferredApn);
+ + mPreferredApn.getOperatorNumeric() + ":" + mPreferredApn);
}
- if (mPreferredApn.numeric.equals(operator)) {
- if (ServiceState.bitmaskHasTech(mPreferredApn.networkTypeBitmask,
+ if (mPreferredApn.getOperatorNumeric().equals(operator)) {
+ if (ServiceState.bitmaskHasTech(mPreferredApn.getNetworkTypeBitmask(),
ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
apnList.add(mPreferredApn);
apnList = sortApnListByPreferred(apnList);
@@ -3533,15 +3453,15 @@
if (mAllApnSettings != null) {
if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(requestedApnType)) {
- if (ServiceState.bitmaskHasTech(apn.networkTypeBitmask,
+ if (apn.canHandleType(requestedApnTypeBitmask)) {
+ if (ServiceState.bitmaskHasTech(apn.getNetworkTypeBitmask(),
ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
if (DBG) log("buildWaitingApns: adding apn=" + apn);
apnList.add(apn);
} else {
if (DBG) {
- log("buildWaitingApns: bearerBitmask:" + apn.bearerBitmask
- + " or " + "networkTypeBitmask:" + apn.networkTypeBitmask
+ log("buildWaitingApns: networkTypeBitmask:"
+ + apn.getNetworkTypeBitmask()
+ "do not include radioTech:" + radioTech);
}
}
@@ -3579,8 +3499,12 @@
list.sort(new Comparator<ApnSetting>() {
@Override
public int compare(ApnSetting apn1, ApnSetting apn2) {
- if (apn1.apnSetId == preferredApnSetId) return -1;
- if (apn2.apnSetId == preferredApnSetId) return 1;
+ if (apn1.getApnSetId() == preferredApnSetId) {
+ return -1;
+ }
+ if (apn2.getApnSetId() == preferredApnSetId) {
+ return 1;
+ }
return 0;
}
});
@@ -3644,7 +3568,7 @@
pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
for(ApnSetting p : mAllApnSettings) {
log("getPreferredApn: apnSetting=" + p);
- if (p.id == pos && p.canHandleType(mRequestedApnType)) {
+ if (p.getId() == pos && p.canHandleType(mRequestedApnType)) {
log("getPreferredApn: X found apnSetting" + p);
cursor.close();
return p;
@@ -3721,7 +3645,7 @@
cleanUpAllConnections(false, Phone.REASON_PS_RESTRICT_ENABLED);
mReregisterOnReconnectFailure = false;
}
- ApnContext apnContext = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
+ ApnContext apnContext = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
if (apnContext != null) {
apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
trySetupData(apnContext);
@@ -3859,19 +3783,6 @@
onSetUserDataEnabled(enabled);
break;
}
- // TODO - remove
- case DctConstants.CMD_SET_DEPENDENCY_MET: {
- boolean met = (msg.arg1 == DctConstants.ENABLED) ? true : false;
- if (DBG) log("CMD_SET_DEPENDENCY_MET met=" + met);
- Bundle bundle = msg.getData();
- if (bundle != null) {
- String apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
- if (apnType != null) {
- onSetDependencyMet(apnType, met);
- }
- }
- break;
- }
case DctConstants.CMD_SET_POLICY_DATA_ENABLE: {
final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
onSetPolicyDataEnabled(enabled);
@@ -3937,7 +3848,7 @@
}
case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
- ApnContext apnCtx = mApnContextsById.get(DctConstants.APN_DEFAULT_ID);
+ ApnContext apnCtx = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
if (mProvisioningApnAlarmTag == msg.arg1) {
if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
@@ -4212,6 +4123,8 @@
pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
pw.println(" mDataRoamingLeakageLog= ");
mDataRoamingLeakageLog.dump(fd, pw, args);
+ pw.println(" mApnSettingsInitializationLog= ");
+ mApnSettingsInitializationLog.dump(fd, pw, args);
pw.flush();
pw.println(" ***************************************");
DcController dcc = mDcc;
@@ -4292,9 +4205,9 @@
}
if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_EMERGENCY)) {
- apnContext = mApnContextsById.get(DctConstants.APN_EMERGENCY_ID);
+ apnContext = mApnContextsByType.get(ApnSetting.TYPE_EMERGENCY);
} else if (TextUtils.equals(apnType, PhoneConstants.APN_TYPE_IMS)) {
- apnContext = mApnContextsById.get(DctConstants.APN_IMS_ID);
+ apnContext = mApnContextsByType.get(ApnSetting.TYPE_IMS);
} else {
log("apnType is invalid, return null");
return null;
@@ -4339,7 +4252,7 @@
if (cursor != null) {
if (cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
- mEmergencyApn = makeApnSetting(cursor);
+ mEmergencyApn = ApnSetting.makeApnSetting(cursor);
}
}
cursor.close();
@@ -4356,7 +4269,7 @@
} else {
boolean hasEmergencyApn = false;
for (ApnSetting apn : mAllApnSettings) {
- if (ArrayUtils.contains(apn.types, PhoneConstants.APN_TYPE_EMERGENCY)) {
+ if ((apn.getApnTypeBitmask() & ApnSetting.TYPE_EMERGENCY) > 0) {
hasEmergencyApn = true;
break;
}
@@ -4428,7 +4341,7 @@
stopDataStallAlarm();
}
- mRequestedApnType = PhoneConstants.APN_TYPE_DEFAULT;
+ mRequestedApnType = ApnSetting.TYPE_DEFAULT;
if (DBG) log("mDisconnectPendingCount = " + mDisconnectPendingCount);
if (tearDown && mDisconnectPendingCount == 0) {
@@ -4507,7 +4420,7 @@
TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
TxRxSum curTxRxSum = new TxRxSum();
- curTxRxSum.updateTxRxSum();
+ curTxRxSum.updateTotalTxRxSum();
mTxPkts = curTxRxSum.txPkts;
mRxPkts = curTxRxSum.rxPkts;
@@ -4671,7 +4584,7 @@
long sent, received;
TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
- mDataStallTxRxSum.updateTxRxSum();
+ mDataStallTxRxSum.updateTcpTxRxSum();
if (VDBG_STALL) {
log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
@@ -4863,7 +4776,7 @@
}
private static DataProfile createDataProfile(ApnSetting apn) {
- return createDataProfile(apn, apn.profileId);
+ return createDataProfile(apn, apn.getProfileId());
}
@VisibleForTesting
@@ -4872,7 +4785,7 @@
int bearerBitmap = 0;
bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
- apn.networkTypeBitmask);
+ apn.getNetworkTypeBitmask());
if (bearerBitmap == 0) {
profileType = DataProfile.TYPE_COMMON;
@@ -4882,11 +4795,13 @@
profileType = DataProfile.TYPE_3GPP;
}
- return new DataProfile(profileId, apn.apn, apn.protocol,
- apn.authType, apn.user, apn.password, profileType,
- apn.maxConnsTime, apn.maxConns, apn.waitTime, apn.carrierEnabled, apn.typesBitmap,
- apn.roamingProtocol, bearerBitmap, apn.mtu, apn.mvnoType, apn.mvnoMatchData,
- apn.modemCognitive);
+ return new DataProfile(profileId, apn.getApnName(),
+ ApnSetting.getProtocolStringFromInt(apn.getProtocol()), apn.getAuthType(),
+ apn.getUser(), apn.getPassword(), profileType, apn.getMaxConnsTime(),
+ apn.getMaxConns(), apn.getWaitTime(), apn.isEnabled(), apn.getApnTypeBitmask(),
+ ApnSetting.getProtocolStringFromInt(apn.getRoamingProtocol()), bearerBitmap,
+ apn.getMtu(), ApnSetting.getMvnoTypeStringFromInt(apn.getMvnoType()),
+ apn.getMvnoMatchData(), apn.getModemCognitive());
}
private void onDataServiceBindingChanged(boolean bound) {
diff --git a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 8c4e9aa..99082ee 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -16,13 +16,8 @@
package com.android.internal.telephony.gsm;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Intent;
import android.os.AsyncResult;
import android.os.Message;
-import android.provider.Telephony.Sms;
import android.provider.Telephony.Sms.Intents;
import android.telephony.Rlog;
import android.telephony.ServiceState;
@@ -106,8 +101,9 @@
}
@Override
- protected boolean shouldBlockSms() {
- return SMSDispatcherUtil.shouldBlockSms(isCdmaMo(), mPhone);
+ protected boolean shouldBlockSmsForEcbm() {
+ // There is no such thing as ECBM for GSM. This only applies to CDMA.
+ return false;
}
@Override
@@ -187,6 +183,7 @@
+ " mRetryCount=" + tracker.mRetryCount
+ " mImsRetry=" + tracker.mImsRetry
+ " mMessageRef=" + tracker.mMessageRef
+ + " mUsesImsServiceForIms=" + tracker.mUsesImsServiceForIms
+ " SS=" + mPhone.getServiceState().getState());
int ss = mPhone.getServiceState().getState();
@@ -202,8 +199,11 @@
// sms over gsm is used:
// if sms over IMS is not supported AND
// this is not a retry case after sms over IMS failed
- // indicated by mImsRetry > 0
- if (0 == tracker.mImsRetry && !isIms()) {
+ // indicated by mImsRetry > 0 OR
+ // this tracker uses ImsSmsDispatcher to handle SMS over IMS. This dispatcher has received
+ // this message because the ImsSmsDispatcher has indicated that the message needs to
+ // fall back to sending over CS.
+ if (0 == tracker.mImsRetry && !isIms() || tracker.mUsesImsServiceForIms) {
if (tracker.mRetryCount == 0 && tracker.mExpectMore) {
mCi.sendSMSExpectMore(IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), reply);
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index c6a7efa..f0aee01 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -29,6 +29,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.CarrierConfigManager;
@@ -79,6 +80,10 @@
"android.telephony.ims.EMERGENCY_MMTEL_FEATURE";
public static final String METADATA_MMTEL_FEATURE = "android.telephony.ims.MMTEL_FEATURE";
public static final String METADATA_RCS_FEATURE = "android.telephony.ims.RCS_FEATURE";
+ // Overrides the sanity permission check of android.permission.BIND_IMS_SERVICE for any
+ // ImsService that is connecting to the platform.
+ // This should ONLY be used for testing and should not be used in production ImsServices.
+ private static final String METADATA_OVERRIDE_PERM_CHECK = "override_bind_check";
// Based on updates from PackageManager
private static final int HANDLER_ADD_PACKAGE = 0;
@@ -88,8 +93,10 @@
private static final int HANDLER_CONFIG_CHANGED = 2;
// A query has been started for an ImsService to relay the features they support.
private static final int HANDLER_START_DYNAMIC_FEATURE_QUERY = 3;
- // A query to request ImsService features has completed.
- private static final int HANDLER_DYNAMIC_FEATURE_QUERY_COMPLETE = 4;
+ // A query to request ImsService features has completed or the ImsService has updated features.
+ private static final int HANDLER_DYNAMIC_FEATURE_CHANGE = 4;
+ // Testing: Overrides the current configuration for ImsService binding
+ private static final int HANDLER_OVERRIDE_IMS_SERVICE_CONFIG = 5;
// Delay between dynamic ImsService queries.
private static final int DELAY_DYNAMIC_QUERY_MS = 5000;
@@ -328,6 +335,8 @@
private final Object mBoundServicesLock = new Object();
private final int mNumSlots;
private final boolean mIsDynamicBinding;
+ // Package name of the default device service.
+ private String mDeviceService;
// Synchronize all messages on a handler to ensure that the cache includes the most recent
// version of the installed ImsServices.
@@ -345,7 +354,7 @@
}
case HANDLER_CONFIG_CHANGED: {
int slotId = (Integer) msg.obj;
- maybeRebindService(slotId);
+ carrierConfigChanged(slotId);
break;
}
case HANDLER_START_DYNAMIC_FEATURE_QUERY: {
@@ -353,7 +362,7 @@
startDynamicQuery(info);
break;
}
- case HANDLER_DYNAMIC_FEATURE_QUERY_COMPLETE: {
+ case HANDLER_DYNAMIC_FEATURE_CHANGE: {
SomeArgs args = (SomeArgs) msg.obj;
ComponentName name = (ComponentName) args.arg1;
Set<ImsFeatureConfiguration.FeatureSlotPair> features =
@@ -362,6 +371,36 @@
dynamicQueryComplete(name, features);
break;
}
+ case HANDLER_OVERRIDE_IMS_SERVICE_CONFIG: {
+ int slotId = msg.arg1;
+ // arg2 will be equal to 1 if it is a carrier service.
+ boolean isCarrierImsService = (msg.arg2 == 1);
+ String packageName = (String) msg.obj;
+ if (isCarrierImsService) {
+ Log.i(TAG, "overriding carrier ImsService - slot=" + slotId + " packageName="
+ + packageName);
+ maybeRebindService(slotId, packageName);
+ } else {
+ Log.i(TAG, "overriding device ImsService - packageName=" + packageName);
+ if (packageName == null || packageName.isEmpty()) {
+ unbindImsService(getImsServiceInfoFromCache(mDeviceService));
+ }
+ mDeviceService = packageName;
+ ImsServiceInfo deviceInfo = getImsServiceInfoFromCache(mDeviceService);
+ if (deviceInfo == null) {
+ // The package name is either "" or does not exist on the device.
+ break;
+ }
+ if (deviceInfo.featureFromMetadata) {
+ bindImsService(deviceInfo);
+ } else {
+ // newly added ImsServiceInfo that has not had features queried yet. Start
+ // async bind and query features.
+ scheduleQueryForFeatures(deviceInfo);
+ }
+ }
+ break;
+ }
default:
return false;
}
@@ -377,7 +416,7 @@
Set<ImsFeatureConfiguration.FeatureSlotPair> features) {
Log.d(TAG, "onComplete called for name: " + name + "features:"
+ printFeatures(features));
- handleFeatureQueryComplete(name, features);
+ handleFeaturesChanged(name, features);
}
@Override
@@ -387,8 +426,6 @@
}
};
- // Package name of the default device service.
- private String mDeviceService;
// Array index corresponds to slot Id associated with the service package name.
private String[] mCarrierServices;
// List index corresponds to Slot Id, Maps ImsFeature.FEATURE->bound ImsServiceController
@@ -594,6 +631,36 @@
return null;
}
+ // Used for testing only.
+ public boolean overrideImsServiceConfiguration(int slotId, boolean isCarrierService,
+ String packageName) {
+ if (slotId < 0 || slotId >= mNumSlots) {
+ Log.w(TAG, "overrideImsServiceConfiguration: invalid slotId!");
+ return false;
+ }
+
+ if (packageName == null) {
+ Log.w(TAG, "overrideImsServiceConfiguration: null packageName!");
+ return false;
+ }
+
+ // encode boolean to int for Message.
+ int carrierService = isCarrierService ? 1 : 0;
+ Message.obtain(mHandler, HANDLER_OVERRIDE_IMS_SERVICE_CONFIG, slotId, carrierService,
+ packageName).sendToTarget();
+ return true;
+ }
+
+ // used for testing only.
+ public String getImsServiceConfiguration(int slotId, boolean isCarrierService) {
+ if (slotId < 0 || slotId >= mNumSlots) {
+ Log.w(TAG, "getImsServiceConfiguration: invalid slotId!");
+ return "";
+ }
+
+ return isCarrierService ? mCarrierServices[slotId] : mDeviceService;
+ }
+
private void putImsController(int slotId, int feature, ImsServiceController controller) {
if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.FEATURE_INVALID
|| feature >= ImsFeature.FEATURE_MAX) {
@@ -901,6 +968,21 @@
}
/**
+ * Implementation of
+ * {@link ImsServiceController.ImsServiceControllerCallbacks#imsServiceFeaturesChanged, which
+ * notify the ImsResolver of a change to the supported ImsFeatures of a connected ImsService.
+ */
+ public void imsServiceFeaturesChanged(ImsFeatureConfiguration config,
+ ImsServiceController controller) {
+ if (controller == null || config == null) {
+ return;
+ }
+ Log.i(TAG, "imsServiceFeaturesChanged: config=" + config.getServiceFeatures()
+ + ", ComponentName=" + controller.getComponentName());
+ handleFeaturesChanged(controller.getComponentName(), config.getServiceFeatures());
+ }
+
+ /**
* Determines if the features specified should cause a bind or keep a binding active to an
* ImsService.
* @return true if MMTEL or RCS features are present, false if they are not or only
@@ -917,22 +999,31 @@
// Possibly rebind to another ImsService if currently installed ImsServices were changed or if
// the SIM card has changed.
// Called from the handler ONLY
- private void maybeRebindService(int slotId) {
+ private void maybeRebindService(int slotId, String newPackageName) {
if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
// not specified, replace package on all slots.
for (int i = 0; i < mNumSlots; i++) {
- updateBoundCarrierServices(i);
+ updateBoundCarrierServices(i, newPackageName);
}
} else {
- updateBoundCarrierServices(slotId);
+ updateBoundCarrierServices(slotId, newPackageName);
}
}
- private void updateBoundCarrierServices(int slotId) {
+ private void carrierConfigChanged(int slotId) {
int subId = mSubscriptionManagerProxy.getSubId(slotId);
- String newPackageName = mCarrierConfigManager.getConfigForSubId(subId).getString(
- CarrierConfigManager.KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING, null);
+ PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
+ if (config != null) {
+ String newPackageName = config.getString(
+ CarrierConfigManager.KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING, null);
+ maybeRebindService(slotId, newPackageName);
+ } else {
+ Log.w(TAG, "carrierConfigChanged: CarrierConfig is null!");
+ }
+ }
+
+ private void updateBoundCarrierServices(int slotId, String newPackageName) {
if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX && slotId < mNumSlots) {
String oldPackageName = mCarrierServices[slotId];
mCarrierServices[slotId] = newPackageName;
@@ -997,12 +1088,12 @@
/**
* Schedules the processing of a completed query.
*/
- private void handleFeatureQueryComplete(ComponentName name,
+ private void handleFeaturesChanged(ComponentName name,
Set<ImsFeatureConfiguration.FeatureSlotPair> features) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = name;
args.arg2 = features;
- mHandler.obtainMessage(HANDLER_DYNAMIC_FEATURE_QUERY_COMPLETE, args).sendToTarget();
+ mHandler.obtainMessage(HANDLER_DYNAMIC_FEATURE_CHANGE, args).sendToTarget();
}
// Starts a dynamic query. Called from handler ONLY.
@@ -1022,7 +1113,7 @@
Set<ImsFeatureConfiguration.FeatureSlotPair> features) {
ImsServiceInfo service = getImsServiceInfoFromCache(name.getPackageName());
if (service == null) {
- Log.w(TAG, "handleFeatureQueryComplete: Couldn't find cached info for name: "
+ Log.w(TAG, "handleFeaturesChanged: Couldn't find cached info for name: "
+ name);
return;
}
@@ -1047,7 +1138,7 @@
public boolean isResolvingBinding() {
return mHandler.hasMessages(HANDLER_START_DYNAMIC_FEATURE_QUERY)
// We haven't processed this message yet, so it is still resolving.
- || mHandler.hasMessages(HANDLER_DYNAMIC_FEATURE_QUERY_COMPLETE)
+ || mHandler.hasMessages(HANDLER_DYNAMIC_FEATURE_CHANGE)
|| mFeatureQueryManager.isQueryInProgress();
}
@@ -1164,9 +1255,11 @@
Log.i(TAG, "service name: " + info.name + ", manifest query: "
+ info.featureFromMetadata);
// Check manifest permission to be sure that the service declares the correct
- // permissions.
- if (TextUtils.equals(serviceInfo.permission,
- Manifest.permission.BIND_IMS_SERVICE)) {
+ // permissions. Overridden if the METADATA_OVERRIDE_PERM_CHECK metadata is set to
+ // true.
+ // NOTE: METADATA_OVERRIDE_PERM_CHECK should only be set for testing.
+ if (TextUtils.equals(serviceInfo.permission, Manifest.permission.BIND_IMS_SERVICE)
+ || serviceInfo.metaData.getBoolean(METADATA_OVERRIDE_PERM_CHECK, false)) {
infos.add(info);
} else {
Log.w(TAG, "ImsService is not protected with BIND_IMS_SERVICE permission: "
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index e13a8ef..e2a0f43 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -149,6 +149,16 @@
}
}
+ private ImsService.Listener mFeatureChangedListener = new ImsService.Listener() {
+ @Override
+ public void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) {
+ if (mCallbacks == null) {
+ return;
+ }
+ mCallbacks.imsServiceFeaturesChanged(c, ImsServiceController.this);
+ }
+ };
+
/**
* Defines callbacks that are used by the ImsServiceController to notify when an ImsService
* has created or removed a new feature as well as the associated ImsServiceController.
@@ -162,6 +172,13 @@
* Called by ImsServiceController when a new MMTEL or RCS feature has been removed.
*/
void imsServiceFeatureRemoved(int slotId, int feature, ImsServiceController controller);
+
+ /**
+ * Called by the ImsServiceController when the ImsService has notified the framework that
+ * its features have changed.
+ */
+ void imsServiceFeaturesChanged(ImsFeatureConfiguration config,
+ ImsServiceController controller);
}
/**
@@ -552,6 +569,7 @@
synchronized (mLock) {
if (isServiceControllerAvailable()) {
Log.d(LOG_TAG, "notifyImsServiceReady");
+ mIImsServiceController.setListener(mFeatureChangedListener);
mIImsServiceController.notifyImsServiceReadyForFeatureCreation();
}
}
diff --git a/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
index 8eec9db..7b0619b 100644
--- a/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
+++ b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
@@ -155,6 +155,10 @@
@Override
public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
+ // At de-registration, notify the framework that no IMS capabilities are currently
+ // available.
+ Log.i(TAG, "registrationDisconnected: resetting MMTEL capabilities.");
+ notifyCapabilitiesStatusChanged(new MmTelCapabilities());
// Implemented in the Registration Adapter
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 1fec867..0a86867 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -1279,12 +1279,12 @@
private CallForwardInfo getCallForwardInfo(ImsCallForwardInfo info) {
CallForwardInfo cfInfo = new CallForwardInfo();
- cfInfo.status = info.mStatus;
- cfInfo.reason = getCFReasonFromCondition(info.mCondition);
+ cfInfo.status = info.getStatus();
+ cfInfo.reason = getCFReasonFromCondition(info.getCondition());
cfInfo.serviceClass = SERVICE_CLASS_VOICE;
- cfInfo.toa = info.mToA;
- cfInfo.number = info.mNumber;
- cfInfo.timeSeconds = info.mTimeSeconds;
+ cfInfo.toa = info.getToA();
+ cfInfo.number = info.getNumber();
+ cfInfo.timeSeconds = info.getTimeSeconds();
return cfInfo;
}
@@ -1308,10 +1308,10 @@
}
} else {
for (int i = 0, s = infos.length; i < s; i++) {
- if (infos[i].mCondition == ImsUtInterface.CDIV_CF_UNCONDITIONAL) {
+ if (infos[i].getCondition() == ImsUtInterface.CDIV_CF_UNCONDITIONAL) {
if (r != null) {
- setVoiceCallForwardingFlag(r, 1, (infos[i].mStatus == 1),
- infos[i].mNumber);
+ setVoiceCallForwardingFlag(r, 1, (infos[i].getStatus() == 1),
+ infos[i].getNumber());
}
}
cfInfos[i] = getCallForwardInfo(infos[i]);
@@ -1325,7 +1325,7 @@
int[] cbInfos = new int[1];
cbInfos[0] = SERVICE_CLASS_NONE;
- if (infos[0].mStatus == 1) {
+ if (infos[0].getStatus() == 1) {
cbInfos[0] = SERVICE_CLASS_VOICE;
}
@@ -1336,7 +1336,7 @@
int[] cwInfos = new int[2];
cwInfos[0] = 0;
- if (infos[0].mStatus == 1) {
+ if (infos[0].getStatus() == 1) {
cwInfos[0] = 1;
cwInfos[1] = SERVICE_CLASS_VOICE;
}
@@ -1432,8 +1432,14 @@
ServiceState newServiceState = (ServiceState) ar.result;
// only update if roaming status changed
if (mRoaming != newServiceState.getRoaming()) {
- if (DBG) logd("Roaming state changed");
- updateRoamingState(newServiceState.getRoaming());
+ if (DBG) logd("Roaming state changed - " + mRoaming);
+ // Update WFC mode only if voice or data is in service.
+ // The STATE_IN_SERVICE is checked to prevent wifi calling mode change
+ // when phone moves from roaming to no service.
+ boolean isInService =
+ (newServiceState.getVoiceRegState() == ServiceState.STATE_IN_SERVICE ||
+ newServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE);
+ updateRoamingState(newServiceState.getRoaming(), isInService);
}
break;
case EVENT_VOICE_CALL_ENDED:
@@ -1442,7 +1448,7 @@
// only update if roaming status changed
boolean newRoaming = getCurrentRoaming();
if (mRoaming != newRoaming) {
- updateRoamingState(newRoaming);
+ updateRoamingState(newRoaming, true);
}
break;
@@ -1804,12 +1810,16 @@
return mCT.getVtDataUsage(perUidStats);
}
- private void updateRoamingState(boolean newRoaming) {
+ private void updateRoamingState(boolean newRoaming, boolean isInService) {
if (mCT.getState() == PhoneConstants.State.IDLE) {
if (DBG) logd("updateRoamingState now: " + newRoaming);
mRoaming = newRoaming;
- ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
- imsManager.setWfcMode(imsManager.getWfcMode(newRoaming), newRoaming);
+ if (isInService) {
+ ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
+ imsManager.setWfcMode(imsManager.getWfcMode(newRoaming), newRoaming);
+ } else {
+ if (DBG) Rlog.d(LOG_TAG, "updateRoamingState service state is OUT_OF_SERVICE");
+ }
} else {
if (DBG) logd("updateRoamingState postponed: " + newRoaming);
mCT.registerForVoiceCallEnded(this,
@@ -1820,7 +1830,7 @@
private boolean getCurrentRoaming() {
TelephonyManager tm = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
- return tm.isNetworkRoaming();
+ return tm.isNetworkRoaming(getSubId());
}
@Override
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 541c74c..239f10a 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -1537,6 +1537,16 @@
return mDesiredMute;
}
+ /**
+ * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
+ * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
+ * and event flash to 16. Currently, event flash is not supported.
+ *
+ * @param c that represents the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
+ * @param result the result message to send when done. If non-null, the {@link Message} must
+ * contain a valid {@link android.os.Messenger} in the {@link Message#replyTo} field,
+ * since this can be used across IPC boundaries.
+ */
public void sendDtmf(char c, Message result) {
if (DBG) log("sendDtmf");
@@ -2373,6 +2383,9 @@
mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
}
+ if (imsCall != mCallExpectedToResume) {
+ mCallExpectedToResume = null;
+ }
}
mPhone.notifySuppServiceFailed(Phone.SuppService.HOLD);
}
@@ -2789,7 +2802,6 @@
@Override
public void onDeregistered(ImsReasonInfo imsReasonInfo) {
if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
- resetImsCapabilities();
mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
mPhone.setImsRegistered(false);
mPhone.processDisconnectReason(imsReasonInfo);
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 58af015..d63b9c2 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -23,6 +23,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Messenger;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Registrant;
@@ -79,6 +80,7 @@
private UUSInfo mUusInfo;
private Handler mHandler;
+ private Messenger mHandlerMessenger;
private PowerManager.WakeLock mPartialWakeLock;
@@ -171,6 +173,7 @@
mOwner = ct;
mHandler = new MyHandler(mOwner.getLooper());
+ mHandlerMessenger = new Messenger(mHandler);
mImsCall = imsCall;
if ((imsCall != null) && (imsCall.getCallProfile() != null)) {
@@ -495,7 +498,9 @@
private boolean
processPostDialChar(char c) {
if (PhoneNumberUtils.is12Key(c)) {
- mOwner.sendDtmf(c, mHandler.obtainMessage(EVENT_DTMF_DONE));
+ Message dtmfComplete = mHandler.obtainMessage(EVENT_DTMF_DONE);
+ dtmfComplete.replyTo = mHandlerMessenger;
+ mOwner.sendDtmf(c, dtmfComplete);
} else if (c == PhoneNumberUtils.PAUSE) {
// From TS 22.101:
// It continues...
@@ -991,11 +996,29 @@
}
public void onRttMessageReceived(String message) {
- getOrCreateRttTextHandler().sendToInCall(message);
+ synchronized (this) {
+ if (mRttTextHandler == null) {
+ Rlog.w(LOG_TAG, "onRttMessageReceived: RTT text handler not available."
+ + " Attempting to create one.");
+ if (mRttTextStream == null) {
+ Rlog.e(LOG_TAG, "onRttMessageReceived:"
+ + " Unable to process incoming message. No textstream available");
+ return;
+ }
+ createRttTextHandler();
+ }
+ }
+ mRttTextHandler.sendToInCall(message);
}
public void setCurrentRttTextStream(android.telecom.Connection.RttTextStream rttTextStream) {
- mRttTextStream = rttTextStream;
+ synchronized (this) {
+ mRttTextStream = rttTextStream;
+ if (mRttTextHandler == null && mIsRttEnabledForCall) {
+ Rlog.i(LOG_TAG, "setCurrentRttTextStream: Creating a text handler");
+ createRttTextHandler();
+ }
+ }
}
public boolean hasRttTextStream() {
@@ -1007,20 +1030,24 @@
}
public void startRttTextProcessing() {
- if (mRttTextStream == null) {
- Rlog.w(LOG_TAG, "startRttTextProcessing: no RTT text stream. Ignoring.");
- return;
+ synchronized (this) {
+ if (mRttTextStream == null) {
+ Rlog.w(LOG_TAG, "startRttTextProcessing: no RTT text stream. Ignoring.");
+ return;
+ }
+ if (mRttTextHandler != null) {
+ Rlog.w(LOG_TAG, "startRttTextProcessing: RTT text handler already exists");
+ return;
+ }
+ createRttTextHandler();
}
- getOrCreateRttTextHandler().initialize(mRttTextStream);
}
- private ImsRttTextHandler getOrCreateRttTextHandler() {
- if (mRttTextHandler != null) {
- return mRttTextHandler;
- }
+ // Make sure to synchronize on ImsPhoneConnection.this before calling.
+ private void createRttTextHandler() {
mRttTextHandler = new ImsRttTextHandler(Looper.getMainLooper(),
(message) -> getImsCall().sendRttMessage(message));
- return mRttTextHandler;
+ mRttTextHandler.initialize(mRttTextStream);
}
/**
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 811d30e..87e51ec 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -36,13 +36,13 @@
import android.os.ResultReceiver;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsSsData;
+import android.telephony.ims.ImsSsInfo;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import com.android.ims.ImsException;
-import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.ImsSsData;
-import android.telephony.ims.ImsSsInfo;
import com.android.ims.ImsUtInterface;
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CallStateException;
@@ -50,7 +50,6 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.uicc.IccRecords;
import java.util.regex.Matcher;
@@ -1480,11 +1479,11 @@
ssInfo = (ImsSsInfo) ssInfoResp.getParcelable(UT_BUNDLE_KEY_SSINFO);
if (ssInfo != null) {
Rlog.d(LOG_TAG,
- "onSuppSvcQueryComplete: ImsSsInfo mStatus = " + ssInfo.mStatus);
- if (ssInfo.mStatus == ImsSsInfo.DISABLED) {
+ "onSuppSvcQueryComplete: ImsSsInfo mStatus = " + ssInfo.getStatus());
+ if (ssInfo.getStatus() == ImsSsInfo.DISABLED) {
sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
mState = State.COMPLETE;
- } else if (ssInfo.mStatus == ImsSsInfo.ENABLED) {
+ } else if (ssInfo.getStatus() == ImsSsInfo.ENABLED) {
sb.append(mContext.getText(com.android.internal.R.string.serviceEnabled));
mState = State.COMPLETE;
} else {
@@ -1532,10 +1531,10 @@
sb.append(mContext.getText(com.android.internal.R.string.serviceDisabled));
} else {
for (int i = 0, s = infos.length; i < s ; i++) {
- if (infos[i].mIcbNum !=null) {
- sb.append("Num: " + infos[i].mIcbNum + " status: "
- + infos[i].mStatus + "\n");
- } else if (infos[i].mStatus == 1) {
+ if (infos[i].getIcbNum() != null) {
+ sb.append("Num: " + infos[i].getIcbNum() + " status: "
+ + infos[i].getStatus() + "\n");
+ } else if (infos[i].getStatus() == 1) {
sb.append(mContext.getText(com.android.internal
.R.string.serviceEnabled));
} else {
@@ -1726,7 +1725,7 @@
}
void parseSsData(ImsSsData ssData) {
- ImsException ex = (ssData.result != RILConstants.SUCCESS)
+ ImsException ex = (ssData.result != ImsSsData.RESULT_SUCCESS)
? new ImsException(null, ssData.result) : null;
mSc = getScStringFromScType(ssData.serviceType);
mAction = getActionStringFromReqType(ssData.requestType);
@@ -1737,7 +1736,7 @@
case ImsSsData.SS_DEACTIVATION:
case ImsSsData.SS_REGISTRATION:
case ImsSsData.SS_ERASURE:
- if ((ssData.result == RILConstants.SUCCESS)
+ if ((ssData.result == ImsSsData.RESULT_SUCCESS)
&& ssData.isTypeUnConditional()) {
/*
* When ssData.serviceType is unconditional (SS_CFU or SS_CF_ALL) and
@@ -1758,30 +1757,31 @@
Rlog.e(LOG_TAG, "setCallForwardingFlag aborted. sim records is null.");
}
}
- onSetComplete(null, new AsyncResult(null, ssData.cfInfo, ex));
+ onSetComplete(null, new AsyncResult(null, ssData.getCallForwardInfo(), ex));
break;
case ImsSsData.SS_INTERROGATION:
if (ssData.isTypeClir()) {
Rlog.d(LOG_TAG, "CLIR INTERROGATION");
Bundle clirInfo = new Bundle();
- clirInfo.putIntArray(UT_BUNDLE_KEY_CLIR, ssData.ssInfo);
+ clirInfo.putIntArray(UT_BUNDLE_KEY_CLIR, ssData.getSuppServiceInfo());
onQueryClirComplete(new AsyncResult(null, clirInfo, ex));
} else if (ssData.isTypeCF()) {
Rlog.d(LOG_TAG, "CALL FORWARD INTERROGATION");
onQueryCfComplete(new AsyncResult(null, mPhone
- .handleCfQueryResult(ssData.cfInfo), ex));
+ .handleCfQueryResult(ssData.getCallForwardInfo()), ex));
} else if (ssData.isTypeBarring()) {
- onSuppSvcQueryComplete(new AsyncResult(null, ssData.ssInfo, ex));
+ onSuppSvcQueryComplete(new AsyncResult(null, ssData.getSuppServiceInfo(), ex));
} else if (ssData.isTypeColr() || ssData.isTypeClip() || ssData.isTypeColp()) {
- ImsSsInfo ssInfo = new ImsSsInfo();
- ssInfo.mStatus = ssData.ssInfo[0];
+ int[] suppServiceInfo = ssData.getSuppServiceInfo();
+ ImsSsInfo ssInfo = new ImsSsInfo(suppServiceInfo[0], null);
Bundle clInfo = new Bundle();
clInfo.putParcelable(UT_BUNDLE_KEY_SSINFO, ssInfo);
onSuppSvcQueryComplete(new AsyncResult(null, clInfo, ex));
} else if (ssData.isTypeIcb()) {
- onIcbQueryComplete(new AsyncResult(null, ssData.imsSsInfo, ex));
+ onIcbQueryComplete(new AsyncResult(null, ssData.getImsSpecificSuppServiceInfo(),
+ ex));
} else {
- onQueryComplete(new AsyncResult(null, ssData.ssInfo, ex));
+ onQueryComplete(new AsyncResult(null, ssData.getSuppServiceInfo(), ex));
}
break;
default:
diff --git a/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java b/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
index 530be1d..5004ce7 100644
--- a/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
+++ b/src/java/com/android/internal/telephony/metrics/SmsSessionEventBuilder.java
@@ -88,4 +88,9 @@
mEvent.format = format;
return this;
}
+
+ public SmsSessionEventBuilder setCellBroadcastMessage(SmsSession.Event.CBMessage msg) {
+ mEvent.cellBroadcastMessage = msg;
+ return this;
+ }
}
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 21f8309..8b9d580 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -1705,7 +1705,7 @@
* @param tech SMS RAT
* @param format SMS format. Either 3GPP or 3GPP2.
*/
- public void writeRilSendSms(int phoneId, int rilSerial, int tech, int format) {
+ public synchronized void writeRilSendSms(int phoneId, int rilSerial, int tech, int format) {
InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_SEND)
@@ -1724,7 +1724,7 @@
* @param tech SMS RAT
* @param format SMS format. Either 3GPP or 3GPP2.
*/
- public void writeRilNewSms(int phoneId, int tech, int format) {
+ public synchronized void writeRilNewSms(int phoneId, int tech, int format) {
InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_RECEIVED)
@@ -1736,6 +1736,42 @@
}
/**
+ * Write incoming Broadcast SMS event
+ *
+ * @param phoneId Phone id
+ * @param format CB msg format
+ * @param priority CB msg priority
+ * @param isCMAS true if msg is CMAS
+ * @param isETWS true if msg is ETWS
+ * @param serviceCategory Service category of CB msg
+ */
+ public synchronized void writeNewCBSms(int phoneId, int format, int priority, boolean isCMAS,
+ boolean isETWS, int serviceCategory) {
+ InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
+
+ int type;
+ if (isCMAS) {
+ type = SmsSession.Event.CBMessageType.CMAS;
+ } else if (isETWS) {
+ type = SmsSession.Event.CBMessageType.ETWS;
+ } else {
+ type = SmsSession.Event.CBMessageType.OTHER;
+ }
+
+ SmsSession.Event.CBMessage cbm = new SmsSession.Event.CBMessage();
+ cbm.msgFormat = format;
+ cbm.msgPriority = priority + 1;
+ cbm.msgType = type;
+ cbm.serviceCategory = serviceCategory;
+
+ smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.CB_SMS_RECEIVED)
+ .setCellBroadcastMessage(cbm)
+ );
+
+ finishSmsSessionIfNeeded(smsSession);
+ }
+
+ /**
* Write NITZ event
*
* @param phoneId Phone id
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index a59e186..361f70b 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -46,7 +46,9 @@
public static final String EXTRA_ICC_CARD_ADDED =
"com.android.internal.telephony.uicc.ICC_CARD_ADDED";
- private final Object mLock = new Object();
+ // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
+ // between UiccSlot, UiccCard and UiccProfile for now.
+ private final Object mLock;
private CardState mCardState;
private String mIccid;
protected String mCardId;
@@ -55,10 +57,11 @@
private CommandsInterface mCi;
private final int mPhoneId;
- public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
+ public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
if (DBG) log("Creating");
mCardState = ics.mCardState;
mPhoneId = phoneId;
+ mLock = lock;
update(c, ci, ics);
}
@@ -83,7 +86,7 @@
if (mCardState != CardState.CARDSTATE_ABSENT) {
if (mUiccProfile == null) {
mUiccProfile = TelephonyComponentFactory.getInstance().makeUiccProfile(
- mContext, mCi, ics, mPhoneId, this);
+ mContext, mCi, ics, mPhoneId, this, mLock);
} else {
mUiccProfile.update(mContext, mCi, ics);
}
@@ -227,13 +230,13 @@
*
* A null aid implies a card level reset - all applications must be reset.
*
- * @deprecated Please use {@link UiccProfile#resetAppWithAid(String)} instead.
+ * @deprecated Please use {@link UiccProfile#resetAppWithAid(String, boolean)} instead.
*/
@Deprecated
- public boolean resetAppWithAid(String aid) {
+ public boolean resetAppWithAid(String aid, boolean reset) {
synchronized (mLock) {
if (mUiccProfile != null) {
- return mUiccProfile.resetAppWithAid(aid);
+ return mUiccProfile.resetAppWithAid(aid, reset);
} else {
return false;
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 033f0a1..e79329a 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -642,14 +642,17 @@
boolean changed = false;
switch(resp.refreshResult) {
+ // Reset the required apps when we know about the refresh so that
+ // anyone interested does not get stale state.
case IccRefreshResponse.REFRESH_RESULT_RESET:
+ changed = uiccCard.resetAppWithAid(resp.aid, true /* reset */);
+ break;
case IccRefreshResponse.REFRESH_RESULT_INIT:
- // Reset the required apps when we know about the refresh so that
- // anyone interested does not get stale state.
- changed = uiccCard.resetAppWithAid(resp.aid);
- break;
+ // don't dispose CatService on SIM REFRESH of type INIT
+ changed = uiccCard.resetAppWithAid(resp.aid, false /* initialize */);
+ break;
default:
- return;
+ return;
}
if (changed && resp.refreshResult == IccRefreshResponse.REFRESH_RESULT_RESET) {
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index f967d80..e5ee6f9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -88,7 +88,9 @@
private static final String OPERATOR_BRAND_OVERRIDE_PREFIX = "operator_branding_";
- private final Object mLock = new Object();
+ // The lock object is created by UiccSlot that owns the UiccCard that owns this UiccProfile.
+ // This is to share the lock between UiccSlot, UiccCard and UiccProfile for now.
+ private final Object mLock;
private PinState mUniversalPinState;
private int mGsmUmtsSubscriptionAppIndex;
private int mCdmaSubscriptionAppIndex;
@@ -214,8 +216,9 @@
};
public UiccProfile(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId,
- UiccCard uiccCard) {
+ UiccCard uiccCard, Object lock) {
if (DBG) log("Creating profile");
+ mLock = lock;
mUiccCard = uiccCard;
mPhoneId = phoneId;
// set current app type based on phone type - do this before calling update() as that
@@ -1237,8 +1240,12 @@
* Resets the application with the input AID. Returns true if any changes were made.
*
* A null aid implies a card level reset - all applications must be reset.
+ *
+ * @param aid aid of the application which should be reset; null imples all applications
+ * @param reset true if reset is required. false for initialization.
+ * @return boolean indicating if there was any change made as part of the reset
*/
- public boolean resetAppWithAid(String aid) {
+ public boolean resetAppWithAid(String aid, boolean reset) {
synchronized (mLock) {
boolean changed = false;
for (int i = 0; i < mUiccApplications.length; i++) {
@@ -1250,11 +1257,12 @@
changed = true;
}
}
- if (TextUtils.isEmpty(aid)) {
+ if (reset && TextUtils.isEmpty(aid)) {
if (mCarrierPrivilegeRules != null) {
mCarrierPrivilegeRules = null;
changed = true;
}
+ // CatService shall be disposed only when a card level reset happens.
if (mCatService != null) {
mCatService.dispose();
mCatService = null;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index ffaad60..25ef637 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -112,9 +112,9 @@
}
if (!mIsEuicc) {
- mUiccCard = new UiccCard(mContext, mCi, ics, mPhoneId);
+ mUiccCard = new UiccCard(mContext, mCi, ics, mPhoneId, mLock);
} else {
- mUiccCard = new EuiccCard(mContext, mCi, ics, phoneId);
+ mUiccCard = new EuiccCard(mContext, mCi, ics, phoneId, mLock);
}
} else {
if (mUiccCard != null) {
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
index 6acfb80..103c75b 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -116,8 +116,8 @@
private EuiccSpecVersion mSpecVersion;
private volatile String mEid;
- public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
- super(c, ci, ics, phoneId);
+ public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
+ super(c, ci, ics, phoneId, lock);
// TODO: Set supportExtendedApdu based on ATR.
mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */);
diff --git a/src/java/com/android/internal/telephony/util/SMSDispatcherUtil.java b/src/java/com/android/internal/telephony/util/SMSDispatcherUtil.java
index a3c7926..17f2611 100644
--- a/src/java/com/android/internal/telephony/util/SMSDispatcherUtil.java
+++ b/src/java/com/android/internal/telephony/util/SMSDispatcherUtil.java
@@ -36,17 +36,6 @@
private SMSDispatcherUtil() {}
/**
- * Whether to block SMS or not.
- *
- * @param isCdma true if cdma format should be used.
- * @param phone the Phone to use
- * @return true to block sms; false otherwise.
- */
- public static boolean shouldBlockSms(boolean isCdma, Phone phone) {
- return isCdma && phone.isInEcm();
- }
-
- /**
* Trigger the proper implementation for getting submit pdu for text sms based on format.
*
* @param isCdma true if cdma format should be used.
diff --git a/src/java/com/android/internal/telephony/util/TimeStampedValue.java b/src/java/com/android/internal/telephony/util/TimeStampedValue.java
deleted file mode 100644
index e2628f6..0000000
--- a/src/java/com/android/internal/telephony/util/TimeStampedValue.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.util;
-
-import android.os.SystemClock;
-
-/**
- * A pair containing a value and an associated time stamp.
- *
- * @param <T> The type of the value.
- */
-public final class TimeStampedValue<T> {
-
- /** The value. */
- public final T mValue;
-
- /**
- * The value of {@link SystemClock#elapsedRealtime} or equivalent when value was
- * determined.
- */
- public final long mElapsedRealtime;
-
- public TimeStampedValue(T value, long elapsedRealtime) {
- this.mValue = value;
- this.mElapsedRealtime = elapsedRealtime;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- TimeStampedValue<?> that = (TimeStampedValue<?>) o;
-
- if (mElapsedRealtime != that.mElapsedRealtime) {
- return false;
- }
- return mValue != null ? mValue.equals(that.mValue) : that.mValue == null;
- }
-
- @Override
- public int hashCode() {
- int result = mValue != null ? mValue.hashCode() : 0;
- result = 31 * result + (int) (mElapsedRealtime ^ (mElapsedRealtime >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "TimeStampedValue{"
- + "mValue=" + mValue
- + ", elapsedRealtime=" + mElapsedRealtime
- + '}';
- }
-}
diff --git a/tests/telephonytests/Android.mk b/tests/telephonytests/Android.mk
index 3356e68..6709d46 100644
--- a/tests/telephonytests/Android.mk
+++ b/tests/telephonytests/Android.mk
@@ -20,7 +20,4 @@
LOCAL_COMPATIBILITY_SUITE := device-tests
-# b/72575505
-LOCAL_ERROR_PRONE_FLAGS := -Xep:JUnit4TestNotRun:WARN
-
include $(BUILD_PACKAGE)
diff --git a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index ccbc251..6be2fb0 100644
--- a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -17,14 +17,19 @@
package android.telephony.ims;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
-import android.os.RemoteException;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
import android.support.test.runner.AndroidJUnit4;
+import android.telecom.TelecomManager;
import android.telephony.ims.aidl.IImsMmTelFeature;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
@@ -32,6 +37,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.internal.IImsCallSession;
+import com.android.internal.telephony.ims.ImsTestBase;
import org.junit.After;
import org.junit.Before;
@@ -41,23 +47,55 @@
import org.mockito.Mockito;
@RunWith(AndroidJUnit4.class)
-public class MmTelFeatureTests {
+public class MmTelFeatureTests extends ImsTestBase {
private static final int TEST_CAPABILITY = 1;
private static final int TEST_RADIO_TECH = 0;
+ private static final int TEST_TTY_RESULT = 0;
+ private static final int TEST_SEND_DTMF_RESULT = 1;
+ private static final int TEST_RESULT_MAX = 2;
+
+ private static final int TEST_RESULT_DELAY_MS = 5000;
+
private android.telephony.ims.TestMmTelFeature mFeature;
private IImsMmTelFeature mFeatureBinder;
private ImsFeature.CapabilityCallback mCapabilityCallback;
private MmTelFeature.Listener mListener;
+ // set to true when the handler receives a message back from the Feature.
+ private boolean[] mHandlerResults;
+
+ private class TestHandler extends Handler {
+
+ TestHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case TEST_TTY_RESULT:
+ mHandlerResults[TEST_TTY_RESULT] = true;
+ break;
+ case TEST_SEND_DTMF_RESULT:
+ mHandlerResults[TEST_SEND_DTMF_RESULT] = true;
+ break;
+ }
+ }
+ }
+ private final Handler mHandler = new TestHandler(Looper.getMainLooper());
+ private final Messenger mHandlerMessenger = new Messenger(mHandler);
+
@Before
- public void setup() throws RemoteException {
+ public void setup() throws Exception {
+ super.setUp();
mFeature = new TestMmTelFeature();
mFeatureBinder = mFeature.getBinder();
mCapabilityCallback = spy(new ImsFeature.CapabilityCallback());
mListener = spy(new MmTelFeature.Listener());
mFeatureBinder.setListener(mListener);
+ mHandlerResults = new boolean[TEST_RESULT_MAX];
}
@After
@@ -91,4 +129,25 @@
assertEquals(sessionBinder, captor.getValue());
}
+
+ @SmallTest
+ @Test
+ public void testSetTtyMessageMessenger() throws Exception {
+ Message resultMessage = Message.obtain(mHandler, TEST_TTY_RESULT);
+ resultMessage.replyTo = mHandlerMessenger;
+ mFeatureBinder.setUiTtyMode(TelecomManager.TTY_MODE_FULL, resultMessage);
+ waitForHandlerAction(mHandler, TEST_RESULT_DELAY_MS);
+ assertTrue(mHandlerResults[TEST_TTY_RESULT]);
+ }
+
+ @SmallTest
+ @Test
+ public void testSendDtmfMessageMessenger() throws Exception {
+ Message resultMessage = Message.obtain(mHandler, TEST_SEND_DTMF_RESULT);
+ resultMessage.replyTo = mHandlerMessenger;
+ IImsCallSession callSession = mFeatureBinder.createCallSession(null);
+ callSession.sendDtmf('0', resultMessage);
+ waitForHandlerAction(mHandler, TEST_RESULT_DELAY_MS);
+ assertTrue(mHandlerResults[TEST_SEND_DTMF_RESULT]);
+ }
}
diff --git a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
index 795d1c0..6414403 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
@@ -16,6 +16,7 @@
package android.telephony.ims;
+import android.os.Message;
import android.os.RemoteException;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
@@ -33,6 +34,22 @@
public CapabilityChangeRequest lastRequest;
public boolean isUtInterfaceCalled = false;
+ private final TestImsCallSession mCallSession = new TestImsCallSession();
+ private class TestImsCallSession extends ImsCallSessionImplBase {
+
+ @Override
+ public void sendDtmf(char c, Message result) {
+ // Just call result to signify complete for test.
+ if (result.replyTo != null) {
+ try {
+ result.replyTo.send(result);
+ } catch (RemoteException e) {
+ // eat error, test will fail.
+ }
+ }
+ }
+ }
+
public void incomingCall(ImsCallSessionImplBase c) throws RemoteException {
notifyIncomingCall(c, null);
}
@@ -44,7 +61,7 @@
@Override
public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) {
- return super.createCallSession(profile);
+ return mCallSession;
}
@Override
@@ -64,6 +81,16 @@
}
@Override
+ public void setUiTtyMode(int mode, Message onCompleteMessage) {
+ try {
+ // just send complete message.
+ onCompleteMessage.replyTo.send(onCompleteMessage);
+ } catch (RemoteException e) {
+ // do nothing, test will fail.
+ }
+ }
+
+ @Override
public boolean queryCapabilityConfiguration(@MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
// Base implementation - Override to provide functionality
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
index 8be2f60..bd20e4a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
@@ -16,22 +16,10 @@
package com.android.internal.telephony;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.res.Resources;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isA;
@@ -39,6 +27,28 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Map;
+
/**
* Unit tests for {@link com.android.internal.telephony.CarrierServiceStateTracker}.
*/
@@ -47,25 +57,34 @@
public static final String LOG_TAG = "CSST";
public static final int TEST_TIMEOUT = 5000;
+ private CarrierServiceStateTracker mSpyCarrierSST;
private CarrierServiceStateTracker mCarrierSST;
private CarrierServiceStateTrackerTestHandler mCarrierServiceStateTrackerTestHandler;
- private CarrierServiceStateTracker.PrefNetworkNotification mPrefNetworkNotification;
- private CarrierServiceStateTracker.EmergencyNetworkNotification mEmergencyNetworkNotification;
+ private FakeContentResolver mFakeContentResolver;
- @Mock Context mContext;
- @Mock ServiceStateTracker mServiceStateTracker;
- @Mock NotificationManager mNotificationManager;
- @Mock Resources mResources;
+ NotificationManager mNotificationManager;
+ PersistableBundle mBundle;
+
+ private class FakeContentResolver extends MockContentResolver {
+ @Override
+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+ super.notifyChange(uri, observer, syncToNetwork);
+ logd("onChanged(uri=" + uri + ")" + observer);
+ if (observer != null) {
+ observer.dispatchChange(false, uri);
+ }
+ }
+ }
private class CarrierServiceStateTrackerTestHandler extends HandlerThread {
-
private CarrierServiceStateTrackerTestHandler(String name) {
super(name);
}
@Override
public void onLooperPrepared() {
- mCarrierSST = spy(new CarrierServiceStateTracker(mPhone, mServiceStateTracker));
+ mCarrierSST = new CarrierServiceStateTracker(mPhone, mSST);
+ mSpyCarrierSST = spy(mCarrierSST);
setReady(true);
}
}
@@ -75,15 +94,29 @@
MockitoAnnotations.initMocks(this);
logd(LOG_TAG + "Setup!");
super.setUp(getClass().getSimpleName());
+ mBundle = mContextFixture.getCarrierConfigBundle();
+ when(mPhone.getSubId()).thenReturn(1);
mCarrierServiceStateTrackerTestHandler =
new CarrierServiceStateTrackerTestHandler(getClass().getSimpleName());
mCarrierServiceStateTrackerTestHandler.start();
- when(mContext.getResources()).thenReturn(mResources);
- when(mContext.getPackageManager()).thenReturn(mPackageManager);
- when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
+ mFakeContentResolver = new CarrierServiceStateTrackerTest.FakeContentResolver();
+
+ when(mPhone.getContext().getContentResolver()).thenReturn(mFakeContentResolver);
+
+ mNotificationManager = (NotificationManager) mContext.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+
+ setDefaultValues();
waitUntilReady();
}
+ private void setDefaultValues() {
+ mBundle.putInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT,
+ 0);
+ mBundle.putInt(CarrierConfigManager.KEY_EMERGENCY_NOTIFICATION_DELAY_INT,
+ 0);
+ }
+
@After
public void tearDown() throws Exception {
mCarrierServiceStateTrackerTestHandler.quit();
@@ -94,12 +127,12 @@
@SmallTest
public void testCancelBothNotifications() {
logd(LOG_TAG + ":testCancelBothNotifications()");
- Message notificationMsg = mCarrierSST.obtainMessage(
+ Message notificationMsg = mSpyCarrierSST.obtainMessage(
CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null);
- doReturn(false).when(mCarrierSST).evaluateSendingMessage(any());
- doReturn(mNotificationManager).when(mCarrierSST).getNotificationManager(any());
- mCarrierSST.handleMessage(notificationMsg);
- waitForHandlerAction(mCarrierSST, TEST_TIMEOUT);
+ doReturn(false).when(mSpyCarrierSST).evaluateSendingMessage(any());
+ doReturn(mNotificationManager).when(mSpyCarrierSST).getNotificationManager(any());
+ mSpyCarrierSST.handleMessage(notificationMsg);
+ waitForHandlerAction(mSpyCarrierSST, TEST_TIMEOUT);
verify(mNotificationManager).cancel(
CarrierServiceStateTracker.NOTIFICATION_EMERGENCY_NETWORK);
verify(mNotificationManager).cancel(
@@ -111,18 +144,58 @@
public void testSendBothNotifications() {
logd(LOG_TAG + ":testSendBothNotifications()");
Notification.Builder mNotificationBuilder = new Notification.Builder(mContext);
- Message notificationMsg = mCarrierSST.obtainMessage(
+ Message notificationMsg = mSpyCarrierSST.obtainMessage(
CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null);
- doReturn(true).when(mCarrierSST).evaluateSendingMessage(any());
- doReturn(false).when(mCarrierSST).isRadioOffOrAirplaneMode();
- doReturn(0).when(mCarrierSST).getDelay(any());
- doReturn(mNotificationBuilder).when(mCarrierSST).getNotificationBuilder(any());
- doReturn(mNotificationManager).when(mCarrierSST).getNotificationManager(any());
- mCarrierSST.handleMessage(notificationMsg);
- waitForHandlerAction(mCarrierSST, TEST_TIMEOUT);
+ doReturn(true).when(mSpyCarrierSST).evaluateSendingMessage(any());
+ doReturn(false).when(mSpyCarrierSST).isRadioOffOrAirplaneMode();
+ doReturn(0).when(mSpyCarrierSST).getDelay(any());
+ doReturn(mNotificationBuilder).when(mSpyCarrierSST).getNotificationBuilder(any());
+ doReturn(mNotificationManager).when(mSpyCarrierSST).getNotificationManager(any());
+ mSpyCarrierSST.handleMessage(notificationMsg);
+ waitForHandlerAction(mSpyCarrierSST, TEST_TIMEOUT);
verify(mNotificationManager).notify(
eq(CarrierServiceStateTracker.NOTIFICATION_PREF_NETWORK), isA(Notification.class));
verify(mNotificationManager).notify(
eq(CarrierServiceStateTracker.NOTIFICATION_EMERGENCY_NETWORK), any());
}
+
+ @Test
+ @SmallTest
+ public void testSendPrefNetworkNotification() {
+ logd(LOG_TAG + ":testSendPrefNetworkNotification()");
+ Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+ mContext.sendBroadcast(intent);
+ waitForMs(300);
+
+ Map<Integer, CarrierServiceStateTracker.NotificationType> notificationTypeMap =
+ mCarrierSST.getNotificationTypeMap();
+ CarrierServiceStateTracker.NotificationType prefNetworkNotification =
+ notificationTypeMap.get(CarrierServiceStateTracker.NOTIFICATION_PREF_NETWORK);
+ CarrierServiceStateTracker.NotificationType spyPrefNetworkNotification = spy(
+ prefNetworkNotification);
+ notificationTypeMap.put(CarrierServiceStateTracker.NOTIFICATION_PREF_NETWORK,
+ spyPrefNetworkNotification);
+ Notification.Builder mNotificationBuilder = new Notification.Builder(mContext);
+ doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST.mSS).getVoiceRegState();
+ doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST.mSS).getDataRegState();
+ doReturn(true).when(mSST).isRadioOn();
+ doReturn(mNotificationBuilder).when(spyPrefNetworkNotification).getNotificationBuilder();
+
+ String prefNetworkMode = Settings.Global.PREFERRED_NETWORK_MODE + mPhone.getSubId();
+ Settings.Global.putInt(mFakeContentResolver, prefNetworkMode,
+ RILConstants.NETWORK_MODE_LTE_CDMA_EVDO);
+ mFakeContentResolver.notifyChange(
+ Settings.Global.getUriFor(prefNetworkMode), mSpyCarrierSST.getContentObserver());
+ waitForMs(500);
+ verify(mNotificationManager).notify(
+ eq(CarrierServiceStateTracker.NOTIFICATION_PREF_NETWORK), isA(Notification.class));
+
+ Settings.Global.putInt(mFakeContentResolver, prefNetworkMode,
+ RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
+ mFakeContentResolver.notifyChange(
+ Settings.Global.getUriFor(prefNetworkMode), mSpyCarrierSST.getContentObserver());
+ waitForMs(500);
+ verify(mNotificationManager, atLeast(1)).cancel(
+ CarrierServiceStateTracker.NOTIFICATION_PREF_NETWORK);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityTdscdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityTdscdmaTest.java
index 1cdf18ca..5915062 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityTdscdmaTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityTdscdmaTest.java
@@ -33,7 +33,7 @@
// Tracking area code ranges from 0 to 65535.
private static final int TAC = 65535;
// Absolute RF Channel Number ranges from 0 to 262140.
- private static final int EARFCN = 262140;
+ private static final int UARFCN = 262140;
private static final int MCC = 120;
private static final int MNC = 260;
private static final String MCC_STR = "120";
@@ -52,33 +52,38 @@
@SmallTest
public void testDefaultConstructor() {
CellIdentityTdscdma ci =
- new CellIdentityTdscdma(MCC_STR, MNC_STR, LAC, CID, CPID);
+ new CellIdentityTdscdma(
+ MCC_STR, MNC_STR, LAC, CID, CPID, UARFCN, ALPHA_LONG, ALPHA_SHORT);
assertEquals(MCC_STR, ci.getMccString());
assertEquals(MNC_STR, ci.getMncString());
assertEquals(LAC, ci.getLac());
assertEquals(CID, ci.getCid());
assertEquals(CPID, ci.getCpid());
+ assertEquals(UARFCN, ci.getChannelNumber());
+ assertEquals(ALPHA_LONG, ci.getOperatorAlphaLong());
+ assertEquals(ALPHA_SHORT, ci.getOperatorAlphaShort());
}
@SmallTest
public void testConstructorWithEmptyMccMnc() {
- CellIdentityTdscdma ci = new CellIdentityTdscdma(null, null, LAC, CID, CPID);
+ CellIdentityTdscdma ci = new CellIdentityTdscdma(
+ null, null, LAC, CID, CPID, UARFCN, "", "");
assertNull(ci.getMccString());
assertNull(ci.getMncString());
- ci = new CellIdentityTdscdma(MCC_STR, null, LAC, CID, CPID);
+ ci = new CellIdentityTdscdma(MCC_STR, null, LAC, CID, CPID, UARFCN, "", "");
assertEquals(MCC_STR, ci.getMccString());
assertNull(ci.getMncString());
- ci = new CellIdentityTdscdma(null, MNC_STR, LAC, CID, CPID);
+ ci = new CellIdentityTdscdma(null, MNC_STR, LAC, CID, CPID, UARFCN, "", "");
assertEquals(MNC_STR, ci.getMncString());
assertNull(ci.getMccString());
- ci = new CellIdentityTdscdma("", "", LAC, CID, CPID);
+ ci = new CellIdentityTdscdma("", "", LAC, CID, CPID, UARFCN, "", "");
assertNull(ci.getMccString());
assertNull(ci.getMncString());
@@ -86,7 +91,8 @@
@SmallTest
public void testParcel() {
- CellIdentityTdscdma ci = new CellIdentityTdscdma(MCC_STR, MNC_STR, LAC, CID, CPID);
+ CellIdentityTdscdma ci = new CellIdentityTdscdma(
+ MCC_STR, MNC_STR, LAC, CID, UARFCN, CPID, ALPHA_LONG, ALPHA_SHORT);
Parcel p = Parcel.obtain();
ci.writeToParcel(p, 0);
@@ -99,7 +105,8 @@
@SmallTest
public void testParcelWithUnknowMccMnc() {
CellIdentityTdscdma ci =
- new CellIdentityTdscdma(null, null, LAC, CID, CPID, ALPHA_LONG, ALPHA_SHORT);
+ new CellIdentityTdscdma(
+ null, null, LAC, CID, CPID, UARFCN, ALPHA_LONG, ALPHA_SHORT);
Parcel p = Parcel.obtain();
p.writeInt(CellIdentity.TYPE_TDSCDMA);
@@ -110,6 +117,7 @@
p.writeInt(LAC);
p.writeInt(CID);
p.writeInt(CPID);
+ p.writeInt(UARFCN);
p.setDataPosition(0);
CellIdentityTdscdma newCi = CellIdentityTdscdma.CREATOR.createFromParcel(p);
@@ -121,7 +129,8 @@
final String invalidMcc = "randomStuff";
final String invalidMnc = "randomStuff";
CellIdentityTdscdma ci =
- new CellIdentityTdscdma(null, null, LAC, CID, CPID, ALPHA_LONG, ALPHA_SHORT);
+ new CellIdentityTdscdma(
+ null, null, LAC, CID, CPID, UARFCN, ALPHA_LONG, ALPHA_SHORT);
Parcel p = Parcel.obtain();
p.writeInt(CellIdentity.TYPE_TDSCDMA);
@@ -132,6 +141,7 @@
p.writeInt(LAC);
p.writeInt(CID);
p.writeInt(CPID);
+ p.writeInt(UARFCN);
p.setDataPosition(0);
CellIdentityTdscdma newCi = CellIdentityTdscdma.CREATOR.createFromParcel(p);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
index 16bc535..a595c36 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
@@ -54,7 +54,7 @@
mCellularNetworkService = new CellularNetworkService();
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = "com.android.phone";
- serviceInfo.permission = "android.permission.BIND_NETWORK_SERVICE";
+ serviceInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
IntentFilter filter = new IntentFilter();
mContextFixture.addService(
NetworkService.NETWORK_SERVICE_INTERFACE,
@@ -132,7 +132,7 @@
waitForMs(1000);
NetworkRegistrationState expectedState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WWAN, domain, voiceRegState,
+ domain, AccessNetworkConstants.TransportType.WWAN, voiceRegState,
ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
false, availableServices, null, cssSupported,
roamingIndicator, systemIsInPrl, defaultRoamingIndicator);
@@ -155,7 +155,7 @@
waitForMs(1000);
expectedState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WWAN, domain, voiceRegState,
+ domain, AccessNetworkConstants.TransportType.WWAN, voiceRegState,
ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
false, availableServices, null, maxDataCalls);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 1d08c42..d2e28ca 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -40,6 +40,7 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -278,6 +279,11 @@
}
@Override
+ public ApplicationInfo getApplicationInfo() {
+ return mApplicationInfo;
+ }
+
+ @Override
public String getOpPackageName() {
return "com.android.internal.telephony";
}
@@ -526,6 +532,7 @@
// when(...) logic to be used to add specific little responses where needed.
private final Resources mResources = mock(Resources.class);
+ private final ApplicationInfo mApplicationInfo = mock(ApplicationInfo.class);
private final PackageManager mPackageManager = mock(PackageManager.class);
private final TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
private final DownloadManager mDownloadManager = mock(DownloadManager.class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 00383a5..77eb7dc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -403,7 +403,7 @@
// voicemail number from sharedPreference
mPhoneUT.setVoiceMailNumber("alphaTag", voiceMailNumber, null);
ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mRuimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
+ verify(mSimRecords).setVoiceMailNumber(eq("alphaTag"), eq(voiceMailNumber),
messageArgumentCaptor.capture());
Message msg = messageArgumentCaptor.getValue();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
new file mode 100644
index 0000000..bcc1730
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2018 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 static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.AsyncResult;
+import android.os.HandlerThread;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellInfoGsm;
+import android.telephony.ServiceState;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+public class LocaleTrackerTest extends TelephonyTest {
+
+ private static final String US_MCC = "310";
+ private static final String FAKE_MNC = "123";
+ private static final String US_COUNTRY_CODE = "us";
+ private static final String COUNTRY_CODE_UNAVAILABLE = "";
+
+ private LocaleTracker mLocaleTracker;
+ private LocaleTrackerTestHandler mLocaleTrackerTestHandler;
+
+ private CellInfoGsm mCellInfo;
+ private WifiManager mWifiManager;
+
+ private class LocaleTrackerTestHandler extends HandlerThread {
+
+ private LocaleTrackerTestHandler(String name) {
+ super(name);
+ }
+
+ @Override
+ public void onLooperPrepared() {
+ mLocaleTracker = new LocaleTracker(mPhone, this.getLooper());
+ setReady(true);
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ logd("LocaleTrackerTest +Setup!");
+ super.setUp(getClass().getSimpleName());
+
+ // This is a workaround to bypass setting system properties, which causes access violation.
+ doReturn(-1).when(mPhone).getPhoneId();
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+
+ mCellInfo = new CellInfoGsm();
+ mCellInfo.setCellIdentity(new CellIdentityGsm(Integer.parseInt(US_MCC),
+ Integer.parseInt(FAKE_MNC), 0, 0));
+ doReturn(Arrays.asList(mCellInfo)).when(mPhone).getAllCellInfo(isNull());
+ doReturn(true).when(mSST).getDesiredPowerState();
+
+ mLocaleTrackerTestHandler = new LocaleTrackerTestHandler(getClass().getSimpleName());
+ mLocaleTrackerTestHandler.start();
+ waitUntilReady();
+ logd("LocaleTrackerTest -Setup!");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mLocaleTracker.removeCallbacksAndMessages(null);
+ mLocaleTrackerTestHandler.quit();
+ super.tearDown();
+ }
+
+ @Test
+ @SmallTest
+ public void testUpdateOperatorNumericSync() throws Exception {
+ mLocaleTracker.updateOperatorNumericSync(US_MCC + FAKE_MNC);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testUpdateOperatorNumericAsync() throws Exception {
+ mLocaleTracker.updateOperatorNumericAsync(US_MCC + FAKE_MNC);
+ waitForMs(100);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testNoSim() throws Exception {
+ mLocaleTracker.updateOperatorNumericAsync("");
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testBootupInAirplaneModeOn() throws Exception {
+ doReturn(false).when(mSST).getDesiredPowerState();
+ mLocaleTracker.updateOperatorNumericAsync("");
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(COUNTRY_CODE_UNAVAILABLE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(COUNTRY_CODE_UNAVAILABLE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testTogglingAirplaneMode() throws Exception {
+ mLocaleTracker.updateOperatorNumericSync(US_MCC + FAKE_MNC);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+
+ doReturn(false).when(mSST).getDesiredPowerState();
+ mLocaleTracker.updateOperatorNumericAsync("");
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(COUNTRY_CODE_UNAVAILABLE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(COUNTRY_CODE_UNAVAILABLE, false);
+
+ doReturn(true).when(mSST).getDesiredPowerState();
+ mLocaleTracker.updateOperatorNumericSync(US_MCC + FAKE_MNC);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager, times(2)).setCountryCode(US_COUNTRY_CODE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testCellInfoUnavailableRetry() throws Exception {
+ doReturn(null).when(mPhone).getAllCellInfo(isNull());
+ mLocaleTracker.updateOperatorNumericAsync("");
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(COUNTRY_CODE_UNAVAILABLE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(COUNTRY_CODE_UNAVAILABLE, false);
+
+ doReturn(Arrays.asList(mCellInfo)).when(mPhone).getAllCellInfo(isNull());
+ waitForHandlerActionDelayed(mLocaleTracker, 100, 2500);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testOutOfAirplaneMode() throws Exception {
+ doReturn(null).when(mPhone).getAllCellInfo(isNull());
+ mLocaleTracker.updateOperatorNumericAsync("");
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(COUNTRY_CODE_UNAVAILABLE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(COUNTRY_CODE_UNAVAILABLE, false);
+
+ doReturn(Arrays.asList(mCellInfo)).when(mPhone).getAllCellInfo(isNull());
+ ServiceState ss = new ServiceState();
+ ss.setState(ServiceState.STATE_IN_SERVICE);
+ AsyncResult ar = new AsyncResult(null, ss, null);
+ mLocaleTracker.sendMessage(mLocaleTracker.obtainMessage(3, ar));
+ waitForHandlerAction(mLocaleTracker, 100);
+ assertEquals(US_COUNTRY_CODE, mLocaleTracker.getCurrentCountry());
+ verify(mWifiManager).setCountryCode(US_COUNTRY_CODE, false);
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
new file mode 100644
index 0000000..eb52e7c
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkRegistrationStateTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 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 static junit.framework.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.CellIdentityLte;
+import android.telephony.NetworkRegistrationState;
+import android.telephony.TelephonyManager;
+
+import org.junit.Test;
+
+/** Unit tests for {@link NetworkRegistrationState}. */
+
+public class NetworkRegistrationStateTest {
+
+ @Test
+ @SmallTest
+ public void testParcel() {
+ NetworkRegistrationState nrs = new NetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_CS,
+ TransportType.WWAN,
+ NetworkRegistrationState.REG_STATE_HOME,
+ TelephonyManager.NETWORK_TYPE_LTE,
+ 0,
+ false,
+ new int[]{NetworkRegistrationState.SERVICE_TYPE_DATA},
+ new CellIdentityLte());
+
+ Parcel p = Parcel.obtain();
+ nrs.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ NetworkRegistrationState newNrs = NetworkRegistrationState.CREATOR.createFromParcel(p);
+ assertEquals(nrs, newNrs);
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NewNitzStateMachineTest.java b/tests/telephonytests/src/com/android/internal/telephony/NewNitzStateMachineTest.java
new file mode 100644
index 0000000..028cbcc
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/NewNitzStateMachineTest.java
@@ -0,0 +1,970 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.TimeZone;
+import android.util.TimestampedValue;
+
+import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult;
+import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class NewNitzStateMachineTest extends TelephonyTest {
+
+ // A country with a single zone : the zone can be guessed from the country.
+ // The UK uses UTC for part of the year so it is not good for detecting bogus NITZ signals.
+ private static final Scenario UNITED_KINGDOM_SCENARIO = new Scenario.Builder()
+ .setInitialDeviceSystemClockUtc(1977, 1, 1, 12, 0, 0)
+ .setInitialDeviceRealtimeMillis(123456789L)
+ .setTimeZone("Europe/London")
+ .setActualTimeUtc(2018, 1, 1, 12, 0, 0)
+ .setCountryIso("gb")
+ .build();
+
+ // A country that has multiple zones, but there is only one matching time zone at the time :
+ // the zone cannot be guessed from the country alone, but can be guessed from the country +
+ // NITZ. The US never uses UTC so it can be used for testing bogus NITZ signal handling.
+ private static final Scenario UNIQUE_US_ZONE_SCENARIO = new Scenario.Builder()
+ .setInitialDeviceSystemClockUtc(1977, 1, 1, 12, 0, 0)
+ .setInitialDeviceRealtimeMillis(123456789L)
+ .setTimeZone("America/Los_Angeles")
+ .setActualTimeUtc(2018, 1, 1, 12, 0, 0)
+ .setCountryIso("us")
+ .build();
+
+ // A country with a single zone: the zone can be guessed from the country alone. CZ never uses
+ // UTC so it can be used for testing bogus NITZ signal handling.
+ private static final Scenario CZECHIA_SCENARIO = new Scenario.Builder()
+ .setInitialDeviceSystemClockUtc(1977, 1, 1, 12, 0, 0)
+ .setInitialDeviceRealtimeMillis(123456789L)
+ .setTimeZone("Europe/Prague")
+ .setActualTimeUtc(2018, 1, 1, 12, 0, 0)
+ .setCountryIso("cz")
+ .build();
+
+ @Mock
+ private NewNitzStateMachine.DeviceState mDeviceState;
+
+ @Mock
+ private NewTimeServiceHelper mTimeServiceHelper;
+
+ private TimeZoneLookupHelper mRealTimeZoneLookupHelper;
+
+ private NewNitzStateMachine mNitzStateMachine;
+
+ @Before
+ public void setUp() throws Exception {
+ logd("NitzStateMachineTest +Setup!");
+ super.setUp("NitzStateMachineTest");
+
+ // In tests we use the real TimeZoneLookupHelper.
+ mRealTimeZoneLookupHelper = new TimeZoneLookupHelper();
+ mNitzStateMachine = new NewNitzStateMachine(
+ mPhone, mTimeServiceHelper, mDeviceState, mRealTimeZoneLookupHelper);
+
+ logd("ServiceStateTrackerTest -Setup!");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ checkNoUnverifiedSetOperations(mTimeServiceHelper);
+
+ super.tearDown();
+ }
+
+ @Test
+ public void test_uniqueUsZone_Assumptions() {
+ // Check we'll get the expected behavior from TimeZoneLookupHelper.
+
+ // allZonesHaveSameOffset == false, so we shouldn't pick an arbitrary zone.
+ CountryResult expectedCountryLookupResult = new CountryResult(
+ "America/New_York", false /* allZonesHaveSameOffset */,
+ UNIQUE_US_ZONE_SCENARIO.getInitialSystemClockMillis());
+ CountryResult actualCountryLookupResult =
+ mRealTimeZoneLookupHelper.lookupByCountry(
+ UNIQUE_US_ZONE_SCENARIO.getNetworkCountryIsoCode(),
+ UNIQUE_US_ZONE_SCENARIO.getInitialSystemClockMillis());
+ assertEquals(expectedCountryLookupResult, actualCountryLookupResult);
+
+ // isOnlyMatch == true, so the combination of country + NITZ should be enough.
+ OffsetResult expectedLookupResult =
+ new OffsetResult("America/Los_Angeles", true /* isOnlyMatch */);
+ OffsetResult actualLookupResult = mRealTimeZoneLookupHelper.lookupByNitzCountry(
+ UNIQUE_US_ZONE_SCENARIO.getNitzSignal().getValue(),
+ UNIQUE_US_ZONE_SCENARIO.getNetworkCountryIsoCode());
+ assertEquals(expectedLookupResult, actualLookupResult);
+ }
+
+ @Test
+ public void test_unitedKingdom_Assumptions() {
+ // Check we'll get the expected behavior from TimeZoneLookupHelper.
+
+ // allZonesHaveSameOffset == true (not only that, there is only one zone), so we can pick
+ // the zone knowing only the country.
+ CountryResult expectedCountryLookupResult = new CountryResult(
+ "Europe/London", true /* allZonesHaveSameOffset */,
+ UNITED_KINGDOM_SCENARIO.getInitialSystemClockMillis());
+ CountryResult actualCountryLookupResult =
+ mRealTimeZoneLookupHelper.lookupByCountry(
+ UNITED_KINGDOM_SCENARIO.getNetworkCountryIsoCode(),
+ UNITED_KINGDOM_SCENARIO.getInitialSystemClockMillis());
+ assertEquals(expectedCountryLookupResult, actualCountryLookupResult);
+
+ OffsetResult expectedLookupResult =
+ new OffsetResult("Europe/London", true /* isOnlyMatch */);
+ OffsetResult actualLookupResult = mRealTimeZoneLookupHelper.lookupByNitzCountry(
+ UNITED_KINGDOM_SCENARIO.getNitzSignal().getValue(),
+ UNITED_KINGDOM_SCENARIO.getNetworkCountryIsoCode());
+ assertEquals(expectedLookupResult, actualLookupResult);
+ }
+
+ @Test
+ public void test_uniqueUsZone_timeZoneEnabled_countryThenNitz() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // Country won't be enough for time zone detection.
+ .verifyNothingWasSetAndReset()
+ .nitzReceived(scenario.getNitzSignal())
+ // Country + NITZ is enough for both time + time zone detection.
+ .verifyTimeSuggestedAndZoneSetAndReset(
+ scenario.getNitzSignal(), scenario.getTimeZoneId());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_unitedKingdom_timeZoneEnabled_countryThenNitz() throws Exception {
+ Scenario scenario = UNITED_KINGDOM_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // Country alone is enough to guess the time zone.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId())
+ .nitzReceived(scenario.getNitzSignal())
+ // Country + NITZ is enough for both time + time zone detection.
+ .verifyTimeSuggestedAndZoneSetAndReset(
+ scenario.getNitzSignal(), scenario.getTimeZoneId());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_uniqueUsZone_timeZoneDisabled_countryThenNitz() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(false)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // Country is not enough to guess the time zone and time zone detection is disabled.
+ .verifyNothingWasSetAndReset()
+ .nitzReceived(scenario.getNitzSignal())
+ // Time zone detection is disabled, but time should be suggested from NITZ.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_unitedKingdom_timeZoneDisabled_countryThenNitz() throws Exception {
+ Scenario scenario = UNITED_KINGDOM_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(false)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // Country alone would be enough for time zone detection, but it's disabled.
+ .verifyNothingWasSetAndReset()
+ .nitzReceived(scenario.getNitzSignal())
+ // Time zone detection is disabled, but time should be suggested from NITZ.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_uniqueUsZone_timeZoneEnabled_nitzThenCountry() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(scenario.getNitzSignal())
+ // The NITZ alone isn't enough to detect a time zone.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The NITZ + country is enough to detect the time zone.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_unitedKingdom_timeZoneEnabled_nitzThenCountry() throws Exception {
+ Scenario scenario = UNITED_KINGDOM_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(false)
+ .initialize();
+ Script script = new Script(device);
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(scenario.getNitzSignal())
+ // The NITZ alone isn't enough to detect a time zone.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode());
+
+ // The NITZ + country is enough to detect the time zone.
+ // NOTE: setting the time zone happens twice because of a quirk in NitzStateMachine: it
+ // handles the country lookup / set, then combines the country with the NITZ state and does
+ // another lookup / set. We shouldn't require it is set twice but we do for simplicity.
+ script.verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId(), 2 /* times */);
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_validCzNitzSignal_nitzReceivedFirst() throws Exception {
+ Scenario scenario = CZECHIA_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(goodNitzSignal)
+ // The NITZ alone isn't enough to detect a time zone.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The NITZ country is enough to detect the time zone, but the NITZ + country is
+ // also sufficient so we expect the time zone to be set twice.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId(), 2);
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_validCzNitzSignal_countryReceivedFirst() throws Exception {
+ Scenario scenario = CZECHIA_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The NITZ country is enough to detect the time zone.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId(), 1);
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(goodNitzSignal)
+ // The time will be suggested from the NITZ signal.
+ // The combination of NITZ + country will cause the time zone to be set.
+ .verifyTimeSuggestedAndZoneSetAndReset(
+ scenario.getNitzSignal(), scenario.getTimeZoneId());
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_bogusCzNitzSignal_nitzReceivedFirst() throws Exception {
+ Scenario scenario = CZECHIA_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Create a corrupted NITZ signal, where the offset information has been lost.
+ NitzData bogusNitzData = NitzData.createForTests(
+ 0 /* UTC! */, null /* dstOffsetMillis */,
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(badNitzSignal)
+ // The NITZ alone isn't enough to detect a time zone, but there isn't enough
+ // information to work out it is bogus.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The country is enough to detect the time zone for CZ. If the NITZ signal
+ // wasn't obviously bogus we'd try to set it twice.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId(), 1);
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_bogusCzNitzSignal_countryReceivedFirst() throws Exception {
+ Scenario scenario = CZECHIA_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Create a corrupted NITZ signal, where the offset information has been lost.
+ NitzData bogusNitzData = NitzData.createForTests(
+ 0 /* UTC! */, null /* dstOffsetMillis */,
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The country is enough to detect the time zone for CZ.
+ .verifyOnlyTimeZoneWasSetAndReset(scenario.getTimeZoneId());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertNull(mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(badNitzSignal)
+ // The NITZ should be detected as bogus so only the time will be suggested.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_bogusUniqueUsNitzSignal_nitzReceivedFirst() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Create a corrupted NITZ signal, where the offset information has been lost.
+ NitzData bogusNitzData = NitzData.createForTests(
+ 0 /* UTC! */, null /* dstOffsetMillis */,
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(badNitzSignal)
+ // The NITZ alone isn't enough to detect a time zone, but there isn't enough
+ // information to work out its bogus.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The country isn't enough to detect the time zone for US so we will leave the time
+ // zone unset.
+ .verifyNothingWasSetAndReset();
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_bogusUsUniqueNitzSignal_countryReceivedFirst() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+
+ // Create a corrupted NITZ signal, where the offset information has been lost.
+ NitzData bogusNitzData = NitzData.createForTests(
+ 0 /* UTC! */, null /* dstOffsetMillis */,
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
+
+ // Simulate the country code becoming known.
+ script.countryReceived(scenario.getNetworkCountryIsoCode())
+ // The country isn't enough to detect the time zone for US so we will leave the time
+ // zone unset.
+ .verifyNothingWasSetAndReset();
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate receiving an NITZ signal.
+ script.nitzReceived(badNitzSignal)
+ // The NITZ should be detected as bogus so only the time will be suggested.
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_emulatorNitzExtensionUsedForTimeZone() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ TimestampedValue<NitzData> originalNitzSignal = scenario.getNitzSignal();
+
+ // Create an NITZ signal with an explicit time zone (as can happen on emulators)
+ NitzData originalNitzData = originalNitzSignal.getValue();
+ // A time zone that is obviously not in the US, but it should not be questioned.
+ String emulatorTimeZoneId = "Europe/London";
+ NitzData emulatorNitzData = NitzData.createForTests(
+ originalNitzData.getLocalOffsetMillis(),
+ originalNitzData.getDstAdjustmentMillis(),
+ originalNitzData.getCurrentTimeInMillis(),
+ java.util.TimeZone.getTimeZone(emulatorTimeZoneId) /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> emulatorNitzSignal = new TimestampedValue<>(
+ originalNitzSignal.getReferenceTimeMillis(), emulatorNitzData);
+
+ // Simulate receiving the emulator NITZ signal.
+ script.nitzReceived(emulatorNitzSignal)
+ .verifyTimeSuggestedAndZoneSetAndReset(
+ scenario.getNitzSignal(), emulatorTimeZoneId);
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(emulatorNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(emulatorTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_emptyCountryStringUsTime_countryReceivedFirst() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ String expectedZoneId = checkNitzOnlyLookupIsAmbiguousAndReturnZoneId(scenario);
+
+ // Nothing should be set. The country is not valid.
+ script.countryReceived("").verifyNothingWasSetAndReset();
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertNull(mNitzStateMachine.getCachedNitzData());
+ assertNull(mNitzStateMachine.getSavedTimeZoneId());
+
+ // Simulate receiving the NITZ signal.
+ script.nitzReceived(scenario.getNitzSignal())
+ .verifyTimeSuggestedAndZoneSetAndReset(scenario.getNitzSignal(), expectedZoneId);
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ @Test
+ public void test_emptyCountryStringUsTime_nitzReceivedFirst() throws Exception {
+ Scenario scenario = UNIQUE_US_ZONE_SCENARIO;
+ Device device = new DeviceBuilder()
+ .setClocksFromScenario(scenario)
+ .setTimeZoneDetectionEnabled(true)
+ .setTimeZoneSettingInitialized(true)
+ .initialize();
+ Script script = new Script(device);
+
+ String expectedZoneId = checkNitzOnlyLookupIsAmbiguousAndReturnZoneId(scenario);
+
+ // Simulate receiving the NITZ signal.
+ script.nitzReceived(scenario.getNitzSignal())
+ .verifyOnlyTimeWasSuggestedAndReset(scenario.getNitzSignal());
+
+ // Check NitzStateMachine state.
+ assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().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).
+ script.countryReceived("").verifyOnlyTimeZoneWasSetAndReset(expectedZoneId);
+
+ // Check NitzStateMachine state.
+ assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
+ assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ }
+
+ /**
+ * Asserts a test scenario has the properties we expect for NITZ-only lookup. There are
+ * usually multiple zones that will share the same UTC offset so we get a low quality / low
+ * confidence answer, but the zone we find should at least have the correct offset.
+ */
+ private String checkNitzOnlyLookupIsAmbiguousAndReturnZoneId(Scenario scenario) {
+ OffsetResult result =
+ mRealTimeZoneLookupHelper.lookupByNitz(scenario.getNitzSignal().getValue());
+ String expectedZoneId = result.zoneId;
+ // All our scenarios should return multiple matches. The only cases where this wouldn't be
+ // true are places that use offsets like XX:15, XX:30 and XX:45.
+ assertFalse(result.isOnlyMatch);
+ assertSameOffset(scenario.getActualTimeMillis(), expectedZoneId, scenario.getTimeZoneId());
+ return expectedZoneId;
+ }
+
+ private static void assertSameOffset(long timeMillis, String zoneId1, String zoneId2) {
+ assertEquals(TimeZone.getTimeZone(zoneId1).getOffset(timeMillis),
+ TimeZone.getTimeZone(zoneId2).getOffset(timeMillis));
+ }
+
+ private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute,
+ int second) {
+ Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC"));
+ cal.clear();
+ cal.set(year, monthInYear - 1, day, hourOfDay, minute, second);
+ return cal.getTimeInMillis();
+ }
+
+ /**
+ * A helper class for common test operations involving a device.
+ */
+ class Script {
+ private final Device mDevice;
+
+ Script(Device device) {
+ this.mDevice = device;
+ }
+
+ Script countryReceived(String countryIsoCode) {
+ mDevice.networkCountryKnown(countryIsoCode);
+ return this;
+ }
+
+ Script nitzReceived(TimestampedValue<NitzData> nitzSignal) {
+ mDevice.nitzSignalReceived(nitzSignal);
+ return this;
+ }
+
+ Script verifyNothingWasSetAndReset() {
+ mDevice.verifyTimeZoneWasNotSet();
+ mDevice.verifyTimeWasNotSuggested();
+ mDevice.checkNoUnverifiedSetOperations();
+ mDevice.resetInvocations();
+ return this;
+ }
+
+ Script verifyOnlyTimeZoneWasSetAndReset(String timeZoneId, int times) {
+ mDevice.verifyTimeZoneWasSet(timeZoneId, times);
+ mDevice.verifyTimeWasNotSuggested();
+ mDevice.checkNoUnverifiedSetOperations();
+ mDevice.resetInvocations();
+ return this;
+ }
+
+ Script verifyOnlyTimeZoneWasSetAndReset(String timeZoneId) {
+ return verifyOnlyTimeZoneWasSetAndReset(timeZoneId, 1);
+ }
+
+ Script verifyOnlyTimeWasSuggestedAndReset(TimestampedValue<NitzData> nitzSignal) {
+ mDevice.verifyTimeZoneWasNotSet();
+
+ TimestampedValue<Long> time = new TimestampedValue<>(
+ nitzSignal.getReferenceTimeMillis(),
+ nitzSignal.getValue().getCurrentTimeInMillis());
+ mDevice.verifyTimeWasSuggested(time);
+ mDevice.checkNoUnverifiedSetOperations();
+ mDevice.resetInvocations();
+ return this;
+ }
+
+ Script verifyTimeSuggestedAndZoneSetAndReset(
+ TimestampedValue<NitzData> nitzSignal, String timeZoneId) {
+ mDevice.verifyTimeZoneWasSet(timeZoneId);
+
+ TimestampedValue<Long> time = new TimestampedValue<>(
+ nitzSignal.getReferenceTimeMillis(),
+ nitzSignal.getValue().getCurrentTimeInMillis());
+ mDevice.verifyTimeWasSuggested(time);
+ mDevice.checkNoUnverifiedSetOperations();
+ mDevice.resetInvocations();
+ return this;
+ }
+
+ Script reset() {
+ mDevice.checkNoUnverifiedSetOperations();
+ mDevice.resetInvocations();
+ return this;
+ }
+ }
+
+ /**
+ * An abstraction of a device for use in telephony time zone detection tests. It can be used to
+ * retrieve device state, modify device state and verify changes.
+ */
+ class Device {
+
+ private final long mInitialSystemClockMillis;
+ private final long mInitialRealtimeMillis;
+ private final boolean mTimeZoneDetectionEnabled;
+ private final boolean mTimeZoneSettingInitialized;
+
+ Device(long initialSystemClockMillis, long initialRealtimeMillis,
+ boolean timeZoneDetectionEnabled, boolean timeZoneSettingInitialized) {
+ mInitialSystemClockMillis = initialSystemClockMillis;
+ mInitialRealtimeMillis = initialRealtimeMillis;
+ mTimeZoneDetectionEnabled = timeZoneDetectionEnabled;
+ mTimeZoneSettingInitialized = timeZoneSettingInitialized;
+ }
+
+ void initialize() {
+ // Set initial configuration.
+ when(mDeviceState.getIgnoreNitz()).thenReturn(false);
+ when(mDeviceState.getNitzUpdateDiffMillis()).thenReturn(2000);
+ when(mDeviceState.getNitzUpdateSpacingMillis()).thenReturn(1000 * 60 * 10);
+
+ // Simulate the country not being known.
+ when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn("");
+
+ when(mTimeServiceHelper.elapsedRealtime()).thenReturn(mInitialRealtimeMillis);
+ when(mTimeServiceHelper.currentTimeMillis()).thenReturn(mInitialSystemClockMillis);
+ when(mTimeServiceHelper.isTimeZoneDetectionEnabled())
+ .thenReturn(mTimeZoneDetectionEnabled);
+ when(mTimeServiceHelper.isTimeZoneSettingInitialized())
+ .thenReturn(mTimeZoneSettingInitialized);
+ }
+
+ void networkCountryKnown(String countryIsoCode) {
+ when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(countryIsoCode);
+ mNitzStateMachine.handleNetworkCountryCodeSet(true);
+ }
+
+ void nitzSignalReceived(TimestampedValue<NitzData> nitzSignal) {
+ mNitzStateMachine.handleNitzReceived(nitzSignal);
+ }
+
+ void verifyTimeZoneWasNotSet() {
+ verify(mTimeServiceHelper, times(0)).setDeviceTimeZone(any(String.class));
+ }
+
+ void verifyTimeZoneWasSet(String timeZoneId) {
+ verifyTimeZoneWasSet(timeZoneId, 1 /* times */);
+ }
+
+ void verifyTimeZoneWasSet(String timeZoneId, int times) {
+ verify(mTimeServiceHelper, times(times)).setDeviceTimeZone(timeZoneId);
+ }
+
+ void verifyTimeWasNotSuggested() {
+ verify(mTimeServiceHelper, times(0)).suggestDeviceTime(any());
+ }
+
+ void verifyTimeWasSuggested(TimestampedValue<Long> expectedTime) {
+ verify(mTimeServiceHelper, times(1)).suggestDeviceTime(eq(expectedTime));
+ }
+
+ /**
+ * Used after calling verify... methods to reset expectations.
+ */
+ void resetInvocations() {
+ clearInvocations(mTimeServiceHelper);
+ }
+
+ void checkNoUnverifiedSetOperations() {
+ NewNitzStateMachineTest.checkNoUnverifiedSetOperations(mTimeServiceHelper);
+ }
+ }
+
+ /** A class used to construct a Device. */
+ class DeviceBuilder {
+
+ private long mInitialSystemClock;
+ private long mInitialRealtimeMillis;
+ private boolean mTimeZoneDetectionEnabled;
+ private boolean mTimeZoneSettingInitialized;
+
+ Device initialize() {
+ Device device = new Device(mInitialSystemClock, mInitialRealtimeMillis,
+ mTimeZoneDetectionEnabled, mTimeZoneSettingInitialized);
+ device.initialize();
+ return device;
+ }
+
+ DeviceBuilder setTimeZoneDetectionEnabled(boolean enabled) {
+ mTimeZoneDetectionEnabled = enabled;
+ return this;
+ }
+
+ DeviceBuilder setTimeZoneSettingInitialized(boolean initialized) {
+ mTimeZoneSettingInitialized = initialized;
+ return this;
+ }
+
+ DeviceBuilder setClocksFromScenario(Scenario scenario) {
+ mInitialRealtimeMillis = scenario.getInitialRealTimeMillis();
+ mInitialSystemClock = scenario.getInitialSystemClockMillis();
+ return this;
+ }
+ }
+
+ /**
+ * A scenario used during tests. Describes a fictional reality.
+ */
+ static class Scenario {
+
+ private final long mInitialDeviceSystemClockMillis;
+ private final long mInitialDeviceRealtimeMillis;
+ private final long mActualTimeMillis;
+ private final TimeZone mZone;
+ private final String mNetworkCountryIsoCode;
+
+ private TimestampedValue<NitzData> mNitzSignal;
+
+ Scenario(long initialDeviceSystemClock, long elapsedRealtime, long timeMillis,
+ String zoneId, String countryIsoCode) {
+ mInitialDeviceSystemClockMillis = initialDeviceSystemClock;
+ mActualTimeMillis = timeMillis;
+ mInitialDeviceRealtimeMillis = elapsedRealtime;
+ mZone = TimeZone.getTimeZone(zoneId);
+ mNetworkCountryIsoCode = countryIsoCode;
+ }
+
+ TimestampedValue<NitzData> getNitzSignal() {
+ if (mNitzSignal == null) {
+ int[] offsets = new int[2];
+ mZone.getOffset(mActualTimeMillis, false /* local */, offsets);
+ int zoneOffsetMillis = offsets[0] + offsets[1];
+ NitzData nitzData = NitzData.createForTests(
+ zoneOffsetMillis, offsets[1], mActualTimeMillis,
+ null /* emulatorHostTimeZone */);
+ mNitzSignal = new TimestampedValue<>(mInitialDeviceRealtimeMillis, nitzData);
+ }
+ return mNitzSignal;
+ }
+
+ long getInitialRealTimeMillis() {
+ return mInitialDeviceRealtimeMillis;
+ }
+
+ long getInitialSystemClockMillis() {
+ return mInitialDeviceSystemClockMillis;
+ }
+
+ String getNetworkCountryIsoCode() {
+ return mNetworkCountryIsoCode;
+ }
+
+ String getTimeZoneId() {
+ return mZone.getID();
+ }
+
+ long getActualTimeMillis() {
+ return mActualTimeMillis;
+ }
+
+ static class Builder {
+
+ private long mInitialDeviceSystemClockMillis;
+ private long mInitialDeviceRealtimeMillis;
+ private long mActualTimeMillis;
+ private String mZoneId;
+ private String mCountryIsoCode;
+
+ Builder setInitialDeviceSystemClockUtc(int year, int monthInYear, int day,
+ int hourOfDay, int minute, int second) {
+ mInitialDeviceSystemClockMillis = createUtcTime(year, monthInYear, day, hourOfDay,
+ minute, second);
+ return this;
+ }
+
+ Builder setInitialDeviceRealtimeMillis(long realtimeMillis) {
+ mInitialDeviceRealtimeMillis = realtimeMillis;
+ return this;
+ }
+
+ Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay,
+ int minute, int second) {
+ mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute,
+ second);
+ return this;
+ }
+
+ Builder setTimeZone(String zoneId) {
+ mZoneId = zoneId;
+ return this;
+ }
+
+ Builder setCountryIso(String isoCode) {
+ mCountryIsoCode = isoCode;
+ return this;
+ }
+
+ Scenario build() {
+ return new Scenario(mInitialDeviceSystemClockMillis, mInitialDeviceRealtimeMillis,
+ mActualTimeMillis, mZoneId, mCountryIsoCode);
+ }
+ }
+ }
+
+ /**
+ * Confirms all mTimeServiceHelper side effects were verified.
+ */
+ private static void checkNoUnverifiedSetOperations(NewTimeServiceHelper mTimeServiceHelper) {
+ // We don't care about current auto time / time zone state retrievals / listening so we can
+ // use "at least 0" times to indicate they don't matter.
+ verify(mTimeServiceHelper, atLeast(0)).setListener(any());
+ verify(mTimeServiceHelper, atLeast(0)).isTimeZoneDetectionEnabled();
+ verify(mTimeServiceHelper, atLeast(0)).isTimeZoneSettingInitialized();
+ verify(mTimeServiceHelper, atLeast(0)).elapsedRealtime();
+ verify(mTimeServiceHelper, atLeast(0)).currentTimeMillis();
+ verifyNoMoreInteractions(mTimeServiceHelper);
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/OldNitzStateMachineTest.java b/tests/telephonytests/src/com/android/internal/telephony/OldNitzStateMachineTest.java
index 608e71b..2fc864a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/OldNitzStateMachineTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/OldNitzStateMachineTest.java
@@ -32,10 +32,10 @@
import android.icu.util.Calendar;
import android.icu.util.GregorianCalendar;
import android.icu.util.TimeZone;
+import android.util.TimestampedValue;
import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult;
import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
-import com.android.internal.telephony.util.TimeStampedValue;
import org.junit.After;
import org.junit.Before;
@@ -80,7 +80,7 @@
private OldNitzStateMachine.DeviceState mDeviceState;
@Mock
- private TimeServiceHelper mTimeServiceHelper;
+ private OldTimeServiceHelper mTimeServiceHelper;
private TimeZoneLookupHelper mRealTimeZoneLookupHelper;
@@ -124,7 +124,7 @@
OffsetResult expectedLookupResult =
new OffsetResult("America/Los_Angeles", true /* isOnlyMatch */);
OffsetResult actualLookupResult = mRealTimeZoneLookupHelper.lookupByNitzCountry(
- UNIQUE_US_ZONE_SCENARIO.getNitzSignal().mValue,
+ UNIQUE_US_ZONE_SCENARIO.getNitzSignal().getValue(),
UNIQUE_US_ZONE_SCENARIO.getNetworkCountryIsoCode());
assertEquals(expectedLookupResult, actualLookupResult);
}
@@ -147,7 +147,7 @@
OffsetResult expectedLookupResult =
new OffsetResult("Europe/London", true /* isOnlyMatch */);
OffsetResult actualLookupResult = mRealTimeZoneLookupHelper.lookupByNitzCountry(
- UNITED_KINGDOM_SCENARIO.getNitzSignal().mValue,
+ UNITED_KINGDOM_SCENARIO.getNitzSignal().getValue(),
UNITED_KINGDOM_SCENARIO.getNetworkCountryIsoCode());
assertEquals(expectedLookupResult, actualLookupResult);
}
@@ -176,7 +176,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -204,7 +204,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -231,7 +231,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -259,7 +259,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -283,7 +283,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -307,7 +307,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -331,7 +331,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -355,7 +355,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -377,7 +377,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
@@ -387,7 +387,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -409,7 +409,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
@@ -423,7 +423,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -438,7 +438,7 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Simulate receiving an NITZ signal.
script.nitzReceived(goodNitzSignal)
@@ -447,7 +447,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(goodNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
@@ -458,7 +458,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(goodNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -473,7 +473,7 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -494,7 +494,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(goodNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(goodNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -509,14 +509,15 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Create a corrupted NITZ signal, where the offset information has been lost.
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.mValue.getCurrentTimeInMillis(), null /* emulatorHostTimeZone */);
- TimeStampedValue<NitzData> badNitzSignal = new TimeStampedValue<>(
- bogusNitzData, goodNitzSignal.mElapsedRealtime);
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
// Simulate receiving an NITZ signal.
script.nitzReceived(badNitzSignal)
@@ -526,7 +527,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
@@ -537,7 +538,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -552,14 +553,15 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Create a corrupted NITZ signal, where the offset information has been lost.
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.mValue.getCurrentTimeInMillis(), null /* emulatorHostTimeZone */);
- TimeStampedValue<NitzData> badNitzSignal = new TimeStampedValue<>(
- bogusNitzData, goodNitzSignal.mElapsedRealtime);
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -578,7 +580,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(scenario.getTimeZoneId(), mNitzStateMachine.getSavedTimeZoneId());
}
@@ -593,14 +595,15 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Create a corrupted NITZ signal, where the offset information has been lost.
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.mValue.getCurrentTimeInMillis(), null /* emulatorHostTimeZone */);
- TimeStampedValue<NitzData> badNitzSignal = new TimeStampedValue<>(
- bogusNitzData, goodNitzSignal.mElapsedRealtime);
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
// Simulate receiving an NITZ signal.
script.nitzReceived(badNitzSignal)
@@ -610,7 +613,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// Simulate the country code becoming known.
@@ -621,7 +624,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@@ -636,14 +639,15 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> goodNitzSignal = scenario.getNitzSignal();
// Create a corrupted NITZ signal, where the offset information has been lost.
NitzData bogusNitzData = NitzData.createForTests(
0 /* UTC! */, null /* dstOffsetMillis */,
- goodNitzSignal.mValue.getCurrentTimeInMillis(), null /* emulatorHostTimeZone */);
- TimeStampedValue<NitzData> badNitzSignal = new TimeStampedValue<>(
- bogusNitzData, goodNitzSignal.mElapsedRealtime);
+ goodNitzSignal.getValue().getCurrentTimeInMillis(),
+ null /* emulatorHostTimeZone */);
+ TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+ goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
// Simulate the country code becoming known.
script.countryReceived(scenario.getNetworkCountryIsoCode())
@@ -663,7 +667,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(badNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(badNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
}
@@ -678,10 +682,10 @@
.initialize();
Script script = new Script(device);
- TimeStampedValue<NitzData> originalNitzSignal = scenario.getNitzSignal();
+ TimestampedValue<NitzData> originalNitzSignal = scenario.getNitzSignal();
// Create an NITZ signal with an explicit time zone (as can happen on emulators)
- NitzData originalNitzData = originalNitzSignal.mValue;
+ NitzData originalNitzData = originalNitzSignal.getValue();
// A time zone that is obviously not in the US, but it should not be questioned.
String emulatorTimeZoneId = "Europe/London";
NitzData emulatorNitzData = NitzData.createForTests(
@@ -689,8 +693,8 @@
originalNitzData.getDstAdjustmentMillis(),
originalNitzData.getCurrentTimeInMillis(),
java.util.TimeZone.getTimeZone(emulatorTimeZoneId) /* emulatorHostTimeZone */);
- TimeStampedValue<NitzData> emulatorNitzSignal = new TimeStampedValue<>(
- emulatorNitzData, originalNitzSignal.mElapsedRealtime);
+ TimestampedValue<NitzData> emulatorNitzSignal = new TimestampedValue<>(
+ originalNitzSignal.getReferenceTimeMillis(), emulatorNitzData);
// Simulate receiving the emulator NITZ signal.
script.nitzReceived(emulatorNitzSignal)
@@ -698,7 +702,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(emulatorNitzSignal.mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(emulatorNitzSignal.getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(emulatorTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@@ -729,7 +733,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@@ -752,7 +756,7 @@
// Check NitzStateMachine state.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertNull(mNitzStateMachine.getSavedTimeZoneId());
// The time zone should be set (but the country is not valid so it's unlikely to be
@@ -761,7 +765,7 @@
// Check NitzStateMachine state.
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
- assertEquals(scenario.getNitzSignal().mValue, mNitzStateMachine.getCachedNitzData());
+ assertEquals(scenario.getNitzSignal().getValue(), mNitzStateMachine.getCachedNitzData());
assertEquals(expectedZoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@@ -772,7 +776,7 @@
*/
private String checkNitzOnlyLookupIsAmbiguousAndReturnZoneId(Scenario scenario) {
OffsetResult result =
- mRealTimeZoneLookupHelper.lookupByNitz(scenario.getNitzSignal().mValue);
+ mRealTimeZoneLookupHelper.lookupByNitz(scenario.getNitzSignal().getValue());
String expectedZoneId = result.zoneId;
// All our scenarios should return multiple matches. The only cases where this wouldn't be
// true are places that use offsets like XX:15, XX:30 and XX:45.
@@ -809,7 +813,7 @@
return this;
}
- Script nitzReceived(TimeStampedValue<NitzData> nitzSignal) {
+ Script nitzReceived(TimestampedValue<NitzData> nitzSignal) {
mDevice.nitzSignalReceived(nitzSignal);
return this;
}
@@ -914,7 +918,7 @@
when(mTimeServiceHelper.currentTimeMillis()).thenReturn(currentTimeMillis + millis);
}
- void nitzSignalReceived(TimeStampedValue<NitzData> nitzSignal) {
+ void nitzSignalReceived(TimestampedValue<NitzData> nitzSignal) {
mNitzStateMachine.handleNitzReceived(nitzSignal);
}
@@ -1001,7 +1005,7 @@
private final TimeZone mZone;
private final String mNetworkCountryIsoCode;
- private TimeStampedValue<NitzData> mNitzSignal;
+ private TimestampedValue<NitzData> mNitzSignal;
Scenario(long initialDeviceSystemClock, long elapsedRealtime, long timeMillis,
String zoneId, String countryIsoCode) {
@@ -1012,7 +1016,7 @@
mNetworkCountryIsoCode = countryIsoCode;
}
- TimeStampedValue<NitzData> getNitzSignal() {
+ TimestampedValue<NitzData> getNitzSignal() {
if (mNitzSignal == null) {
int[] offsets = new int[2];
mZone.getOffset(mActualTimeMillis, false /* local */, offsets);
@@ -1020,7 +1024,7 @@
NitzData nitzData = NitzData.createForTests(
zoneOffsetMillis, offsets[1], mActualTimeMillis,
null /* emulatorHostTimeZone */);
- mNitzSignal = new TimeStampedValue<>(nitzData, mInitialDeviceRealtimeMillis);
+ mNitzSignal = new TimestampedValue<>(mInitialDeviceRealtimeMillis, nitzData);
}
return mNitzSignal;
}
@@ -1092,7 +1096,7 @@
/**
* Confirms all mTimeServiceHelper side effects were verified.
*/
- private static void checkNoUnverifiedSetOperations(TimeServiceHelper mTimeServiceHelper) {
+ private static void checkNoUnverifiedSetOperations(OldTimeServiceHelper mTimeServiceHelper) {
// We don't care about current auto time / time zone state retrievals / listening so we can
// use "at least 0" times to indicate they don't matter.
verify(mTimeServiceHelper, atLeast(0)).setListener(any());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index dd356aa..10dd6f2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -115,22 +115,25 @@
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
+import android.telephony.CellInfoTdscdma;
import android.telephony.CellInfoWcdma;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataProfile;
import com.android.internal.telephony.RIL.RilHandler;
-import com.android.internal.telephony.dataconnection.ApnSetting;
import com.android.internal.telephony.dataconnection.DcTracker;
import org.junit.After;
@@ -194,6 +197,8 @@
private static final int RSSNR = 2147483647;
private static final int RSRP = 96;
private static final int RSRQ = 10;
+ private static final int RSCP = 94;
+ private static final int ECNO = 5;
private static final int SIGNAL_NOISE_RATIO = 6;
private static final int SIGNAL_STRENGTH = 24;
private static final int SYSTEM_ID = 65533;
@@ -205,6 +210,7 @@
private static final int TYPE_GSM = 1;
private static final int TYPE_LTE = 3;
private static final int TYPE_WCDMA = 4;
+ private static final int TYPE_TD_SCDMA = 5;
private static final int PROFILE_ID = 0;
private static final String APN = "apn";
@@ -692,11 +698,12 @@
@FlakyTest
@Test
public void testSetInitialAttachApn() throws Exception {
- ApnSetting apnSetting = new ApnSetting(
- -1, "22210", "Vodafone IT", "web.omnitel.it", "", "",
- "", "", "", "", "", 0, new String[]{"DUN"}, "IP", "IP", true, 0, 0,
- 0, false, 0, 0, 0, 0, "", "");
- DataProfile dataProfile = DcTracker.createDataProfile(apnSetting, apnSetting.profileId);
+ ApnSetting apnSetting = ApnSetting.makeApnSetting(
+ -1, "22210", "Vodafone IT", "web.omnitel.it", null, -1,
+ null, null, -1, "", "", 0, ApnSetting.TYPE_DUN, ApnSetting.PROTOCOL_IP,
+ ApnSetting.PROTOCOL_IP, true, 0, 0, false, 0, 0, 0, 0, -1, "");
+ DataProfile dataProfile = DcTracker.createDataProfile(
+ apnSetting, apnSetting.getProfileId());
boolean isRoaming = false;
mRILUnderTest.setInitialAttachApn(dataProfile, isRoaming, obtainMessage());
@@ -1183,7 +1190,8 @@
expected.setTimeStampType(RIL_TIMESTAMP_TYPE_OEM_RIL);
CellIdentityWcdma ci = new CellIdentityWcdma(
LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
- CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE);
+ CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
+ SIGNAL_STRENGTH, BIT_ERROR_RATE, Integer.MAX_VALUE, Integer.MAX_VALUE);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_UNKNOWN);
@@ -1191,6 +1199,47 @@
}
@Test
+ public void testConvertHalCellInfoListForTdscdma() throws Exception {
+ android.hardware.radio.V1_2.CellInfoTdscdma cellinfo =
+ new android.hardware.radio.V1_2.CellInfoTdscdma();
+ cellinfo.cellIdentityTdscdma.base.lac = LAC;
+ cellinfo.cellIdentityTdscdma.base.cid = CID;
+ cellinfo.cellIdentityTdscdma.base.cpid = PSC;
+ cellinfo.cellIdentityTdscdma.uarfcn = UARFCN;
+ cellinfo.cellIdentityTdscdma.base.mcc = MCC_STR;
+ cellinfo.cellIdentityTdscdma.base.mnc = MNC_STR;
+ cellinfo.signalStrengthTdscdma.signalStrength = SIGNAL_STRENGTH;
+ cellinfo.signalStrengthTdscdma.bitErrorRate = BIT_ERROR_RATE;
+ cellinfo.signalStrengthTdscdma.rscp = RSCP;
+ android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
+ record.cellInfoType = TYPE_TD_SCDMA;
+ record.registered = false;
+ record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
+ record.timeStamp = TIMESTAMP;
+ record.tdscdma.add(cellinfo);
+ ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+ new ArrayList<android.hardware.radio.V1_2.CellInfo>();
+ records.add(record);
+
+ ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_2(records);
+
+ assertEquals(1, ret.size());
+ CellInfoTdscdma cellInfoTdscdma = (CellInfoTdscdma) ret.get(0);
+ CellInfoTdscdma expected = new CellInfoTdscdma();
+ expected.setRegistered(false);
+ expected.setTimeStamp(TIMESTAMP);
+ expected.setTimeStampType(RIL_TIMESTAMP_TYPE_OEM_RIL);
+ expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
+ CellIdentityTdscdma ci = new CellIdentityTdscdma(
+ MCC_STR, MNC_STR, LAC, CID, PSC, UARFCN, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
+ CellSignalStrengthTdscdma cs = new CellSignalStrengthTdscdma(
+ SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP);
+ expected.setCellIdentity(ci);
+ expected.setCellSignalStrength(cs);
+ assertEquals(expected, cellInfoTdscdma);
+ }
+
+ @Test
public void testConvertHalCellInfoListForCdma() throws Exception {
android.hardware.radio.V1_0.CellInfoCdma cellinfo =
new android.hardware.radio.V1_0.CellInfoCdma();
@@ -1374,7 +1423,8 @@
expected.setTimeStampType(RIL_TIMESTAMP_TYPE_OEM_RIL);
CellIdentityWcdma ci = new CellIdentityWcdma(
LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, ALPHA_LONG, ALPHA_SHORT);
- CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE);
+ CellSignalStrengthWcdma cs =
+ new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1394,7 +1444,8 @@
expected.setTimeStampType(RIL_TIMESTAMP_TYPE_OEM_RIL);
CellIdentityWcdma ci = new CellIdentityWcdma(
LAC, CID, PSC, UARFCN, MCC_STR, MNC_STR, EMPTY_ALPHA_LONG, EMPTY_ALPHA_SHORT);
- CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE);
+ CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
+ SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1416,7 +1467,8 @@
expected.setTimeStampType(RIL_TIMESTAMP_TYPE_OEM_RIL);
CellIdentityWcdma ci = new CellIdentityWcdma(
LAC, CID, PSC, UARFCN, null, null, ALPHA_LONG, ALPHA_SHORT);
- CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(SIGNAL_STRENGTH, BIT_ERROR_RATE);
+ CellSignalStrengthWcdma cs = new CellSignalStrengthWcdma(
+ SIGNAL_STRENGTH, BIT_ERROR_RATE, RSCP, ECNO);
expected.setCellIdentity(ci);
expected.setCellSignalStrength(cs);
expected.setCellConnectionStatus(CellInfo.CONNECTION_NONE);
@@ -1539,8 +1591,8 @@
cellinfo.cellIdentityWcdma.operatorNames.alphaShort = alphaShort;
cellinfo.signalStrengthWcdma.base.signalStrength = SIGNAL_STRENGTH;
cellinfo.signalStrengthWcdma.base.bitErrorRate = BIT_ERROR_RATE;
- cellinfo.signalStrengthWcdma.rscp = 10;
- cellinfo.signalStrengthWcdma.ecno = 5;
+ cellinfo.signalStrengthWcdma.rscp = RSCP;
+ cellinfo.signalStrengthWcdma.ecno = ECNO;
android.hardware.radio.V1_2.CellInfo record = new android.hardware.radio.V1_2.CellInfo();
record.cellInfoType = TYPE_WCDMA;
record.registered = false;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
index 0fa88bf..55fde49 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
@@ -282,18 +282,18 @@
@SmallTest
public void testNetworkRegistrationState() {
NetworkRegistrationState wwanVoiceRegState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WWAN, NetworkRegistrationState.DOMAIN_CS,
+ NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN,
0, 0, 0, false,
null, null, true, 0, 0, 0);
NetworkRegistrationState wwanDataRegState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WWAN, NetworkRegistrationState.DOMAIN_PS,
+ NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
0, 0, 0, false,
null, null, 0);
NetworkRegistrationState wlanRegState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WLAN, NetworkRegistrationState.DOMAIN_PS,
+ NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WLAN,
0, 0, 0, false,
null, null);
@@ -303,20 +303,20 @@
ss.addNetworkRegistrationState(wwanDataRegState);
ss.addNetworkRegistrationState(wlanRegState);
- assertEquals(ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN,
- NetworkRegistrationState.DOMAIN_CS), wwanVoiceRegState);
- assertEquals(ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN,
- NetworkRegistrationState.DOMAIN_PS), wwanDataRegState);
- assertEquals(ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WLAN,
- NetworkRegistrationState.DOMAIN_PS), wlanRegState);
+ assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_CS,
+ AccessNetworkConstants.TransportType.WWAN), wwanVoiceRegState);
+ assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
+ AccessNetworkConstants.TransportType.WWAN), wwanDataRegState);
+ assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
+ AccessNetworkConstants.TransportType.WLAN), wlanRegState);
wwanDataRegState = new NetworkRegistrationState(
- AccessNetworkConstants.TransportType.WWAN, NetworkRegistrationState.DOMAIN_PS,
+ NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
0, 0, 0, true,
null, null, 0);
ss.addNetworkRegistrationState(wwanDataRegState);
- assertEquals(ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN,
- NetworkRegistrationState.DOMAIN_PS), wwanDataRegState);
+ assertEquals(ss.getNetworkRegistrationStates(NetworkRegistrationState.DOMAIN_PS,
+ AccessNetworkConstants.TransportType.WWAN), wwanDataRegState);
}
@SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 3108d2b..603f800 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -60,24 +60,27 @@
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.NetworkRegistrationState;
import android.telephony.NetworkService;
+import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
+import android.util.TimestampedValue;
import com.android.internal.R;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
-import com.android.internal.telephony.util.TimeStampedValue;
import org.junit.After;
import org.junit.Before;
@@ -88,6 +91,7 @@
import org.mockito.Mockito;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -137,7 +141,7 @@
mCellularNetworkService = new CellularNetworkService();
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = "com.android.phone";
- serviceInfo.permission = "android.permission.BIND_NETWORK_SERVICE";
+ serviceInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
IntentFilter filter = new IntentFilter();
mContextFixture.addService(
NetworkService.NETWORK_SERVICE_INTERFACE,
@@ -1490,15 +1494,15 @@
mSimulatedCommands.triggerNITZupdate(nitzStr);
waitForMs(200);
- ArgumentCaptor<TimeStampedValue<NitzData>> argumentsCaptor =
- ArgumentCaptor.forClass(TimeStampedValue.class);
+ ArgumentCaptor<TimestampedValue<NitzData>> argumentsCaptor =
+ ArgumentCaptor.forClass(TimestampedValue.class);
verify(mNitzStateMachine, times(1))
.handleNitzReceived(argumentsCaptor.capture());
// Confirm the argument was what we expected.
- TimeStampedValue<NitzData> actualNitzSignal = argumentsCaptor.getValue();
- assertEquals(expectedNitzData, actualNitzSignal.mValue);
- assertTrue(actualNitzSignal.mElapsedRealtime <= SystemClock.elapsedRealtime());
+ TimestampedValue<NitzData> actualNitzSignal = argumentsCaptor.getValue();
+ assertEquals(expectedNitzData, actualNitzSignal.getValue());
+ assertTrue(actualNitzSignal.getReferenceTimeMillis() <= SystemClock.elapsedRealtime());
}
}
@@ -1627,4 +1631,97 @@
waitForMs(200);
assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
}
+
+ private void sendPhyChanConfigChange(int[] bandwidths) {
+ ArrayList<PhysicalChannelConfig> pc = new ArrayList<>();
+ int ssType = PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
+ for (int bw : bandwidths) {
+ pc.add(new PhysicalChannelConfig(ssType, bw));
+
+ // All cells after the first are secondary serving cells.
+ ssType = PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING;
+ }
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_PHYSICAL_CHANNEL_CONFIG,
+ new AsyncResult(null, pc, null)));
+ waitForMs(100);
+ }
+
+ private void sendRegStateUpdateForLteCellId(CellIdentityLte cellId) {
+ NetworkRegistrationState dataResult = new NetworkRegistrationState(
+ 2, 1, 1, TelephonyManager.NETWORK_TYPE_LTE, 0, false, null, cellId, 1);
+ NetworkRegistrationState voiceResult = new NetworkRegistrationState(
+ 1, 1, 1, TelephonyManager.NETWORK_TYPE_LTE, 0, false, null, cellId,
+ false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ // update data reg state to be in service
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ }
+
+ @Test
+ public void testPhyChanBandwidthUpdatedOnDataRegState() throws Exception {
+ // Cell ID change should trigger hasLocationChanged.
+ CellIdentityLte cellIdentity5 =
+ new CellIdentityLte(1, 1, 5, 1, 5000, "001", "01", "test", "tst");
+
+ sendPhyChanConfigChange(new int[] {10000});
+ sendRegStateUpdateForLteCellId(cellIdentity5);
+ assertTrue(Arrays.equals(new int[] {5000}, sst.mSS.getCellBandwidths()));
+ }
+
+ @Test
+ public void testPhyChanBandwidthNotUpdatedWhenInvalidInCellIdentity() throws Exception {
+ // Cell ID change should trigger hasLocationChanged.
+ CellIdentityLte cellIdentityInv =
+ new CellIdentityLte(1, 1, 5, 1, 12345, "001", "01", "test", "tst");
+
+ sendPhyChanConfigChange(new int[] {10000});
+ sendRegStateUpdateForLteCellId(cellIdentityInv);
+ assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
+ }
+
+ @Test
+ public void testPhyChanBandwidthPrefersCarrierAggregationReport() throws Exception {
+ // Cell ID change should trigger hasLocationChanged.
+ CellIdentityLte cellIdentity10 =
+ new CellIdentityLte(1, 1, 5, 1, 10000, "001", "01", "test", "tst");
+
+ sendPhyChanConfigChange(new int[] {10000, 5000});
+ sendRegStateUpdateForLteCellId(cellIdentity10);
+ assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
+ }
+
+ @Test
+ public void testPhyChanBandwidthRatchetedOnPhyChanBandwidth() throws Exception {
+ // LTE Cell with bandwidth = 10000
+ CellIdentityLte cellIdentity10 =
+ new CellIdentityLte(1, 1, 1, 1, 10000, "1", "1", "test", "tst");
+
+ sendRegStateUpdateForLteCellId(cellIdentity10);
+ assertTrue(Arrays.equals(new int[] {10000}, sst.mSS.getCellBandwidths()));
+ sendPhyChanConfigChange(new int[] {10000, 5000});
+ assertTrue(Arrays.equals(new int[] {10000, 5000}, sst.mSS.getCellBandwidths()));
+ }
+
+ @Test
+ public void testPhyChanBandwidthResetsOnOos() throws Exception {
+ testPhyChanBandwidthRatchetedOnPhyChanBandwidth();
+ NetworkRegistrationState dataResult = new NetworkRegistrationState(
+ 2, 1, 0, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, 1);
+ NetworkRegistrationState voiceResult = new NetworkRegistrationState(
+ 1, 1, 0, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null,
+ false, 0, 0, 0);
+ sst.mPollingContext[0] = 2;
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForMs(200);
+ sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+ waitForMs(200);
+ assertTrue(Arrays.equals(new int[0], sst.mSS.getCellBandwidths()));
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 56c6e91..89d8143 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -332,7 +332,8 @@
nullable(CommandsInterface.class));
doReturn(mUiccProfile).when(mTelephonyComponentFactory)
.makeUiccProfile(nullable(Context.class), nullable(CommandsInterface.class),
- nullable(IccCardStatus.class), anyInt(), nullable(UiccCard.class));
+ nullable(IccCardStatus.class), anyInt(), nullable(UiccCard.class),
+ nullable(Object.class));
doReturn(mCT).when(mTelephonyComponentFactory)
.makeGsmCdmaCallTracker(nullable(GsmCdmaPhone.class));
doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
index 8c49c21..6722691 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
@@ -16,9 +16,19 @@
package com.android.internal.telephony.dataconnection;
-import android.net.NetworkCapabilities;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
import android.net.NetworkConfig;
import android.net.NetworkRequest;
+import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
@@ -32,16 +42,6 @@
import org.junit.Test;
import org.mockito.Mock;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
public class ApnContextTest extends TelephonyTest {
@Mock
@@ -143,14 +143,14 @@
NetworkRequest nr = new NetworkRequest.Builder().build();
mApnContext.requestNetwork(nr, log);
- verify(mDcTracker, times(1)).setEnabled(eq(DctConstants.APN_DEFAULT_ID), eq(true));
+ verify(mDcTracker, times(1)).setEnabled(eq(ApnSetting.TYPE_DEFAULT), eq(true));
mApnContext.requestNetwork(nr, log);
- verify(mDcTracker, times(1)).setEnabled(eq(DctConstants.APN_DEFAULT_ID), eq(true));
+ verify(mDcTracker, times(1)).setEnabled(eq(ApnSetting.TYPE_DEFAULT), eq(true));
mApnContext.releaseNetwork(nr, log);
- verify(mDcTracker, times(1)).setEnabled(eq(DctConstants.APN_DEFAULT_ID), eq(false));
+ verify(mDcTracker, times(1)).setEnabled(eq(ApnSetting.TYPE_DEFAULT), eq(false));
mApnContext.releaseNetwork(nr, log);
- verify(mDcTracker, times(1)).setEnabled(eq(DctConstants.APN_DEFAULT_ID), eq(false));
+ verify(mDcTracker, times(1)).setEnabled(eq(ApnSetting.TYPE_DEFAULT), eq(false));
}
@Test
@@ -176,32 +176,31 @@
public void testProvisionApn() throws Exception {
mContextFixture.putResource(R.string.mobile_provisioning_apn, "fake_apn");
- ApnSetting myApn = new ApnSetting(
+ ApnSetting myApn = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"fake_apn", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bismask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
mApnContext.setApnSetting(myApn);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
index 4c49e5b..b9738e5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
@@ -16,13 +16,6 @@
package com.android.internal.telephony.dataconnection;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_ALL;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_DEFAULT;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_HIPRI;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_IA;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_MMS;
-import static com.android.internal.telephony.PhoneConstants.APN_TYPE_SUPL;
-
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -30,9 +23,11 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
+import android.net.Uri;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
+import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.PhoneConstants;
@@ -44,6 +39,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
@@ -62,41 +58,40 @@
super.tearDown();
}
- static ApnSetting createApnSetting(String[] apnTypes) {
- return createApnSettingInternal(apnTypes, true);
+ static ApnSetting createApnSetting(int apnTypesBitmask) {
+ return createApnSettingInternal(apnTypesBitmask, true);
}
- private static ApnSetting createDisabledApnSetting(String[] apnTypes) {
- return createApnSettingInternal(apnTypes, false);
+ private static ApnSetting createDisabledApnSetting(int apnTypesBitmask) {
+ return createApnSettingInternal(apnTypesBitmask, false);
}
- private static ApnSetting createApnSettingInternal(String[] apnTypes, boolean carrierEnabled) {
- return new ApnSetting(
+ private static ApnSetting createApnSettingInternal(int apnTypeBitmask, boolean carrierEnabled) {
+ return ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"spmode.ne.jp", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- apnTypes, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ apnTypeBitmask, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
carrierEnabled, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
}
@@ -108,91 +103,84 @@
}
private static void assertApnSettingEqual(ApnSetting a1, ApnSetting a2) {
- assertEquals(a1.carrier, a2.carrier);
- assertEquals(a1.apn, a2.apn);
- assertEquals(a1.proxy, a2.proxy);
- assertEquals(a1.port, a2.port);
- assertEquals(a1.mmsc, a2.mmsc);
- assertEquals(a1.mmsProxy, a2.mmsProxy);
- assertEquals(a1.mmsPort, a2.mmsPort);
- assertEquals(a1.user, a2.user);
- assertEquals(a1.password, a2.password);
- assertEquals(a1.authType, a2.authType);
- assertEquals(a1.id, a2.id);
- assertEquals(a1.numeric, a2.numeric);
- assertEquals(a1.protocol, a2.protocol);
- assertEquals(a1.roamingProtocol, a2.roamingProtocol);
- assertEquals(a1.types.length, a2.types.length);
- int i;
- for (i = 0; i < a1.types.length; i++) {
- assertEquals(a1.types[i], a2.types[i]);
- }
- assertEquals(a1.carrierEnabled, a2.carrierEnabled);
- assertEquals(a1.bearerBitmask, a2.bearerBitmask);
- assertEquals(a1.profileId, a2.profileId);
- assertEquals(a1.modemCognitive, a2.modemCognitive);
- assertEquals(a1.maxConns, a2.maxConns);
- assertEquals(a1.waitTime, a2.waitTime);
- assertEquals(a1.maxConnsTime, a2.maxConnsTime);
- assertEquals(a1.mtu, a2.mtu);
- assertEquals(a1.mvnoType, a2.mvnoType);
- assertEquals(a1.mvnoMatchData, a2.mvnoMatchData);
- assertEquals(a1.networkTypeBitmask, a2.networkTypeBitmask);
- assertEquals(a1.apnSetId, a2.apnSetId);
+ assertEquals(a1.getEntryName(), a2.getEntryName());
+ assertEquals(a1.getApnName(), a2.getApnName());
+ assertEquals(a1.getProxyAddressAsString(), a2.getProxyAddressAsString());
+ assertEquals(a1.getProxyPort(), a2.getProxyPort());
+ assertEquals(a1.getMmsc(), a2.getMmsc());
+ assertEquals(a1.getMmsProxyAddressAsString(), a2.getMmsProxyAddressAsString());
+ assertEquals(a1.getMmsProxyPort(), a2.getMmsProxyPort());
+ assertEquals(a1.getUser(), a2.getUser());
+ assertEquals(a1.getPassword(), a2.getPassword());
+ assertEquals(a1.getAuthType(), a2.getAuthType());
+ assertEquals(a1.getId(), a2.getId());
+ assertEquals(a1.getOperatorNumeric(), a2.getOperatorNumeric());
+ assertEquals(a1.getProtocol(), a2.getProtocol());
+ assertEquals(a1.getRoamingProtocol(), a2.getRoamingProtocol());
+ assertEquals(a1.getApnTypeBitmask(), a2.getApnTypeBitmask());
+ assertEquals(a1.isEnabled(), a2.isEnabled());
+ assertEquals(a1.getProfileId(), a2.getProfileId());
+ assertEquals(a1.getModemCognitive(), a2.getModemCognitive());
+ assertEquals(a1.getMaxConns(), a2.getMaxConns());
+ assertEquals(a1.getWaitTime(), a2.getWaitTime());
+ assertEquals(a1.getMaxConnsTime(), a2.getMaxConnsTime());
+ assertEquals(a1.getMtu(), a2.getMtu());
+ assertEquals(a1.getMvnoType(), a2.getMvnoType());
+ assertEquals(a1.getMvnoMatchData(), a2.getMvnoMatchData());
+ assertEquals(a1.getNetworkTypeBitmask(), a2.getNetworkTypeBitmask());
+ assertEquals(a1.getApnSetId(), a2.getApnSetId());
}
@Test
@SmallTest
public void testFromString() throws Exception {
- String[] dunTypes = {"DUN"};
- String[] mmsTypes = {"mms", "*"};
+ final int dunTypesBitmask = ApnSetting.TYPE_DUN;
+ final int mmsTypesBitmask = ApnSetting.TYPE_MMS | ApnSetting.TYPE_ALL;
ApnSetting expectedApn;
String testString;
// A real-world v1 example string.
testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN";
- expectedApn = new ApnSetting(
- -1, "22210", "Vodafone IT", "web.omnitel.it", "", "",
- "", "", "", "", "", 0, dunTypes, "IP", "IP", true, 0, 0,
- 0, false, 0, 0, 0, 0, "", "");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "22210", "Vodafone IT", "web.omnitel.it", "", -1, null, "", -1, "", "", 0,
+ dunTypesBitmask, ApnSetting.PROTOCOL_IP, ApnSetting.PROTOCOL_IP, true,
+ 0, 0, false, 0, 0, 0, 0, -1, "");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v2 string.
testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14";
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "",
- "", "", "", "", "", 0, mmsTypes, "IPV6", "IP", true, 14, 0,
- 0, false, 0, 0, 0, 0, "", "");
+ int networkTypeBitmask = 1 << (13 - 1);
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, -1, "");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v2 string with spaces.
testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV6, IP,true,14";
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "",
- "", "", "", "", "", 0, mmsTypes, "IPV6", "IP", true, 14, 0,
- 0, false, 0, 0, 0, 0, "", "");
- assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
- int networkTypeBitmask = 1 << (13 - 1);
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, networkTypeBitmask, 0, false, 0, 0, 0, 0, "", "");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, -1, "");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v3 string.
testString = "[ApnSettingV3] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14,,,,,,,spn,testspn";
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, 14, 0, 0, false, 0, 0, 0, 0, "spn", "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v4 string with network type bitmask.
testString =
"[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,6";
networkTypeBitmask = 1 << (6 - 1);
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, networkTypeBitmask, 0, false, 0, 0, 0, 0, "spn", "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
testString =
@@ -200,51 +188,48 @@
+ "4|5|6|7|8|12|13|14|19";
// The value was calculated by adding "4|5|6|7|8|12|13|14|19".
networkTypeBitmask = 276728;
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, networkTypeBitmask, 0, false, 0, 0, 0, 0, "spn", "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v4 string with network type bitmask and compatible bearer bitmask.
testString =
"[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,8,,,,,,,spn,testspn, 6";
networkTypeBitmask = 1 << (6 - 1);
- int bearerBitmask = 1 << (8 - 1);
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, 0, bearerBitmask, 0, false, 0, 0, 0, 0, "spn",
- "testspn");
- assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, networkTypeBitmask, 0, false, 0, 0, 0, 0, "spn",
- "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v4 string with network type bitmask and incompatible bearer bitmask.
testString =
"[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,9,,,,,,,spn,testspn, 6";
- bearerBitmask = 1 << (8 - 1);
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, 0, bearerBitmask, 0, false, 0, 0, 0, 0, "spn",
- "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0,
+ 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v5 string with apnSetId=0
testString =
"[ApnSettingV5] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,0";
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, 0, 0, 0, false, 0, 0, 0, 0, "spn", "testspn");
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// A v5 string with apnSetId=3
testString =
"[ApnSettingV5] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3";
- expectedApn = new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, mmsTypes, "IPV6",
- "IP", true, 0, 0, false, 0, 0, 0, 0, "spn", "testspn", 3);
+ expectedApn = ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3);
assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
// Return no apn if insufficient fields given.
@@ -258,6 +243,7 @@
@Test
@SmallTest
public void testArrayFromString() throws Exception {
+ final int mmsTypesBitmask = ApnSetting.TYPE_MMS;
// Test a multiple v3 string.
String testString =
"[ApnSettingV3] Name,apn,,,,,,,,,123,45,,mms,IPV6,IP,true,14,,,,,,,spn,testspn";
@@ -268,44 +254,48 @@
testString +=
" ;[ApnSettingV5] Name1,apn2,,,,,,,,,123,46,,mms,IPV6,IP,true,0,,,,,,,,,,3";
List<ApnSetting> expectedApns = new ArrayList<ApnSetting>();
- expectedApns.add(new ApnSetting(
- -1, "12345", "Name", "apn", "", "", "", "", "", "", "", 0, new String[]{"mms"}, "IPV6",
- "IP", true, 14, 0, 0, false, 0, 0, 0, 0, "spn", "testspn"));
- expectedApns.add(new ApnSetting(
- -1, "12346", "Name1", "apn1", "", "", "", "", "", "", "", 0, new String[]{"mms"}, "IPV6",
- "IP", true, 12, 0, 0, false, 0, 0, 0, 0, "gid", "testGid"));
- expectedApns.add(new ApnSetting(
- -1, "12346", "Name1", "apn2", "", "", "", "", "", "", "", 0, new String[]{"mms"}, "IPV6",
- "IP", true, 12, 0, 0, false, 0, 0, 0, 0, "", ""));
- expectedApns.add(new ApnSetting(
- -1, "12346", "Name1", "apn2", "", "", "", "", "", "", "", 0, new String[]{"mms"}, "IPV6",
- "IP", true, 0, 0, false, 0, 0, 0, 0, "", "", 3));
+ expectedApns.add(ApnSetting.makeApnSetting(
+ -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 1 << (13 - 1), 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn"));
+ expectedApns.add(ApnSetting.makeApnSetting(
+ -1, "12346", "Name1", "apn1", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 1 << (12 - 1), 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_GID, "testGid"));
+ expectedApns.add(ApnSetting.makeApnSetting(
+ -1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 1 << (12 - 1), 0, false, 0, 0, 0, 0, -1, ""));
+ expectedApns.add(ApnSetting.makeApnSetting(
+ -1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
+ mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 0, 0, false, 0, 0, 0, 0, -1, "", 3));
assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString));
}
@Test
@SmallTest
public void testToString() throws Exception {
- String[] types = {"default", "*"};
- // use default apn_set_id constructor
- ApnSetting apn = new ApnSetting(
- 99, "12345", "Name", "apn", "proxy", "port",
- "mmsc", "mmsproxy", "mmsport", "user", "password", 0,
- types, "IPV6", "IP", true, 14, 0, 0, false, 0, 0, 0, 0, "", "");
- String expected = "[ApnSettingV5] Name, 99, 12345, apn, proxy, "
- + "mmsc, mmsproxy, mmsport, port, 0, default | *, "
- + "IPV6, IP, true, 14, 8192, 0, false, 0, 0, 0, 0, , , false, 4096, 0";
+ // Use default apn_set_id constructor.
+ ApnSetting apn = ApnSetting.makeApnSetting(
+ 99, "12345", "Name", "apn", null, 10,
+ null, null, -1, "user", "password", 0,
+ ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ 4096, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "");
+ String expected = "[ApnSettingV5] Name, 99, 12345, apn, null, "
+ + "null, null, null, 10, 0, default, "
+ + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0";
assertEquals(expected, apn.toString());
- int networkTypeBitmask = 1 << (14 - 1);
- int bearerBitmask =
- ServiceState.convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask);
- apn = new ApnSetting(99, "12345", "Name", "apn", "proxy", "port",
- "mmsc", "mmsproxy", "mmsport", "user", "password", 0,
- types, "IPV6", "IP", true, networkTypeBitmask, 0, false, 0, 0, 0, 0, "", "", 3);
- expected = "[ApnSettingV5] Name, 99, 12345, apn, proxy, "
- + "mmsc, mmsproxy, mmsport, port, 0, default | *, IPV6, IP, true, 0, "
- + bearerBitmask + ", 0, false, 0, 0, 0, 0, , , false, 8192, 3";
+ final int networkTypeBitmask = 1 << (14 - 1);
+ apn = ApnSetting.makeApnSetting(
+ 99, "12345", "Name", "apn", null, 10,
+ null, null, -1, "user", "password", 0,
+ ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+ networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3);
+ expected = "[ApnSettingV5] Name, 99, 12345, apn, null, "
+ + "null, null, null, 10, 0, default, "
+ + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3";
assertEquals(expected, apn.toString());
}
@@ -317,50 +307,43 @@
doReturn(false).when(mServiceState).getDataRoaming();
doReturn(1).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT}).isMetered(mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_DEFAULT), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS, PhoneConstants.APN_TYPE_SUPL}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_DUN}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_SUPL}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA), mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_CBS), mPhone));
+
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
// Carrier config settings changes.
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
}
@Test
@@ -371,42 +354,34 @@
doReturn(true).when(mServiceState).getDataRoaming();
doReturn(1).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_DEFAULT), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS, PhoneConstants.APN_TYPE_SUPL}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_DUN}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_SUPL}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_CBS), mPhone));
// Carrier config settings changes.
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_FOTA});
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
}
@Test
@@ -419,42 +394,34 @@
.getRilDataRadioTechnology();
doReturn(1).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_DEFAULT), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_MMS, PhoneConstants.APN_TYPE_SUPL})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_DUN})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_SUPL})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_CBS})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_CBS), mPhone));
// Carrier config settings changes.
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_FOTA});
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
}
@Test
@@ -465,33 +432,26 @@
doReturn(false).when(mServiceState).getDataRoaming();
doReturn(1).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_CBS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_SUPL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_IA}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_IMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_IMS), mPhone));
+
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
}
@Test
@@ -501,42 +461,35 @@
new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS});
doReturn(true).when(mServiceState).getDataRoaming();
doReturn(2).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_CBS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_SUPL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_IA}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_IMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_IMS), mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
+
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
}
@Test
@@ -548,42 +501,35 @@
doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN).when(mServiceState)
.getRilDataRadioTechnology();
doReturn(2).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_CBS})
- .isMetered(mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_CBS}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_SUPL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_SUPL, PhoneConstants.APN_TYPE_IA})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_IMS})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_IMS), mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
- assertTrue(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
- assertFalse(ApnSetting.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
+
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_SUPL, mPhone));
+ assertTrue(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_CBS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DEFAULT, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_MMS, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_DUN, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_FOTA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_IA, mPhone));
+ assertFalse(ApnSettingUtils.isMeteredApnType(PhoneConstants.APN_TYPE_HIPRI, mPhone));
}
@Test
@@ -595,19 +541,16 @@
doReturn(false).when(mServiceState).getDataRoaming();
doReturn(3).when(mPhone).getSubId();
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS, PhoneConstants.APN_TYPE_MMS})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_FOTA})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_FOTA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
}
@Test
@@ -618,20 +561,16 @@
doReturn(true).when(mServiceState).getDataRoaming();
doReturn(3).when(mPhone).getSubId();
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS, PhoneConstants.APN_TYPE_MMS}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_FOTA}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_FOTA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).
- isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
}
@Test
@@ -644,19 +583,16 @@
.getRilDataRadioTechnology();
doReturn(3).when(mPhone).getSubId();
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IMS, PhoneConstants.APN_TYPE_MMS})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_FOTA})
- .isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_FOTA), mPhone));
- assertFalse(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertFalse(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
}
@Test
@@ -668,22 +604,17 @@
doReturn(false).when(mServiceState).getDataRoaming();
doReturn(4).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_DUN}).
- isMetered(mPhone));
-
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_DUN), mPhone));
}
@Test
@@ -695,20 +626,17 @@
doReturn(true).when(mServiceState).getDataRoaming();
doReturn(4).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_DUN})
- .isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_DUN), mPhone));
}
@Test
@@ -722,20 +650,17 @@
.getRilDataRadioTechnology();
doReturn(4).when(mPhone).getSubId();
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_ALL}).isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_FOTA, PhoneConstants.APN_TYPE_CBS}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
- assertTrue(createApnSetting(
- new String[]{PhoneConstants.APN_TYPE_IA, PhoneConstants.APN_TYPE_DUN}).
- isMetered(mPhone));
+ assertTrue(ApnSettingUtils.isMetered(
+ createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_DUN), mPhone));
}
@Test
@@ -743,59 +668,52 @@
public void testCanHandleType() throws Exception {
String types[] = {"mms"};
- // empty string replaced with ALL ('*') when loaded to db
- assertFalse(createApnSetting(new String[]{}).
- canHandleType(APN_TYPE_MMS));
+ assertTrue(createApnSetting(ApnSetting.TYPE_ALL)
+ .canHandleType(ApnSetting.TYPE_MMS));
- assertTrue(createApnSetting(new String[]{APN_TYPE_ALL}).
- canHandleType(APN_TYPE_MMS));
+ assertFalse(createApnSetting(ApnSetting.TYPE_DEFAULT)
+ .canHandleType(ApnSetting.TYPE_MMS));
- assertFalse(createApnSetting(new String[]{APN_TYPE_DEFAULT}).
- canHandleType(APN_TYPE_MMS));
-
- assertTrue(createApnSetting(new String[]{"DEfAULT"}).
- canHandleType("defAult"));
+ assertTrue(createApnSetting(ApnSetting.TYPE_DEFAULT)
+ .canHandleType(ApnSetting.TYPE_DEFAULT));
// Hipri is asymmetric
- assertTrue(createApnSetting(new String[]{APN_TYPE_DEFAULT}).
- canHandleType(APN_TYPE_HIPRI));
- assertFalse(createApnSetting(new String[]{APN_TYPE_HIPRI}).
- canHandleType(APN_TYPE_DEFAULT));
+ assertTrue(createApnSetting(ApnSetting.TYPE_DEFAULT)
+ .canHandleType(ApnSetting.TYPE_HIPRI));
+ assertFalse(createApnSetting(ApnSetting.TYPE_HIPRI)
+ .canHandleType(ApnSetting.TYPE_DEFAULT));
- assertTrue(createApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_DEFAULT));
+ assertTrue(createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_DEFAULT));
- assertTrue(createApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_MMS));
+ assertTrue(createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_MMS));
- assertFalse(createApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_SUPL));
+ assertFalse(createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_SUPL));
// special IA case - doesn't match wildcards
- assertFalse(createApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_IA));
- assertFalse(createApnSetting(new String[]{APN_TYPE_ALL}).
- canHandleType(APN_TYPE_IA));
- assertFalse(createApnSetting(new String[]{APN_TYPE_ALL}).
- canHandleType("iA"));
- assertTrue(createApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS, APN_TYPE_IA}).
- canHandleType(APN_TYPE_IA));
+ assertFalse(createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_IA));
+ assertTrue(createApnSetting(
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_IA)
+ .canHandleType(ApnSetting.TYPE_IA));
// check carrier disabled
- assertFalse(createDisabledApnSetting(new String[]{APN_TYPE_ALL}).
- canHandleType(APN_TYPE_MMS));
- assertFalse(createDisabledApnSetting(new String[]{"DEfAULT"}).
- canHandleType("defAult"));
- assertFalse(createDisabledApnSetting(new String[]{APN_TYPE_DEFAULT}).
- canHandleType(APN_TYPE_HIPRI));
- assertFalse(createDisabledApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_DEFAULT));
- assertFalse(createDisabledApnSetting(new String[]{APN_TYPE_DEFAULT, APN_TYPE_MMS}).
- canHandleType(APN_TYPE_MMS));
- assertFalse(createDisabledApnSetting(new String[]
- {APN_TYPE_DEFAULT, APN_TYPE_MMS, APN_TYPE_IA}).
- canHandleType(APN_TYPE_IA));
+ assertFalse(createDisabledApnSetting(ApnSetting.TYPE_ALL)
+ .canHandleType(ApnSetting.TYPE_MMS));
+ assertFalse(createDisabledApnSetting(ApnSetting.TYPE_DEFAULT)
+ .canHandleType(ApnSetting.TYPE_DEFAULT));
+ assertFalse(createDisabledApnSetting(ApnSetting.TYPE_DEFAULT)
+ .canHandleType(ApnSetting.TYPE_HIPRI));
+ assertFalse(createDisabledApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_DEFAULT));
+ assertFalse(createDisabledApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ .canHandleType(ApnSetting.TYPE_MMS));
+ assertFalse(createDisabledApnSetting(
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_IA)
+ .canHandleType(ApnSetting.TYPE_IA));
}
@Test
@@ -804,8 +722,10 @@
final int dummyInt = 1;
final String dummyString = "dummy";
final String[] dummyStringArr = new String[] {"dummy"};
+ final InetAddress dummyProxyAddress = InetAddress.getByAddress(new byte[]{0, 0, 0, 0});
+ final Uri dummyUri = Uri.parse("www.google.com");
// base apn
- ApnSetting baseApn = createApnSetting(new String[] {"mms", "default"});
+ ApnSetting baseApn = createApnSetting(ApnSetting.TYPE_MMS | ApnSetting.TYPE_DEFAULT);
Field[] fields = ApnSetting.class.getDeclaredFields();
for (Field f : fields) {
int modifiers = f.getModifiers();
@@ -815,17 +735,23 @@
f.setAccessible(true);
ApnSetting testApn = null;
if (int.class.equals(f.getType())) {
- testApn = new ApnSetting(baseApn);
+ testApn = ApnSetting.makeApnSetting(baseApn);
f.setInt(testApn, dummyInt + f.getInt(testApn));
} else if (boolean.class.equals(f.getType())) {
- testApn = new ApnSetting(baseApn);
+ testApn = ApnSetting.makeApnSetting(baseApn);
f.setBoolean(testApn, !f.getBoolean(testApn));
} else if (String.class.equals(f.getType())) {
- testApn = new ApnSetting(baseApn);
+ testApn = ApnSetting.makeApnSetting(baseApn);
f.set(testApn, dummyString);
} else if (String[].class.equals(f.getType())) {
- testApn = new ApnSetting(baseApn);
+ testApn = ApnSetting.makeApnSetting(baseApn);
f.set(testApn, dummyStringArr);
+ } else if (InetAddress.class.equals(f.getType())) {
+ testApn = ApnSetting.makeApnSetting(baseApn);
+ f.set(testApn, dummyProxyAddress);
+ } else if (Uri.class.equals(f.getType())) {
+ testApn = ApnSetting.makeApnSetting(baseApn);
+ f.set(testApn, dummyUri);
} else {
fail("Unsupported field:" + f.getName());
}
@@ -838,60 +764,58 @@
@Test
@SmallTest
public void testEqualsRoamingProtocol() throws Exception {
- ApnSetting apn1 = new ApnSetting(
+ ApnSetting apn1 = ApnSetting.makeApnSetting(
1234,
"310260",
"",
"ims",
- "",
- "",
- "",
- "",
- "",
+ null,
+ -1,
+ null,
+ null,
+ -1,
"",
"",
-1,
- new String[]{"ims"},
- "IPV6",
- "",
+ ApnSetting.TYPE_IMS,
+ ApnSetting.PROTOCOL_IPV6,
+ -1,
true,
- 0,
- 131071,
+ ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131071),
0,
false,
0,
0,
0,
1440,
- "",
+ -1,
"");
- ApnSetting apn2 = new ApnSetting(
+ ApnSetting apn2 = ApnSetting.makeApnSetting(
1235,
"310260",
"",
"ims",
- "",
- "",
- "",
- "",
- "",
+ null,
+ -1,
+ null,
+ null,
+ -1,
"",
"",
-1,
- new String[]{"ims"},
- "IPV6",
- "IPV6",
+ ApnSetting.TYPE_IMS,
+ ApnSetting.PROTOCOL_IPV6,
+ ApnSetting.PROTOCOL_IPV6,
true,
- 0,
- 131072,
+ ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131072),
0,
false,
0,
0,
0,
1440,
- "",
+ -1,
"");
assertTrue(apn1.equals(apn2, false));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index f0b2584..ce5eaeb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -55,6 +55,7 @@
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
@@ -98,60 +99,58 @@
private DataConnectionTestHandler mDataConnectionTestHandler;
private DcController mDcc;
- private ApnSetting mApn1 = new ApnSetting(
+ private ApnSetting mApn1 = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"spmode.ne.jp", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
- private ApnSetting mApn2 = new ApnSetting(
+ private ApnSetting mApn2 = ApnSetting.makeApnSetting(
2164, // id
"44010", // numeric
"sp-mode", // name
"spmode.ne.jp", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- new String[]{"default", "dun"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
private class DataConnectionTestHandler extends HandlerThread {
@@ -176,7 +175,7 @@
CellularDataService cellularDataService = new CellularDataService();
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = "com.android.phone";
- serviceInfo.permission = "android.permission.BIND_DATA_SERVICE";
+ serviceInfo.permission = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
IntentFilter filter = new IntentFilter();
mContextFixture.addService(
DataService.DATA_SERVICE_INTERFACE,
@@ -501,6 +500,7 @@
assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
}
+ @Test
@SmallTest
public void testIsIpAddress() throws Exception {
// IPv4
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java
index 5dbe995..97fcc75 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.dataconnection;
import android.telephony.ServiceState;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataProfile;
import android.test.suitebuilder.annotation.SmallTest;
@@ -26,132 +27,130 @@
public class DataProfileTest extends TestCase {
- private ApnSetting mApn1 = new ApnSetting(
+ private ApnSetting mApn1 = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"fake_apn", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"user", // user
"passwd", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IPV6", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IPV6, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
1234, // profile_id
false, // modem_cognitive
321, // max_conns
456, // wait_time
789, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
- private ApnSetting mApn2 = new ApnSetting(
+ private ApnSetting mApn2 = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"fake_apn", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"user", // user
"passwd", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
1234, // profile_id
false, // modem_cognitive
111, // max_conns
456, // wait_time
789, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
- private ApnSetting mApn3 = new ApnSetting(
+ private ApnSetting mApn3 = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"fake_apn", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"user", // user
"passwd", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 276600, // network_type_bitmask
+ 276600, // networktype_bitmask
1234, // profile_id
false, // modem_cognitive
111, // max_conns
456, // wait_time
789, // max_conns_time
0, // mtu
- "", // mvno_type
- "" // mnvo_match_data
- );
+ -1, // mvno_type
+ ""); // mnvo_match_data
@SmallTest
public void testCreateFromApnSetting() throws Exception {
- DataProfile dp = DcTracker.createDataProfile(mApn1, mApn1.profileId);
- assertEquals(mApn1.profileId, dp.getProfileId());
- assertEquals(mApn1.apn, dp.getApn());
- assertEquals(mApn1.protocol, dp.getProtocol());
+ DataProfile dp = DcTracker.createDataProfile(mApn1, mApn1.getProfileId());
+ assertEquals(mApn1.getProfileId(), dp.getProfileId());
+ assertEquals(mApn1.getApnName(), dp.getApn());
+ assertEquals(ApnSetting.getProtocolStringFromInt(mApn1.getProtocol()), dp.getProtocol());
assertEquals(RILConstants.SETUP_DATA_AUTH_PAP_CHAP, dp.getAuthType());
- assertEquals(mApn1.user, dp.getUserName());
- assertEquals(mApn1.password, dp.getPassword());
+ assertEquals(mApn1.getUser(), dp.getUserName());
+ assertEquals(mApn1.getPassword(), dp.getPassword());
assertEquals(0, dp.getType()); // TYPE_COMMON
- assertEquals(mApn1.maxConnsTime, dp.getMaxConnsTime());
- assertEquals(mApn1.maxConns, dp.getMaxConns());
- assertEquals(mApn1.waitTime, dp.getWaitTime());
- assertEquals(mApn1.carrierEnabled, dp.isEnabled());
+ assertEquals(mApn1.getMaxConnsTime(), dp.getMaxConnsTime());
+ assertEquals(mApn1.getMaxConns(), dp.getMaxConns());
+ assertEquals(mApn1.getWaitTime(), dp.getWaitTime());
+ assertEquals(mApn1.isEnabled(), dp.isEnabled());
}
@SmallTest
public void testCreateFromApnSettingWithNetworkTypeBitmask() throws Exception {
- DataProfile dp = DcTracker.createDataProfile(mApn3, mApn3.profileId);
- assertEquals(mApn3.profileId, dp.getProfileId());
- assertEquals(mApn3.apn, dp.getApn());
- assertEquals(mApn3.protocol, dp.getProtocol());
+ DataProfile dp = DcTracker.createDataProfile(mApn3, mApn3.getProfileId());
+ assertEquals(mApn3.getProfileId(), dp.getProfileId());
+ assertEquals(mApn3.getApnName(), dp.getApn());
+ assertEquals(ApnSetting.getProtocolStringFromInt(mApn3.getProtocol()), dp.getProtocol());
assertEquals(RILConstants.SETUP_DATA_AUTH_PAP_CHAP, dp.getAuthType());
- assertEquals(mApn3.user, dp.getUserName());
- assertEquals(mApn3.password, dp.getPassword());
+ assertEquals(mApn3.getUser(), dp.getUserName());
+ assertEquals(mApn3.getPassword(), dp.getPassword());
assertEquals(2, dp.getType()); // TYPE_3GPP2
- assertEquals(mApn3.maxConnsTime, dp.getMaxConnsTime());
- assertEquals(mApn3.maxConns, dp.getMaxConns());
- assertEquals(mApn3.waitTime, dp.getWaitTime());
- assertEquals(mApn3.carrierEnabled, dp.isEnabled());
+ assertEquals(mApn3.getMaxConnsTime(), dp.getMaxConnsTime());
+ assertEquals(mApn3.getMaxConns(), dp.getMaxConns());
+ assertEquals(mApn3.getWaitTime(), dp.getWaitTime());
+ assertEquals(mApn3.isEnabled(), dp.isEnabled());
int expectedBearerBitmap =
- ServiceState.convertNetworkTypeBitmaskToBearerBitmask(mApn3.networkTypeBitmask);
+ ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+ mApn3.getNetworkTypeBitmask());
assertEquals(expectedBearerBitmap, dp.getBearerBitmap());
}
@SmallTest
public void testEquals() throws Exception {
- DataProfile dp1 = DcTracker.createDataProfile(mApn1, mApn1.profileId);
- DataProfile dp2 = DcTracker.createDataProfile(mApn1, mApn1.profileId);
+ DataProfile dp1 = DcTracker.createDataProfile(mApn1, mApn1.getProfileId());
+ DataProfile dp2 = DcTracker.createDataProfile(mApn1, mApn1.getProfileId());
assertEquals(dp1, dp2);
- dp2 = DcTracker.createDataProfile(mApn2, mApn2.profileId);
+ dp2 = DcTracker.createDataProfile(mApn2, mApn2.getProfileId());
assertFalse(dp1.equals(dp2));
}
}
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 17f026f..451571e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -64,12 +64,14 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
import android.util.LocalLog;
import com.android.internal.R;
@@ -126,7 +128,6 @@
private static final Uri PREFERAPN_URI = Uri.parse(
Telephony.Carriers.CONTENT_URI + "/preferapn");
-
@Mock
ISub mIsub;
@Mock
@@ -158,7 +159,7 @@
CellularDataService cellularDataService = new CellularDataService();
ServiceInfo serviceInfo = new ServiceInfo();
serviceInfo.packageName = "com.android.phone";
- serviceInfo.permission = "android.permission.BIND_DATA_SERVICE";
+ serviceInfo.permission = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
IntentFilter filter = new IntentFilter();
mContextFixture.addService(
DataService.DATA_SERVICE_INTERFACE,
@@ -604,7 +605,7 @@
logd("Sending EVENT_ENABLE_NEW_APN");
// APN id 0 is APN_TYPE_DEFAULT
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
waitForMs(200);
dataConnectionReasons = new DataConnectionReasons();
@@ -678,7 +679,7 @@
logd("Sending EVENT_ENABLE_NEW_APN");
// APN id 0 is APN_TYPE_DEFAULT
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
waitForMs(200);
@@ -737,8 +738,8 @@
boolean dataEnabled = mDct.isUserDataEnabled();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
- mDct.setEnabled(DctConstants.APN_IMS_ID, true);
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_IMS, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
logd("Sending EVENT_RECORDS_LOADED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
@@ -792,8 +793,8 @@
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
- mDct.setEnabled(DctConstants.APN_IMS_ID, true);
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_IMS, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
logd("Sending EVENT_RECORDS_LOADED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
@@ -850,8 +851,8 @@
//set Default and MMS to be metered in the CarrierConfigManager
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS});
- mDct.setEnabled(DctConstants.APN_IMS_ID, true);
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_IMS, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
logd("Sending DATA_ENABLED_CMD");
mDct.setUserDataEnabled(true);
@@ -965,8 +966,8 @@
boolean dataEnabled = mDct.isUserDataEnabled();
mDct.setUserDataEnabled(true);
- mDct.setEnabled(DctConstants.APN_IMS_ID, true);
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_IMS, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
logd("Sending EVENT_RECORDS_LOADED");
mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_RECORDS_LOADED, null));
@@ -1006,7 +1007,8 @@
private void initApns(String targetApn, String[] canHandleTypes) {
doReturn(targetApn).when(mApnContext).getApnType();
doReturn(true).when(mApnContext).isConnectable();
- ApnSetting apnSetting = createApnSetting(canHandleTypes);
+ ApnSetting apnSetting = createApnSetting(ApnSetting.getApnTypesBitmaskFromString(
+ TextUtils.join(",", canHandleTypes)));
doReturn(apnSetting).when(mApnContext).getNextApnSetting();
doReturn(apnSetting).when(mApnContext).getApnSetting();
doReturn(mDcac).when(mApnContext).getDcAc();
@@ -1261,7 +1263,7 @@
.getRilDataRadioTechnology();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
mDct.setUserDataEnabled(true);
initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
@@ -1338,7 +1340,7 @@
Settings.Global.TETHER_DUN_APN, null);
// should return APN from db
dunApn = mDct.fetchDunApns().get(0);
- assertEquals(FAKE_APN5, dunApn.apn);
+ assertEquals(FAKE_APN5, dunApn.getApnName());
}
// Test for fetchDunApns() with apn set id
@@ -1381,7 +1383,7 @@
.getRilDataRadioTechnology();
mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
new String[]{PhoneConstants.APN_TYPE_DEFAULT});
- mDct.setEnabled(DctConstants.APN_DEFAULT_ID, true);
+ mDct.setEnabled(ApnSetting.TYPE_DEFAULT, true);
mDct.setUserDataEnabled(true);
initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
index 6b00289..2f452f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
@@ -16,8 +16,12 @@
package com.android.internal.telephony.dataconnection;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
+import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.RetryManager;
@@ -31,97 +35,91 @@
import java.util.ArrayList;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
/**
* APN retry manager tests
*/
public class RetryManagerTest extends TelephonyTest {
// This is the real APN data for the Japanese carrier NTT Docomo.
- private ApnSetting mApn1 = new ApnSetting(
+ private ApnSetting mApn1 = ApnSetting.makeApnSetting(
2163, // id
"44010", // numeric
"sp-mode", // name
"spmode.ne.jp", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
- private ApnSetting mApn2 = new ApnSetting(
+ private ApnSetting mApn2 = ApnSetting.makeApnSetting(
2164, // id
"44010", // numeric
"mopera U", // name
"mopera.net", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
-1, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
- private ApnSetting mApn3 = new ApnSetting(
+ private ApnSetting mApn3 = ApnSetting.makeApnSetting(
2165, // id
"44010", // numeric
"b-mobile for Nexus", // name
"bmobile.ne.jp", // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
+ null, // proxy
+ -1, // port
+ null, // mmsc
+ null, // mmsproxy
+ -1, // mmsport
"", // user
"", // password
3, // authtype
- new String[]{"default", "supl"}, // types
- "IP", // protocol
- "IP", // roaming_protocol
+ ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+ ApnSetting.PROTOCOL_IP, // protocol
+ ApnSetting.PROTOCOL_IP, // roaming_protocol
true, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
+ 0, // networktype_bitmask
0, // profile_id
false, // modem_cognitive
0, // max_conns
0, // wait_time
0, // max_conns_time
0, // mtu
- "", // mvno_type
+ -1, // mvno_type
""); // mnvo_match_data
private PersistableBundle mBundle;
@@ -173,7 +171,7 @@
new String[]{"default:"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
RetryManager rm = new RetryManager(mPhone, "default");
rm.setWaitingApns(waitingApns);
@@ -195,7 +193,7 @@
new String[]{"supl:2000,3000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
RetryManager rm = new RetryManager(mPhone, "supl");
rm.setWaitingApns(waitingApns);
@@ -249,8 +247,8 @@
new String[]{"others:2000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "default");
rm.setWaitingApns(waitingApns);
@@ -287,8 +285,8 @@
new String[]{"dun:2000,5000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "dun");
rm.setWaitingApns(waitingApns);
@@ -335,8 +333,8 @@
new String[]{"mms: 3000,6000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "mms");
rm.setWaitingApns(waitingApns);
@@ -383,7 +381,7 @@
new String[]{"fota:1000,4000,7000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting apn = new ApnSetting(mApn1);
+ ApnSetting apn = ApnSetting.makeApnSetting(mApn1);
waitingApns.add(apn);
RetryManager rm = new RetryManager(mPhone, "fota");
@@ -416,8 +414,8 @@
new String[]{"xyz : 1000,4000,7000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
@@ -473,9 +471,9 @@
new String[]{"default:2000:2000,3000:3000", "ims:1000,4000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
- ApnSetting myApn3 = new ApnSetting(mApn3);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
+ ApnSetting myApn3 = ApnSetting.makeApnSetting(mApn3);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
waitingApns.add(myApn3);
@@ -532,8 +530,8 @@
new String[]{"default:1000,4000,7000,9000", "mms:1234,4123"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
@@ -587,7 +585,7 @@
new String[]{"default:default_randomization=1000,3000:2000,6000:3000,10000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
RetryManager rm = new RetryManager(mPhone, "default");
rm.setWaitingApns(waitingApns);
@@ -624,8 +622,8 @@
new String[]{"default:max_retries=infinite,1000,2000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "default");
rm.setWaitingApns(waitingApns);
@@ -682,8 +680,8 @@
new String[]{"hipri: max_retries=4,1000,2000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "hipri");
rm.setWaitingApns(waitingApns);
@@ -752,8 +750,8 @@
mBundle.putLong(CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 2000);
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(new ApnSetting(mApn1));
- waitingApns.add(new ApnSetting(mApn2));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn1));
+ waitingApns.add(ApnSetting.makeApnSetting(mApn2));
RetryManager rm = new RetryManager(mPhone, "default");
rm.setWaitingApns(waitingApns);
@@ -800,8 +798,8 @@
new String[]{"dun:1000,4000,7000,9000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
@@ -845,7 +843,7 @@
// reset the retry manager
- ApnSetting myApn3 = new ApnSetting(mApn3);
+ ApnSetting myApn3 = ApnSetting.makeApnSetting(mApn3);
waitingApns.clear();
waitingApns.add(myApn3);
@@ -881,8 +879,8 @@
new String[]{"others:1000,4000,7000,9000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
@@ -937,8 +935,8 @@
new String[]{"default:1000,4000,7000,9000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
@@ -980,8 +978,8 @@
new String[]{"mms:2000,3000", "default:1000,4000,7000,9000"});
ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = new ApnSetting(mApn1);
- ApnSetting myApn2 = new ApnSetting(mApn2);
+ ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
+ ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
waitingApns.add(myApn1);
waitingApns.add(myApn2);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
index f217c7d..fd19f80 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -35,6 +36,7 @@
import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
+import com.android.ims.MmTelFeatureConnection;
import com.android.internal.telephony.TelephonyTest;
import org.junit.After;
@@ -47,13 +49,16 @@
public class ImsManagerTest extends TelephonyTest {
private static final String UNSET_PROVISIONED_STRING = "unset";
private static final boolean ENHANCED_4G_MODE_DEFAULT_VAL = true;
- private static final boolean ENHANCED_4G_ENABLE_DEFAULT_VAL = true;
private static final boolean ENHANCED_4G_MODE_EDITABLE = true;
private static final boolean WFC_IMS_ENABLE_DEFAULT_VAL = false;
private static final boolean WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL = true;
private static final boolean VT_IMS_ENABLE_DEFAULT_VAL = true;
- private static final int WFC_IMS_MODE_DEFAULT_VAL = 2;
- private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL = 3;
+ private static final boolean WFC_IMS_EDITABLE_VAL = true;
+ private static final boolean WFC_IMS_NOT_EDITABLE_VAL = false;
+ private static final int WFC_IMS_MODE_DEFAULT_VAL =
+ ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
+ private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL =
+ ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED;
PersistableBundle mBundle;
@@ -64,7 +69,7 @@
Hashtable<Integer, Integer> mProvisionedIntVals = new Hashtable<>();
Hashtable<Integer, String> mProvisionedStringVals = new Hashtable<>();
ImsConfigImplBase.ImsConfigStub mImsConfigStub;
- ImsConfig mImsConfig;
+ @Mock MmTelFeatureConnection mMmTelFeatureConnection;
private final int[] mSubId = {0};
private int mPhoneId;
@@ -80,6 +85,8 @@
doReturn(mSubscriptionController).when(mBinder).queryLocalInterface(anyString());
mServiceManagerMockedServices.put("isub", mBinder);
+ doReturn(true).when(mMmTelFeatureConnection).isBinderAlive();
+
mImsManagerInstances.remove(mPhoneId);
setDefaultValues();
@@ -92,7 +99,9 @@
private void setDefaultValues() {
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL,
- ENHANCED_4G_ENABLE_DEFAULT_VAL);
+ ENHANCED_4G_MODE_EDITABLE);
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
+ WFC_IMS_EDITABLE_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL,
WFC_IMS_ENABLE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL,
@@ -119,7 +128,7 @@
eq(SubscriptionManager.WFC_IMS_ENABLED),
anyString());
- assertEquals(ENHANCED_4G_ENABLE_DEFAULT_VAL,
+ assertEquals(ENHANCED_4G_MODE_DEFAULT_VAL,
imsManager.isEnhanced4gLteModeSettingEnabledByUser());
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
@@ -239,7 +248,126 @@
}
- private ImsManager initializeProvisionedValues() {
+ /**
+ * Tests that when a WFC mode is set for home/roaming, that setting is sent to the ImsService
+ * correctly.
+ *
+ * Preconditions:
+ * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true
+ */
+ @Test @SmallTest
+ public void testSetWfcSetting_true_shouldSetWfcModeWrtRoamingState() throws Exception {
+ // First, Set WFC home/roaming mode that is not the Carrier Config default.
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+ ImsManager imsManager = initializeProvisionedValues();
+
+ // Roaming
+ doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+ // Roaming mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED));
+
+ // Not roaming
+ doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+ // Home mode (WIFI_PREFERRED) should be set. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED));
+ }
+
+ /**
+ * Tests that the settings for WFC mode are ignored if the Carrier sets the settings to not
+ * editable.
+ *
+ * Preconditions:
+ * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = false
+ */
+ @Test @SmallTest
+ public void testSetWfcSetting_wfcNotEditable() throws Exception {
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
+ WFC_IMS_NOT_EDITABLE_VAL);
+ // Set some values that are different than the defaults for WFC mode.
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_MODE),
+ anyString());
+ doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
+ .when(mSubscriptionController).getSubscriptionProperty(
+ anyInt(),
+ eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
+ anyString());
+ ImsManager imsManager = initializeProvisionedValues();
+
+ // Roaming
+ doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+ // User defined setting for Roaming mode (WIFI_ONLY) should be set independent of whether or
+ // not WFC mode is editable. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
+
+ // Not roaming
+ doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+ // Default Home mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(WFC_IMS_MODE_DEFAULT_VAL));
+ }
+
+ /**
+ * Tests that the CarrierConfig defaults will be used if no setting is set in the Subscription
+ * Manager.
+ *
+ * Preconditions:
+ * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true
+ * - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = Carrier preferred
+ * - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = WiFi preferred
+ */
+ @Test @SmallTest
+ public void testSetWfcSetting_noUserSettingSet() throws Exception {
+ ImsManager imsManager = initializeProvisionedValues();
+
+ // Roaming
+ doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+
+ // Default Roaming mode (WIFI_PREFERRED) for carrier should be set. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(WFC_IMS_ROAMING_MODE_DEFAULT_VAL));
+
+ // Not roaming
+ doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
+ // Turn on WFC
+ imsManager.setWfcSetting(true);
+
+ // Default Home mode (CELLULAR_PREFERRED) for carrier should be set. With 1000 ms timeout.
+ verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
+ eq(WFC_IMS_MODE_DEFAULT_VAL));
+ }
+
+ private ImsManager initializeProvisionedValues() throws Exception {
when(mImsConfigImplBaseMock.getConfigInt(anyInt()))
.thenAnswer(invocation -> {
return getProvisionedInt((Integer) (invocation.getArguments()[0]));
@@ -255,15 +383,13 @@
// Configure ImsConfigStub
mImsConfigStub = new ImsConfigImplBase.ImsConfigStub(mImsConfigImplBaseMock);
- doReturn(mImsConfigStub).when(mImsConfigImplBaseMock).getIImsConfig();
-
- // Configure ImsConfig
- mImsConfig = new ImsConfig(mImsConfigStub, mContext);
+ doReturn(mImsConfigStub).when(mMmTelFeatureConnection).getConfigInterface();
// Configure ImsManager
ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
try {
- replaceInstance(ImsManager.class, "mConfig", imsManager, mImsConfig);
+ replaceInstance(ImsManager.class, "mMmTelFeatureConnection", imsManager,
+ mMmTelFeatureConnection);
} catch (Exception ex) {
fail("failed with " + ex);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/mocks/DcTrackerMock.java b/tests/telephonytests/src/com/android/internal/telephony/mocks/DcTrackerMock.java
index a09c4eb..c02f68b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/mocks/DcTrackerMock.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/mocks/DcTrackerMock.java
@@ -53,14 +53,6 @@
throw new RuntimeException("Not Implemented");
}
@Override
- public boolean isApnSupported(String name) {
- throw new RuntimeException("Not Implemented");
- }
- @Override
- public int getApnPriority(String name) {
- throw new RuntimeException("Not Implemented");
- }
- @Override
public LinkProperties getLinkProperties(String apnType) {
throw new RuntimeException("Not Implemented");
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
index dc21b70..27b8531 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
@@ -63,7 +63,8 @@
@Override
public void onLooperPrepared() {
mUicccard = new UiccCard(mContextFixture.getTestDouble(),
- mSimulatedCommands, mIccCardStatus, 0 /* phoneId */);
+ mSimulatedCommands, mIccCardStatus, 0 /* phoneId */,
+ new Object());
/* create a custom handler for the Handler Thread */
mHandler = new Handler(mTestHandlerThread.getLooper()) {
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
index 1e12729..01220d5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
@@ -82,7 +82,7 @@
public void onLooperPrepared() {
mUiccProfile = new UiccProfile(mContextFixture.getTestDouble(),
mSimulatedCommands, mIccCardStatus, 0 /* phoneId */,
- mUiccCard);
+ mUiccCard, new Object());
/* create a custom handler for the Handler Thread */
mHandler = new Handler(mTestHandlerThread.getLooper()) {
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index e3ac6a8..457f021 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -251,7 +251,8 @@
mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId);
verify(mTelephonyComponentFactory).makeUiccProfile(
- anyObject(), eq(mSimulatedCommands), eq(mIccCardStatus), anyInt(), anyObject());
+ anyObject(), eq(mSimulatedCommands), eq(mIccCardStatus), anyInt(), anyObject(),
+ anyObject());
assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
assertNotNull(mUiccSlot.getUiccCard());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
index a90e947..f933596 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
@@ -101,7 +101,7 @@
// The first broadcast should be sent after initialization.
UiccCard card = new UiccCard(mContext, mSimulatedCommands,
- makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */);
+ makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */, new Object());
when(UiccController.getInstance().getUiccCardForPhone(0)).thenReturn(card);
uiccLauncher.handleMessage(msg);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
index 831d0b8..dc621a5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
@@ -103,7 +103,7 @@
public void onLooperPrepared() {
mEuiccCard =
new EuiccCard(mContextFixture.getTestDouble(), mMockCi, mMockIccCardStatus,
- 0 /* phoneId */) {
+ 0 /* phoneId */, new Object()) {
@Override
protected byte[] getDeviceId() {
return IccUtils.bcdToBytes("987654321012345");
@@ -173,7 +173,7 @@
final CountDownLatch latch = new CountDownLatch(1);
mHandler.post(() -> {
mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
- mMockIccCardStatus, 0 /* phoneId */);
+ mMockIccCardStatus, 0 /* phoneId */, new Object());
latch.countDown();
});
assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS));