Merge "Extract telephony-protos target."
diff --git a/src/java/com/android/internal/telephony/AnswerToReset.java b/src/java/com/android/internal/telephony/AnswerToReset.java
new file mode 100644
index 0000000..4440fd2
--- /dev/null
+++ b/src/java/com/android/internal/telephony/AnswerToReset.java
@@ -0,0 +1,415 @@
+/*
+ * 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 android.annotation.Nullable;
+import android.telephony.Rlog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.uicc.IccUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This class parses an Answer To Reset (ATR) message.
+ * The ATR message structure is defined in standard ISO/IEC 7816-3. The eUICC related ATR message
+ * is defined in standard ETSI TS 102 221 V14.0.0.
+ */
+public class AnswerToReset {
+ private static final String TAG = "AnswerToReset";
+ private static final boolean VDBG = false; // STOPSHIP if true
+
+ public static final byte EUICC_SUPPORTED = (byte) 0x82;
+ public static final byte DIRECT_CONVENTION = (byte) 0x3B;
+ public static final byte INVERSE_CONVENTION = (byte) 0x3F;
+ public static final int INTERFACE_BYTES_MASK = 0xF0;
+ public static final int T_MASK = 0x0F;
+ public static final int T_VALUE_FOR_GLOBAL_INTERFACE = 15;
+ public static final int TA_MASK = 0x10;
+ public static final int TB_MASK = 0x20;
+ public static final int TC_MASK = 0x40;
+ public static final int TD_MASK = 0x80;
+
+ private boolean mIsDirectConvention;
+ private boolean mOnlyTEqualsZero = true;
+ private boolean mIsEuiccSupported;
+ private byte mFormatByte;
+ private ArrayList<InterfaceByte> mInterfaceBytes = new ArrayList<>();
+ private byte[] mHistoricalBytes;
+ private Byte mCheckByte;
+
+ /**
+ * Returns an AnswerToReset by parsing the input atr string, return null if the parsing fails.
+ */
+ public static AnswerToReset parseAtr(String atr) {
+ AnswerToReset answerToReset = new AnswerToReset();
+ if (answerToReset.parseAtrString(atr)) {
+ return answerToReset;
+ }
+ return null;
+ }
+
+ private AnswerToReset() {}
+
+ private static String byteToStringHex(Byte b) {
+ return b == null ? null : IccUtils.byteToHex(b);
+ }
+
+ private void checkIsEuiccSupported() {
+ // eUICC is supported only if the value of the first tB after T=15 is 82.
+ for (int i = 0; i < mInterfaceBytes.size() - 1; i++) {
+ if (mInterfaceBytes.get(i).getTD() != null
+ && (mInterfaceBytes.get(i).getTD() & T_MASK) == T_VALUE_FOR_GLOBAL_INTERFACE
+ && mInterfaceBytes.get(i + 1).getTB() != null
+ && mInterfaceBytes.get(i + 1).getTB() == EUICC_SUPPORTED) {
+ mIsEuiccSupported = true;
+ return;
+ }
+ }
+ }
+
+ private int parseConventionByte(byte[] atrBytes, int index) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the convention byte.");
+ return -1;
+ }
+ byte value = atrBytes[index];
+ if (value == DIRECT_CONVENTION) {
+ mIsDirectConvention = true;
+ } else if (value == INVERSE_CONVENTION) {
+ mIsDirectConvention = false;
+ } else {
+ loge("Unrecognized convention byte " + IccUtils.byteToHex(value));
+ return -1;
+ }
+ return index + 1;
+ }
+
+ private int parseFormatByte(byte[] atrBytes, int index) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the format byte.");
+ return -1;
+ }
+ mFormatByte = atrBytes[index];
+ mHistoricalBytes = new byte[mFormatByte & T_MASK];
+ if (VDBG) log("mHistoricalBytesLength: " + mHistoricalBytes.length);
+ return index + 1;
+ }
+
+ private int parseInterfaceBytes(byte[] atrBytes, int index) {
+ // The first lastTD is actually not any TD but instead the format byte.
+ byte lastTD = mFormatByte;
+ while (true) {
+ if (VDBG) log("lastTD: " + IccUtils.byteToHex(lastTD));
+ // Parse the interface bytes.
+ if ((lastTD & INTERFACE_BYTES_MASK) == 0) {
+ break;
+ }
+
+ InterfaceByte interfaceByte = new InterfaceByte();
+ if (VDBG) log("lastTD & TA_MASK: " + IccUtils.byteToHex((byte) (lastTD & TA_MASK)));
+ if ((lastTD & TA_MASK) != 0) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the byte for TA.");
+ return -1;
+ }
+ interfaceByte.setTA(atrBytes[index]);
+ index++;
+ }
+ if (VDBG) log("lastTD & TB_MASK: " + IccUtils.byteToHex((byte) (lastTD & TB_MASK)));
+ if ((lastTD & TB_MASK) != 0) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the byte for TB.");
+ return -1;
+ }
+ interfaceByte.setTB(atrBytes[index]);
+ index++;
+ }
+ if (VDBG) log("lastTD & TC_MASK: " + IccUtils.byteToHex((byte) (lastTD & TC_MASK)));
+ if ((lastTD & TC_MASK) != 0) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the byte for TC.");
+ return -1;
+ }
+ interfaceByte.setTC(atrBytes[index]);
+ index++;
+ }
+ if (VDBG) log("lastTD & TD_MASK: " + IccUtils.byteToHex((byte) (lastTD & TD_MASK)));
+ if ((lastTD & TD_MASK) != 0) {
+ if (index >= atrBytes.length) {
+ loge("Failed to read the byte for TD.");
+ return -1;
+ }
+ interfaceByte.setTD(atrBytes[index]);
+ index++;
+ }
+ mInterfaceBytes.add(interfaceByte);
+ Byte newTD = interfaceByte.getTD();
+ if (VDBG) log("index=" + index + ", " + toString());
+ if (newTD == null) {
+ break;
+ }
+ lastTD = newTD;
+ // Parse the T values from all the TD, here we only check whether T is equal to any
+ // other values other than 0, since the check byte can be absent only when T is
+ // equal to 0.
+ if ((lastTD & T_MASK) != 0) {
+ mOnlyTEqualsZero = false;
+ }
+ }
+ return index;
+ }
+
+ private int parseHistoricalBytes(byte[] atrBytes, int index) {
+ if (mHistoricalBytes.length + index > atrBytes.length) {
+ loge("Failed to read the historical bytes.");
+ return -1;
+ }
+ if (mHistoricalBytes.length > 0) {
+ System.arraycopy(atrBytes, index, mHistoricalBytes, 0, mHistoricalBytes.length);
+ }
+ return index + mHistoricalBytes.length;
+ }
+
+ private int parseCheckBytes(byte[] atrBytes, int index) {
+ if (index < atrBytes.length) {
+ mCheckByte = atrBytes[index];
+ index++;
+ } else {
+ if (!mOnlyTEqualsZero) {
+ loge("Check byte must be present because T equals to values other than 0.");
+ return -1;
+ } else {
+ log("Check byte can be absent because T=0.");
+ }
+ }
+ return index;
+ }
+
+ private boolean parseAtrString(String atr) {
+ if (atr.length() % 2 != 0) {
+ loge("The length of input ATR string " + atr.length() + " is not even.");
+ return false;
+ }
+
+ if (atr.length() < 4) {
+ loge("Valid ATR string must at least contains TS and T0.");
+ return false;
+ }
+
+ byte[] atrBytes = IccUtils.hexStringToBytes(atr);
+ if (atrBytes == null) {
+ return false;
+ }
+
+ int index = parseConventionByte(atrBytes, 0);
+ if (index == -1) {
+ return false;
+ }
+
+ index = parseFormatByte(atrBytes, index);
+ if (index == -1) {
+ return false;
+ }
+
+ index = parseInterfaceBytes(atrBytes, index);
+ if (index == -1) {
+ return false;
+ }
+
+ index = parseHistoricalBytes(atrBytes, index);
+ if (index == -1) {
+ return false;
+ }
+
+ index = parseCheckBytes(atrBytes, index);
+ if (index == -1) {
+ return false;
+ }
+
+ if (index != atrBytes.length) {
+ loge("Unexpected bytes after the check byte.");
+ return false;
+ }
+ log("Successfully parsed the ATR string " + atr + " into " + toString());
+ checkIsEuiccSupported();
+ return true;
+ }
+
+ /**
+ * This class holds the interface bytes.
+ */
+ public static class InterfaceByte {
+ private Byte mTA;
+ private Byte mTB;
+ private Byte mTC;
+ private Byte mTD;
+
+ @Nullable
+ public Byte getTA() {
+ return mTA;
+ }
+
+ @Nullable
+ public Byte getTB() {
+ return mTB;
+ }
+
+ @Nullable
+ public Byte getTC() {
+ return mTC;
+ }
+
+ @Nullable
+ public Byte getTD() {
+ return mTD;
+ }
+
+ public void setTA(Byte tA) {
+ mTA = tA;
+ }
+
+ public void setTB(Byte tB) {
+ mTB = tB;
+ }
+
+ public void setTC(Byte tC) {
+ mTC = tC;
+ }
+
+ public void setTD(Byte tD) {
+ mTD = tD;
+ }
+
+ private InterfaceByte() {
+ mTA = null;
+ mTB = null;
+ mTC = null;
+ mTD = null;
+ }
+
+ @VisibleForTesting
+ public InterfaceByte(Byte tA, Byte tB, Byte tC, Byte tD) {
+ this.mTA = tA;
+ this.mTB = tB;
+ this.mTC = tC;
+ this.mTD = tD;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ InterfaceByte ib = (InterfaceByte) o;
+ return (Objects.equals(mTA, ib.getTA())
+ && Objects.equals(mTB, ib.getTB())
+ && Objects.equals(mTC, ib.getTC())
+ && Objects.equals(mTD, ib.getTD()));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTA, mTB, mTC, mTD);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("{");
+ sb.append("TA=").append(byteToStringHex(mTA)).append(",");
+ sb.append("TB=").append(byteToStringHex(mTB)).append(",");
+ sb.append("TC=").append(byteToStringHex(mTC)).append(",");
+ sb.append("TD=").append(byteToStringHex(mTD));
+ sb.append("}");
+ return sb.toString();
+ }
+ };
+
+ private static void log(String msg) {
+ Rlog.d(TAG, msg);
+ }
+
+ private static void loge(String msg) {
+ Rlog.e(TAG, msg);
+ }
+
+ public byte getConventionByte() {
+ return mIsDirectConvention ? DIRECT_CONVENTION : INVERSE_CONVENTION;
+ }
+
+ public byte getFormatByte() {
+ return mFormatByte;
+ }
+
+ public List<InterfaceByte> getInterfaceBytes() {
+ return mInterfaceBytes;
+ }
+
+ @Nullable
+ public byte[] getHistoricalBytes() {
+ return mHistoricalBytes;
+ }
+
+ @Nullable
+ public Byte getCheckByte() {
+ return mCheckByte;
+ }
+
+ public boolean isEuiccSupported() {
+ return mIsEuiccSupported;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("AnswerToReset:{");
+ sb.append("mConventionByte=")
+ .append(IccUtils.byteToHex(getConventionByte())).append(",");
+ sb.append("mFormatByte=").append(byteToStringHex(mFormatByte)).append(",");
+ sb.append("mInterfaceBytes={");
+ for (InterfaceByte ib : mInterfaceBytes) {
+ sb.append(ib.toString());
+ }
+ sb.append("},");
+ sb.append("mHistoricalBytes={");
+ for (byte b : mHistoricalBytes) {
+ sb.append(IccUtils.byteToHex(b)).append(",");
+ }
+ sb.append("},");
+ sb.append("mCheckByte=").append(byteToStringHex(mCheckByte));
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Dump
+ */
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("AnswerToReset:");
+ pw.println(toString());
+ pw.flush();
+ }
+}
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index f8efd30..55d5f25 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -167,8 +167,7 @@
}
}
- private int[] getAvailableServices(int regState, int domain,
- boolean emergencyOnly) {
+ private int[] getAvailableServices(int regState, int domain, boolean emergencyOnly) {
int[] availableServices = null;
// In emergency only states, only SERVICE_TYPE_EMERGENCY is available.
@@ -177,7 +176,7 @@
if (emergencyOnly) {
availableServices = new int[] {NetworkRegistrationState.SERVICE_TYPE_EMERGENCY};
} else if (regState == NetworkRegistrationState.REG_STATE_ROAMING
- || regState != NetworkRegistrationState.REG_STATE_HOME) {
+ || regState == NetworkRegistrationState.REG_STATE_HOME) {
if (domain == NetworkRegistrationState.DOMAIN_PS) {
availableServices = new int[] {NetworkRegistrationState.SERVICE_TYPE_DATA};
} else if (domain == NetworkRegistrationState.DOMAIN_CS) {
@@ -243,6 +242,10 @@
private CellIdentity convertHalCellIdentityToCellIdentity(
android.hardware.radio.V1_0.CellIdentity cellIdentity) {
+ if (cellIdentity == null) {
+ return null;
+ }
+
CellIdentity result = null;
switch(cellIdentity.cellInfoType) {
case CellInfoType.GSM: {
@@ -305,6 +308,7 @@
return result;
}
+ @Override
public void getNetworkRegistrationState(int domain, NetworkServiceCallback callback) {
if (DBG) log("getNetworkRegistrationState for domain " + domain);
Message message = null;
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 0c51dca..3e6391a 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -1957,11 +1957,6 @@
}
@Override
- public void getDataCallList(Message response) {
- mCi.getDataCallList(response);
- }
-
- @Override
public void updateServiceLocation() {
mSST.enableSingleLocationUpdate();
}
@@ -2294,8 +2289,14 @@
config_switch_phone_on_voice_reg_state_change)) {
mCi.getVoiceRadioTechnology(obtainMessage(EVENT_REQUEST_VOICE_RADIO_TECH_DONE));
}
- // Force update IMS service
- ImsManager.getInstance(mContext, mPhoneId).updateImsServiceConfig(true);
+ // Force update IMS service if it is available, if it isn't the config will be
+ // updated when ImsPhoneCallTracker opens a connection.
+ ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
+ if (imsManager.isServiceAvailable()) {
+ imsManager.updateImsServiceConfig(true);
+ } else {
+ logd("ImsManager is not available to update CarrierConfig.");
+ }
// Update broadcastEmergencyCallStateChanges
CarrierConfigManager configMgr = (CarrierConfigManager)
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index ac629f8..9059f2f 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -16,32 +16,25 @@
package com.android.internal.telephony;
-import android.app.Activity;
import android.os.RemoteException;
import android.os.Message;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.provider.Telephony.Sms;
-import android.content.Intent;
import android.telephony.Rlog;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.aidl.IImsSmsListener;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.ImsSmsImplBase;
+import android.telephony.ims.stub.ImsSmsImplBase.SendStatusResult;
+import android.provider.Telephony.Sms.Intents;
+import android.util.Pair;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
-import com.android.ims.ImsServiceProxy;
-import com.android.ims.internal.IImsSmsListener;
+import com.android.ims.MmTelFeatureConnection;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.util.SMSDispatcherUtil;
-import com.android.internal.telephony.gsm.SmsMessage;
-
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.feature.MmTelFeature;
-import android.telephony.ims.internal.stub.SmsImplBase;
-import android.telephony.ims.internal.stub.SmsImplBase.SendStatusResult;
-import android.telephony.ims.internal.stub.SmsImplBase.StatusReportResult;
-import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.provider.Telephony.Sms.Intents;
-import android.util.Pair;
import java.util.HashMap;
import java.util.Map;
@@ -51,6 +44,7 @@
/**
* Responsible for communications with {@link com.android.ims.ImsManager} to send/receive messages
* over IMS.
+ * @hide
*/
public class ImsSmsDispatcher extends SMSDispatcher {
// Initial condition for ims connection retry.
@@ -107,7 +101,7 @@
}
@Override
- public void onDeregistered(com.android.ims.ImsReasonInfo info) {
+ public void onDeregistered(ImsReasonInfo info) {
Rlog.d(TAG, "onImsDisconnected imsReasonInfo=" + info);
synchronized (mLock) {
mIsRegistered = false;
@@ -127,12 +121,12 @@
};
// Callback fires when ImsManager MMTel Feature changes state
- private ImsServiceProxy.IFeatureUpdate mNotifyStatusChangedCallback =
- new ImsServiceProxy.IFeatureUpdate() {
+ private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback =
+ new MmTelFeatureConnection.IFeatureUpdate() {
@Override
public void notifyStateChanged() {
try {
- int status = getImsManager().getImsServiceStatus();
+ int status = getImsManager().getImsServiceState();
Rlog.d(TAG, "Status Changed: " + status);
switch (status) {
case android.telephony.ims.feature.ImsFeature.STATE_READY: {
@@ -144,7 +138,7 @@
}
case android.telephony.ims.feature.ImsFeature.STATE_INITIALIZING:
// fall through
- case android.telephony.ims.feature.ImsFeature.STATE_NOT_AVAILABLE:
+ case ImsFeature.STATE_UNAVAILABLE:
synchronized (mLock) {
mIsImsServiceUp = false;
}
@@ -174,18 +168,18 @@
throw new IllegalArgumentException("Invalid token.");
}
switch(reason) {
- case SmsImplBase.SEND_STATUS_OK:
+ case ImsSmsImplBase.SEND_STATUS_OK:
tracker.onSent(mContext);
break;
- case SmsImplBase.SEND_STATUS_ERROR:
+ case ImsSmsImplBase.SEND_STATUS_ERROR:
tracker.onFailed(mContext, reason, 0 /* errorCode */);
mTrackers.remove(token);
break;
- case SmsImplBase.SEND_STATUS_ERROR_RETRY:
+ case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY:
tracker.mRetryCount += 1;
sendSms(tracker);
break;
- case SmsImplBase.SEND_STATUS_ERROR_FALLBACK:
+ case ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK:
fallbackToPstn(token, tracker);
break;
default:
@@ -208,8 +202,8 @@
getImsManager().acknowledgeSmsReport(
token,
messageRef,
- result.first ? SmsImplBase.STATUS_REPORT_STATUS_OK
- : SmsImplBase.STATUS_REPORT_STATUS_ERROR);
+ result.first ? ImsSmsImplBase.STATUS_REPORT_STATUS_OK
+ : ImsSmsImplBase.STATUS_REPORT_STATUS_ERROR);
} catch (ImsException e) {
Rlog.e(TAG, "Failed to acknowledgeSmsReport(). Error: "
+ e.getMessage());
@@ -229,8 +223,8 @@
getImsManager().acknowledgeSms(token,
0,
result == Intents.RESULT_SMS_HANDLED
- ? SmsImplBase.STATUS_REPORT_STATUS_OK
- : SmsImplBase.DELIVER_STATUS_ERROR);
+ ? ImsSmsImplBase.STATUS_REPORT_STATUS_OK
+ : ImsSmsImplBase.DELIVER_STATUS_ERROR);
} catch (ImsException e) {
Rlog.e(TAG, "Failed to acknowledgeSms(). Error: " + e.getMessage());
}
@@ -286,7 +280,7 @@
if (getImsManager().isServiceAvailable()) {
return;
}
- // remove callback so we do not receive updates from old ImsServiceProxy when switching
+ // remove callback so we do not receive updates from old MmTelFeatureConnection when switching
// between ImsServices.
getImsManager().removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback);
// Exponential backoff during retry, limited to 32 seconds.
diff --git a/src/java/com/android/internal/telephony/NetworkRegistrationManager.java b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
new file mode 100644
index 0000000..30210a8
--- /dev/null
+++ b/src/java/com/android/internal/telephony/NetworkRegistrationManager.java
@@ -0,0 +1,230 @@
+/*
+ * 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 android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.Registrant;
+import android.os.RegistrantList;
+import android.os.RemoteException;
+import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.CarrierConfigManager;
+import android.telephony.INetworkService;
+import android.telephony.INetworkServiceCallback;
+import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkService;
+import android.telephony.Rlog;
+
+/**
+ * Class that serves as the layer between NetworkService and ServiceStateTracker. It helps binding,
+ * sending request and registering for state change to NetworkService.
+ */
+public class NetworkRegistrationManager {
+ private static final String TAG = NetworkRegistrationManager.class.getSimpleName();
+
+ private final int mTransportType;
+
+ private final Phone mPhone;
+
+ private final CarrierConfigManager mCarrierConfigManager;
+
+ // Registrants who listens registration state change callback from this class.
+ private final RegistrantList mRegStateChangeRegistrants = new RegistrantList();
+
+ private INetworkService.Stub mServiceBinder;
+
+ private RegManagerDeathRecipient mDeathRecipient;
+
+ public NetworkRegistrationManager(int transportType, Phone phone) {
+ mTransportType = transportType;
+ mPhone = phone;
+ mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
+ Context.CARRIER_CONFIG_SERVICE);
+
+ bindService();
+ }
+
+ public boolean isServiceConnected() {
+ return (mServiceBinder != null) && (mServiceBinder.isBinderAlive());
+ }
+
+ public void unregisterForNetworkRegistrationStateChanged(Handler h) {
+ mRegStateChangeRegistrants.remove(h);
+ }
+
+ public void registerForNetworkRegistrationStateChanged(Handler h, int what, Object obj) {
+ logd("registerForNetworkRegistrationStateChanged");
+ Registrant r = new Registrant(h, what, obj);
+ mRegStateChangeRegistrants.addUnique(h, what, obj);
+ }
+
+ public void getNetworkRegistrationState(int domain, Message onCompleteMessage) {
+ if (onCompleteMessage == null) return;
+
+ logd("getNetworkRegistrationState domain " + domain);
+ if (!isServiceConnected()) {
+ onCompleteMessage.obj = new AsyncResult(onCompleteMessage.obj, null,
+ new IllegalStateException("Service not connected."));
+ onCompleteMessage.sendToTarget();
+ return;
+ }
+
+ try {
+ mServiceBinder.getNetworkRegistrationState(mPhone.getPhoneId(), domain,
+ new NetworkRegStateCallback(onCompleteMessage));
+ } catch (RemoteException e) {
+ Rlog.e(TAG, "getNetworkRegistrationState RemoteException " + e);
+ onCompleteMessage.obj = new AsyncResult(onCompleteMessage.obj, null, e);
+ onCompleteMessage.sendToTarget();
+ }
+ }
+
+ private class RegManagerDeathRecipient implements IBinder.DeathRecipient {
+
+ private final ComponentName mComponentName;
+
+ RegManagerDeathRecipient(ComponentName name) {
+ mComponentName = name;
+ }
+
+ @Override
+ public void binderDied() {
+ // TODO: try to restart the service.
+ logd("NetworkService(" + mComponentName + " transport type "
+ + mTransportType + ") died.");
+ }
+ }
+
+ private class NetworkServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mServiceBinder = (INetworkService.Stub) service;
+ mDeathRecipient = new RegManagerDeathRecipient(name);
+ try {
+ mServiceBinder.linkToDeath(mDeathRecipient, 0);
+ mServiceBinder.createNetworkServiceProvider(mPhone.getPhoneId());
+ mServiceBinder.registerForNetworkRegistrationStateChanged(mPhone.getPhoneId(),
+ new NetworkRegStateCallback(null));
+ } catch (RemoteException exception) {
+ // Remote exception means that the binder already died.
+ mDeathRecipient.binderDied();
+ logd("RemoteException " + exception);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ logd("onServiceDisconnected " + name);
+ if (mServiceBinder != null) {
+ mServiceBinder.unlinkToDeath(mDeathRecipient, 0);
+ }
+ }
+ }
+
+ private class NetworkRegStateCallback extends INetworkServiceCallback.Stub {
+ // Message only used upon onGetNetworkRegistrationStateComplete.
+ // If the callback is passed to listen to network state change,
+ // this message is null.
+ private final Message mOnCompleteMessage;
+
+ NetworkRegStateCallback(Message onCompleteMessage) {
+ mOnCompleteMessage = onCompleteMessage;
+ }
+
+ @Override
+ public void onGetNetworkRegistrationStateComplete(
+ int result, NetworkRegistrationState state) {
+ logd("onGetNetworkRegistrationStateComplete result "
+ + result + " state " + state);
+ mOnCompleteMessage.arg1 = result;
+ mOnCompleteMessage.obj = new AsyncResult(mOnCompleteMessage.obj, state, null);
+ mOnCompleteMessage.sendToTarget();
+ }
+
+ @Override
+ public void onNetworkStateChanged() {
+ logd("onNetworkStateChanged");
+ mRegStateChangeRegistrants.notifyRegistrants();
+ }
+ }
+
+ private boolean bindService() {
+ Intent intent = new Intent(NetworkService.NETWORK_SERVICE_INTERFACE);
+ intent.setPackage(getPackageName());
+ try {
+ // We bind this as a foreground service because it is operating directly on the SIM,
+ // and we do not want it subjected to power-savings restrictions while doing so.
+ return mPhone.getContext().bindService(intent, new NetworkServiceConnection(),
+ Context.BIND_AUTO_CREATE);
+ } catch (SecurityException e) {
+ loge("bindService failed " + e);
+ return false;
+ }
+ }
+
+ private String getPackageName() {
+ String packageName;
+ int resourceId;
+ String carrierConfig;
+
+ switch (mTransportType) {
+ case TransportType.WWAN:
+ resourceId = com.android.internal.R.string.config_wwan_network_service_package;
+ carrierConfig = CarrierConfigManager
+ .KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING;
+ break;
+ case TransportType.WLAN:
+ resourceId = com.android.internal.R.string.config_wlan_network_service_package;
+ carrierConfig = CarrierConfigManager
+ .KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING;
+ break;
+ default:
+ throw new IllegalStateException("Transport type not WWAN or WLAN. type="
+ + mTransportType);
+ }
+
+ // Read package name from resource overlay
+ packageName = mPhone.getContext().getResources().getString(resourceId);
+
+ PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
+
+ if (b != null) {
+ // If carrier config overrides it, use the one from carrier config
+ packageName = b.getString(carrierConfig, packageName);
+ }
+
+ logd("Binding to packageName " + packageName + " for transport type"
+ + mTransportType);
+
+ return packageName;
+ }
+
+ private static int logd(String msg) {
+ return Rlog.d(TAG, msg);
+ }
+
+ private static int loge(String msg) {
+ return Rlog.e(TAG, msg);
+ }
+}
diff --git a/src/java/com/android/internal/telephony/NitzStateMachine.java b/src/java/com/android/internal/telephony/NitzStateMachine.java
index 20e9802..1a365ee 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachine.java
@@ -19,7 +19,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.Rlog;
@@ -29,6 +28,8 @@
import android.util.TimeUtils;
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;
@@ -97,20 +98,6 @@
return ignoreNitz != null && ignoreNitz.equals("yes");
}
- /**
- * Returns the same value as {@link System#currentTimeMillis()}.
- */
- public long currentTimeMillis() {
- return System.currentTimeMillis();
- }
-
- /**
- * Returns the same value as {@link SystemClock#elapsedRealtime()}.
- */
- public long elapsedRealtime() {
- return SystemClock.elapsedRealtime();
- }
-
public String getNetworkCountryIsoForPhone() {
return mTelephonyManager.getNetworkCountryIsoForPhone(mPhone.getPhoneId());
}
@@ -131,13 +118,13 @@
// Time Zone detection state.
/**
- * Sometimes we get the NITZ time before we know what country we
- * are in. Keep the time zone information from the NITZ string in
- * mNitzData so we can fix the time zone once know the country.
+ * Sometimes we get the NITZ time before we know what country we are in. We keep the time zone
+ * information from the NITZ string in mLatestNitzSignal so we can fix the time zone once we
+ * know the country.
*/
private boolean mNeedCountryCodeForNitz = false;
- private NitzData mNitzData;
+ private TimeStampedValue<NitzData> mLatestNitzSignal;
private boolean mGotCountryCode = false;
private String mSavedTimeZoneId;
@@ -165,7 +152,7 @@
public NitzStateMachine(GsmCdmaPhone phone) {
this(phone,
- TelephonyComponentFactory.getInstance().makeTimeServiceHelper(phone.getContext()),
+ new TimeServiceHelper(phone.getContext()),
new DeviceState(phone),
new TimeZoneLookupHelper());
}
@@ -218,121 +205,147 @@
}
if (countryChanged || mNeedCountryCodeForNitz) {
- // Capture the time zone property. This allows us to tell whether the device has a time
- // zone set. TimeZone.getDefault() returns a default zone (GMT) even when time zone is
- // not explicitly set making the system property a better indicator of whether an
- // explicit time zone choice has been made.
+ // 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, "fixTimeZone"
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet:"
+ " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized
- + " mNitzData=" + mNitzData
- + " iso-cc='" + isoCountryCode
- + "' countryUsesUtc="
- + mTimeZoneLookupHelper.countryUsesUtc(isoCountryCode));
+ + " mLatestNitzSignal=" + mLatestNitzSignal
+ + " isoCountryCode=" + isoCountryCode);
}
String zoneId;
if (TextUtils.isEmpty(isoCountryCode) && mNeedCountryCodeForNitz) {
// Country code not found. This is likely a test network.
// Get a TimeZone based only on the NITZ parameters (best guess).
- // mNeedCountryCodeForNitz is only set to true when mNitzData is set so there's no
- // need to check mNitzData == null.
- zoneId = mTimeZoneLookupHelper.guessZoneIdByNitz(mNitzData);
+ // mNeedCountryCodeForNitz is only set to true when mLatestNitzSignal is set so
+ // there's no need to check mLatestNitzSignal == null.
+ OffsetResult lookupResult =
+ mTimeZoneLookupHelper.lookupByNitz(mLatestNitzSignal.mValue);
if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone(): guessNitzTimeZone returned " + zoneId);
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: guessZoneIdByNitz() returned"
+ + " lookupResult=" + lookupResult);
}
- } else if ((mNitzData == null || nitzOffsetMightBeBogus(mNitzData))
- && isTimeZoneSettingInitialized
- && !mTimeZoneLookupHelper.countryUsesUtc(isoCountryCode)) {
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
+ } else if (mLatestNitzSignal == null) {
+ zoneId = null;
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: No cached NITZ data available,"
+ + " not setting zone");
+ }
+ } else { // mLatestNitzSignal != null
+ if (nitzOffsetMightBeBogus(mLatestNitzSignal.mValue)
+ && isTimeZoneSettingInitialized
+ && !countryUsesUtc(isoCountryCode, mLatestNitzSignal)) {
- // This case means that (1) the device received no NITZ signal yet or received an
- // NITZ signal that looks bogus due to having a zero offset from UTC, (2) the device
- // has a time zone set explicitly, and (3) the iso tells us the country is NOT one
- // that uses a zero offset. This is interpreted as being NITZ incorrectly reporting
- // a local time and not a UTC time. The zone is left as the current device's zone
- // setting, and the time may be adjusted by assuming the current zone setting is
- // correct.
- TimeZone zone = TimeZone.getDefault();
- zoneId = zone.getID();
+ // This case means that (1) the device received an NITZ signal that could be
+ // bogus due to having a zero offset from UTC, (2) the device has had a time
+ // zone set explicitly and (3) the iso tells us the country is NOT one that uses
+ // a zero offset. This is interpreted as being NITZ incorrectly reporting a
+ // local time and not a UTC time. The zone is left as the current device's zone
+ // setting, and the system clock may be adjusted by taking the NITZ time and
+ // assuming the current zone setting is correct.
- // Note that mNeedCountryCodeForNitz => (implies) { mNitzData != null }. Therefore,
- // if mNitzData == null, mNeedCountryCodeForNitz cannot be true. The code in this
- // section therefore means that when mNitzData == null (and the country is one that
- // doesn't use a zero UTC offset) the device will retain the existing time zone
- // setting and not try to derive one from the isoCountryCode.
- if (mNeedCountryCodeForNitz) {
- try {
- // Acquire the wakelock as we're reading the system clock here.
- mWakeLock.acquire();
-
- long ctm = mDeviceState.currentTimeMillis();
- long tzOffset = zone.getOffset(ctm);
- if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone: tzOffset=" + tzOffset
- + " ltod=" + TimeUtils.logTimeOfDay(ctm));
- }
- if (mTimeServiceHelper.isTimeDetectionEnabled()) {
- long adj = ctm - tzOffset;
- String msg = "fixTimeZone: adj ltod=" + TimeUtils.logTimeOfDay(adj);
- setAndBroadcastNetworkSetTime(msg, adj);
- } else {
- // Adjust the saved NITZ time to account for tzOffset.
- mSavedNitzTime = new TimeStampedValue<>(
- mSavedNitzTime.mValue - tzOffset,
- mSavedNitzTime.mElapsedRealtime);
- if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone: adj mSavedTime=" + mSavedNitzTime);
- }
- }
- } finally {
- mWakeLock.release();
+ TimeZone zone = TimeZone.getDefault();
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: NITZ looks bogus, maybe using"
+ + " current default zone to adjust the system clock,"
+ + " mNeedCountryCodeForNitz=" + mNeedCountryCodeForNitz
+ + " mLatestNitzSignal=" + mLatestNitzSignal
+ + " zone=" + zone);
}
- }
- if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone: using default TimeZone");
- }
- } else if (mNitzData == null) {
- // The use of 1/1/1970 UTC is unusual but consistent with historical behavior when
- // it wasn't possible to detect whether a previous NITZ signal had been saved.
- zoneId = mTimeZoneLookupHelper.guessZoneIdByInstantOffsetDstCountry(
- 0 /* when */, 0 /* offset */, false /* dst */, isoCountryCode);
- if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone: No cached NITZ data available, using only country"
- + " code. zoneId=" + zoneId);
- }
- } else {
- zoneId = mTimeZoneLookupHelper.guessZoneIdByNitzCountry(mNitzData, isoCountryCode);
- if (DBG) {
- Rlog.d(LOG_TAG, "fixTimeZone: using getTimeZone(off, dst, time, iso)");
+ zoneId = zone.getID();
+
+ if (mNeedCountryCodeForNitz) {
+ NitzData nitzData = mLatestNitzSignal.mValue;
+ try {
+ // Acquire the wakelock as we're reading the elapsed realtime clock
+ // here.
+ mWakeLock.acquire();
+
+ // Use the time that came with the NITZ offset that we think is bogus:
+ // we just interpret it as local time.
+ long ctm = nitzData.getCurrentTimeInMillis();
+ long delayAdjustedCtm = ctm + (mTimeServiceHelper.elapsedRealtime()
+ - mLatestNitzSignal.mElapsedRealtime);
+ long tzOffset = zone.getOffset(delayAdjustedCtm);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet:"
+ + " tzOffset=" + tzOffset
+ + " delayAdjustedCtm="
+ + TimeUtils.logTimeOfDay(delayAdjustedCtm));
+ }
+ if (mTimeServiceHelper.isTimeDetectionEnabled()) {
+ long timeZoneAdjustedCtm = delayAdjustedCtm - tzOffset;
+ String msg = "handleNetworkCountryCodeSet: setting time"
+ + " timeZoneAdjustedCtm="
+ + TimeUtils.logTimeOfDay(timeZoneAdjustedCtm);
+ setAndBroadcastNetworkSetTime(msg, timeZoneAdjustedCtm);
+ } else {
+ // Adjust the saved NITZ time to account for tzOffset.
+ mSavedNitzTime = new TimeStampedValue<>(
+ mSavedNitzTime.mValue - tzOffset,
+ mSavedNitzTime.mElapsedRealtime);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet:"
+ + "adjusting time mSavedNitzTime=" + mSavedNitzTime);
+ }
+ }
+ } finally {
+ mWakeLock.release();
+ }
+ }
+ } else {
+ NitzData nitzData = mLatestNitzSignal.mValue;
+ OffsetResult lookupResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, isoCountryCode);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: using"
+ + " guessZoneIdByNitzCountry(nitzData, isoCountryCode),"
+ + " nitzData=" + nitzData
+ + " isoCountryCode=" + isoCountryCode
+ + " lookupResult=" + lookupResult);
+ }
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
}
}
- final String tmpLog = "fixTimeZone:"
+ final String tmpLog = "handleNetworkCountryCodeSet:"
+ " isTimeZoneSettingInitialized=" + isTimeZoneSettingInitialized
- + " mNitzData=" + mNitzData
- + " iso-cc=" + isoCountryCode
+ + " mLatestNitzSignal=" + mLatestNitzSignal
+ + " isoCountryCode=" + isoCountryCode
+ " mNeedCountryCodeForNitz=" + mNeedCountryCodeForNitz
+ " zoneId=" + zoneId;
mTimeZoneLog.log(tmpLog);
if (zoneId != null) {
- Rlog.d(LOG_TAG, "fixTimeZone: zone != null zoneId=" + zoneId);
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: zoneId != null, zoneId=" + zoneId);
if (mTimeServiceHelper.isTimeZoneDetectionEnabled()) {
setAndBroadcastNetworkSetTimeZone(zoneId);
} else {
- Rlog.d(LOG_TAG, "fixTimeZone: skip changing zone as getAutoTimeZone was false");
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: skip changing zone as"
+ + " isTimeZoneDetectionEnabled() is false");
}
if (mNeedCountryCodeForNitz) {
- saveNitzTimeZone(zoneId);
+ mSavedTimeZoneId = zoneId;
}
} else {
- Rlog.d(LOG_TAG, "fixTimeZone: zone == null, do nothing for zone");
+ Rlog.d(LOG_TAG, "handleNetworkCountryCodeSet: lookupResult == null, do nothing");
}
mNeedCountryCodeForNitz = false;
}
}
+ private boolean countryUsesUtc(
+ String isoCountryCode, TimeStampedValue<NitzData> nitzSignal) {
+ return mTimeZoneLookupHelper.countryUsesUtc(
+ isoCountryCode,
+ nitzSignal.mValue.getCurrentTimeInMillis());
+ }
+
/**
* Informs the {@link NitzStateMachine} that the network has become available.
*/
@@ -384,41 +397,34 @@
if (!mGotCountryCode) {
zoneId = null;
} else if (!TextUtils.isEmpty(iso)) {
- zoneId = mTimeZoneLookupHelper.guessZoneIdByNitzCountry(newNitzData, iso);
+ OffsetResult lookupResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(newNitzData, iso);
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
} else {
// We don't have a valid iso country code. This is
// most likely because we're on a test network that's
// using a bogus MCC (eg, "001"), so get a TimeZone
// based only on the NITZ parameters.
- zoneId = mTimeZoneLookupHelper.guessZoneIdByNitz(newNitzData);
+ OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitz(newNitzData);
if (DBG) {
- Rlog.d(LOG_TAG, "setTimeZoneFromNitz(): findByNitz returned " + zoneId);
+ Rlog.d(LOG_TAG, "handleTimeZoneFromNitz: guessZoneIdByNitz returned"
+ + " lookupResult=" + lookupResult);
}
+ zoneId = lookupResult != null ? lookupResult.zoneId : null;
}
}
- int previousUtcOffset;
- boolean previousIsDst;
- if (mNitzData == null) {
- // No previously saved NITZ data. Use the same defaults as Android would have done
- // before it was possible to detect this case.
- previousUtcOffset = 0;
- previousIsDst = false;
- } else {
- previousUtcOffset = mNitzData.getLocalOffsetMillis();
- previousIsDst = mNitzData.isDst();
- }
if ((zoneId == null)
- || (newNitzData.getLocalOffsetMillis() != previousUtcOffset)
- || (newNitzData.isDst() != previousIsDst)) {
- // We got the time before the country or the zone has changed
+ || mLatestNitzSignal == null
+ || offsetInfoDiffers(newNitzData, mLatestNitzSignal.mValue)) {
+ // We got the time before the country, or the zone has changed
// so we don't know how to identify the DST rules yet. Save
// the information and hope to fix it up later.
mNeedCountryCodeForNitz = true;
- mNitzData = newNitzData;
+ mLatestNitzSignal = nitzSignal;
}
- String tmpLog = "NITZ: nitzTimeSignal=" + nitzSignal
+ String tmpLog = "handleTimeZoneFromNitz: nitzSignal=" + nitzSignal
+ " zoneId=" + zoneId
+ " iso=" + iso + " mGotCountryCode=" + mGotCountryCode
+ " mNeedCountryCodeForNitz=" + mNeedCountryCodeForNitz
@@ -434,19 +440,26 @@
setAndBroadcastNetworkSetTimeZone(zoneId);
}
mNitzTimeZoneDetectionSuccessful = true;
- saveNitzTimeZone(zoneId);
+ mSavedTimeZoneId = zoneId;
}
} catch (RuntimeException ex) {
- Rlog.e(LOG_TAG, "NITZ: Processing NITZ data " + nitzSignal + " ex=" + ex);
+ Rlog.e(LOG_TAG, "handleTimeZoneFromNitz: Processing NITZ data"
+ + " nitzSignal=" + nitzSignal
+ + " ex=" + ex);
}
}
- private void handleTimeFromNitz(TimeStampedValue<NitzData> nitzTimeSignal) {
+ private static boolean offsetInfoDiffers(NitzData one, NitzData two) {
+ return one.getLocalOffsetMillis() != two.getLocalOffsetMillis()
+ || one.isDst() != two.isDst();
+ }
+
+ private void handleTimeFromNitz(TimeStampedValue<NitzData> nitzSignal) {
try {
boolean ignoreNitz = mDeviceState.getIgnoreNitz();
if (ignoreNitz) {
Rlog.d(LOG_TAG,
- "setTimeFromNitz: Not setting clock because gsm.ignore-nitz is set");
+ "handleTimeFromNitz: Not setting clock because gsm.ignore-nitz is set");
return;
}
@@ -456,25 +469,25 @@
mWakeLock.acquire();
// Validate the nitzTimeSignal to reject obviously bogus elapsedRealtime values.
- long elapsedRealtime = mDeviceState.elapsedRealtime();
- long millisSinceNitzReceived = elapsedRealtime - nitzTimeSignal.mElapsedRealtime;
+ long elapsedRealtime = mTimeServiceHelper.elapsedRealtime();
+ long millisSinceNitzReceived = elapsedRealtime - nitzSignal.mElapsedRealtime;
if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
if (DBG) {
- Rlog.d(LOG_TAG, "setTimeFromNitz: not setting time, unexpected"
+ Rlog.d(LOG_TAG, "handleTimeFromNitz: not setting time, unexpected"
+ " elapsedRealtime=" + elapsedRealtime
- + " nitzTimeSignal=" + nitzTimeSignal);
+ + " nitzSignal=" + nitzSignal);
}
return;
}
// Adjust the NITZ time by the delay since it was received to get the time now.
long adjustedCurrentTimeMillis =
- nitzTimeSignal.mValue.getCurrentTimeInMillis() + millisSinceNitzReceived;
- long gained = adjustedCurrentTimeMillis - mDeviceState.currentTimeMillis();
+ nitzSignal.mValue.getCurrentTimeInMillis() + millisSinceNitzReceived;
+ long gained = adjustedCurrentTimeMillis - mTimeServiceHelper.currentTimeMillis();
if (mTimeServiceHelper.isTimeDetectionEnabled()) {
- String logMsg = "(setTimeFromNitz)"
- + " nitzTimeSignal=" + nitzTimeSignal
+ String logMsg = "handleTimeFromNitz:"
+ + " nitzSignal=" + nitzSignal
+ " adjustedCurrentTimeMillis=" + adjustedCurrentTimeMillis
+ " millisSinceNitzReceived= " + millisSinceNitzReceived
+ " gained=" + gained;
@@ -483,8 +496,8 @@
logMsg += ": First update received.";
setAndBroadcastNetworkSetTime(logMsg, adjustedCurrentTimeMillis);
} else {
- long elapsedRealtimeSinceLastSaved =
- mDeviceState.elapsedRealtime() - mSavedNitzTime.mElapsedRealtime;
+ long elapsedRealtimeSinceLastSaved = mTimeServiceHelper.elapsedRealtime()
+ - mSavedNitzTime.mElapsedRealtime;
int nitzUpdateSpacing = mDeviceState.getNitzUpdateSpacingMillis();
int nitzUpdateDiff = mDeviceState.getNitzUpdateDiffMillis();
if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing
@@ -512,38 +525,36 @@
// Save the last NITZ time signal used so we can return to it later
// if auto-time detection is toggled.
mSavedNitzTime = new TimeStampedValue<>(
- adjustedCurrentTimeMillis, nitzTimeSignal.mElapsedRealtime);
+ adjustedCurrentTimeMillis, nitzSignal.mElapsedRealtime);
} finally {
mWakeLock.release();
}
} catch (RuntimeException ex) {
- Rlog.e(LOG_TAG, "setTimeFromNitz: Processing NITZ data " + nitzTimeSignal
+ Rlog.e(LOG_TAG, "handleTimeFromNitz: Processing NITZ data"
+ + " nitzSignal=" + nitzSignal
+ " ex=" + ex);
}
}
- private void saveNitzTimeZone(String zoneId) {
- mSavedTimeZoneId = zoneId;
- }
-
private void setAndBroadcastNetworkSetTimeZone(String zoneId) {
if (DBG) {
- Rlog.d(LOG_TAG, "setAndBroadcastNetworkSetTimeZone: setTimeZone=" + zoneId);
+ Rlog.d(LOG_TAG, "setAndBroadcastNetworkSetTimeZone: zoneId=" + zoneId);
}
mTimeServiceHelper.setDeviceTimeZone(zoneId);
if (DBG) {
Rlog.d(LOG_TAG,
- "setAndBroadcastNetworkSetTimeZone: call alarm.setTimeZone and broadcast"
+ "setAndBroadcastNetworkSetTimeZone: called setDeviceTimeZone()"
+ " zoneId=" + zoneId);
}
}
private void setAndBroadcastNetworkSetTime(String msg, long time) {
if (!mWakeLock.isHeld()) {
- Rlog.w(LOG_TAG, "Wake lock not held while setting device time (msg=" + msg + ")");
+ Rlog.w(LOG_TAG, "setAndBroadcastNetworkSetTime: Wake lock not held while setting device"
+ + " time (msg=" + msg + ")");
}
- msg = "setAndBroadcastNetworkSetTime: [setting time to time=" + time + "]:" + msg;
+ msg = "setAndBroadcastNetworkSetTime: [Setting time to time=" + time + "]:" + msg;
if (DBG) {
Rlog.d(LOG_TAG, msg);
}
@@ -554,15 +565,17 @@
private void handleAutoTimeEnabled() {
if (DBG) {
- Rlog.d(LOG_TAG, "Reverting to NITZ Time: mSavedTime=" + mSavedNitzTime);
+ Rlog.d(LOG_TAG, "handleAutoTimeEnabled: Reverting to NITZ Time:"
+ + " mSavedNitzTime=" + mSavedNitzTime);
}
if (mSavedNitzTime != null) {
try {
// Acquire the wakelock as we're reading the elapsed realtime clock here.
mWakeLock.acquire();
- long elapsedRealtime = mDeviceState.elapsedRealtime();
- String msg = "Reverting to NITZ time, elapsedRealtime=" + elapsedRealtime
+ long elapsedRealtime = mTimeServiceHelper.elapsedRealtime();
+ String msg = "mSavedNitzTime: Reverting to NITZ time"
+ + " elapsedRealtime=" + elapsedRealtime
+ " mSavedNitzTime=" + mSavedNitzTime;
long adjustedCurrentTimeMillis =
mSavedNitzTime.mValue + (elapsedRealtime - mSavedNitzTime.mElapsedRealtime);
@@ -574,7 +587,8 @@
}
private void handleAutoTimeZoneEnabled() {
- String tmpLog = "Reverting to NITZ TimeZone: tz=" + mSavedTimeZoneId;
+ String tmpLog = "handleAutoTimeZoneEnabled: Reverting to NITZ TimeZone:"
+ + " mSavedTimeZoneId=" + mSavedTimeZoneId;
if (DBG) {
Rlog.d(LOG_TAG, tmpLog);
}
@@ -598,9 +612,9 @@
// Time Zone Detection State
pw.println(" mNeedCountryCodeForNitz=" + mNeedCountryCodeForNitz);
- pw.println(" mNitzData=" + mNitzData);
+ pw.println(" mLatestNitzSignal=" + mLatestNitzSignal);
pw.println(" mGotCountryCode=" + mGotCountryCode);
- pw.println(" mSavedTimeZone=" + mSavedTimeZoneId);
+ pw.println(" mSavedTimeZoneId=" + mSavedTimeZoneId);
pw.println(" mNitzTimeZoneDetectionSuccessful=" + mNitzTimeZoneDetectionSuccessful);
// Miscellaneous
@@ -630,22 +644,22 @@
* @param iso Country code from network MCC
*/
private void updateTimeZoneByNetworkCountryCode(String iso) {
- String zoneId = mTimeZoneLookupHelper.guessZoneIdByCountry(
- iso, mDeviceState.currentTimeMillis());
- if (zoneId != null) {
+ CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry(
+ iso, mTimeServiceHelper.currentTimeMillis());
+ if (lookupResult != null && lookupResult.allZonesHaveSameOffset) {
+ String logMsg = "updateTimeZoneByNetworkCountryCode: set time"
+ + " lookupResult=" + lookupResult
+ + " iso=" + iso;
if (DBG) {
- Rlog.d(LOG_TAG, "updateTimeZoneByNetworkCountryCode: set time zone=" + zoneId
- + " iso=" + iso);
+ Rlog.d(LOG_TAG, logMsg);
}
-
- mTimeZoneLog.log("updateTimeZoneByNetworkCountryCode: set time zone=" + zoneId
- + " iso=" + iso);
- setAndBroadcastNetworkSetTimeZone(zoneId);
+ mTimeZoneLog.log(logMsg);
+ setAndBroadcastNetworkSetTimeZone(lookupResult.zoneId);
} else {
if (DBG) {
- Rlog.d(LOG_TAG,
- "updateTimeZoneByNetworkCountryCode: no good zone for iso-cc='" + iso
- + "', do nothing");
+ Rlog.d(LOG_TAG, "updateTimeZoneByNetworkCountryCode: no good zone for"
+ + " iso=" + iso
+ + " lookupResult=" + lookupResult);
}
}
}
@@ -661,7 +675,7 @@
* Returns the last NITZ data that was cached.
*/
public NitzData getCachedNitzData() {
- return mNitzData;
+ return mLatestNitzSignal != null ? mLatestNitzSignal.mValue : null;
}
/**
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 7e8621a..662f8e1 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -125,10 +125,6 @@
} else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
mImsServiceReady = false;
updateImsPhone();
- } else if (intent.getAction().equals(ImsConfig.ACTION_IMS_CONFIG_CHANGED)) {
- int item = intent.getIntExtra(ImsConfig.EXTRA_CHANGED_ITEM, -1);
- String value = intent.getStringExtra(ImsConfig.EXTRA_NEW_VALUE);
- ImsManager.onProvisionedValueChanged(context, item, value);
}
}
}
@@ -562,7 +558,6 @@
filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
}
- filter.addAction(ImsConfig.ACTION_IMS_CONFIG_CHANGED);
mContext.registerReceiver(mImsIntentReceiver, filter);
// Monitor IMS service - but first poll to see if already up (could miss
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index c857740..5b6dffb 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -150,11 +150,17 @@
where as in single SIM mode only instance. isMultiSimEnabled() function checks
whether it is single SIM or multi SIM mode */
int numPhones = TelephonyManager.getDefault().getPhoneCount();
- // Start ImsResolver and bind to ImsServices.
+ // Return whether or not the device should use dynamic binding or the static
+ // implementation (deprecated)
+ boolean isDynamicBinding = sContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_dynamic_bind_ims);
+ // Get the package name of the default IMS implementation.
String defaultImsPackage = sContext.getResources().getString(
com.android.internal.R.string.config_ims_package);
+ // Start ImsResolver and bind to ImsServices.
Rlog.i(LOG_TAG, "ImsResolver: defaultImsPackage: " + defaultImsPackage);
- sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones);
+ sImsResolver = new ImsResolver(sContext, defaultImsPackage, numPhones,
+ isDynamicBinding);
sImsResolver.populateCacheAndStartBind();
int[] networkModes = new int[numPhones];
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index c64c090..af393f8 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -736,19 +736,6 @@
boolean getMute();
/**
- * Get the current active Data Call list
- *
- * @param response <strong>On success</strong>, "response" bytes is
- * made available as:
- * (String[])(((AsyncResult)response.obj).result).
- * <strong>On failure</strong>,
- * (((AsyncResult)response.obj).result) == null and
- * (((AsyncResult)response.obj).exception) being an instance of
- * com.android.internal.telephony.gsm.CommandException
- */
- void getDataCallList(Message response);
-
- /**
* Update the ServiceState CellLocation for current network registration.
*/
void updateServiceLocation();
diff --git a/src/java/com/android/internal/telephony/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
index cd28b2b..1c6e023 100644
--- a/src/java/com/android/internal/telephony/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -124,8 +124,7 @@
mCommandsInterfaces = cis;
try {
- tr.addOnSubscriptionsChangedListener(context.getOpPackageName(),
- mSubscriptionsChangedListener);
+ tr.addOnSubscriptionsChangedListener("PhoneSwitcher", mSubscriptionsChangedListener);
} catch (RemoteException e) {
}
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index ce4743f..a190cde 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -48,15 +48,12 @@
import android.hardware.radio.V1_0.RadioResponseType;
import android.hardware.radio.V1_0.ResetNvType;
import android.hardware.radio.V1_0.SelectUiccSub;
-import android.hardware.radio.V1_0.SetupDataCallResult;
import android.hardware.radio.V1_0.SimApdu;
import android.hardware.radio.V1_0.SmsWriteArgs;
import android.hardware.radio.V1_0.UusInfo;
import android.net.ConnectivityManager;
import android.net.KeepalivePacketData;
-import android.net.LinkAddress;
import android.net.LinkProperties;
-import android.net.NetworkUtils;
import android.os.AsyncResult;
import android.os.Build;
import android.os.Handler;
@@ -87,7 +84,6 @@
import android.telephony.SmsManager;
import android.telephony.TelephonyHistogram;
import android.telephony.TelephonyManager;
-import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.text.TextUtils;
@@ -288,10 +284,6 @@
" mRadioProxyCookie = " + mRadioProxyCookie.get());
if ((long) msg.obj == mRadioProxyCookie.get()) {
resetProxyAndRequestList();
-
- // todo: rild should be back up since message was sent with a delay. this is
- // a hack.
- getRadioProxy(null);
}
break;
}
@@ -326,11 +318,7 @@
public void serviceDied(long cookie) {
// Deal with service going away
riljLog("serviceDied");
- // todo: temp hack to send delayed message so that rild is back up by then
- //mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
- mRilHandler.sendMessageDelayed(
- mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie),
- IRADIO_GET_SERVICE_DELAY_MILLIS);
+ mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
}
}
@@ -346,9 +334,7 @@
// Clear request list on close
clearRequestList(RADIO_NOT_AVAILABLE, false);
- // todo: need to get service right away so setResponseFunctions() can be called for
- // unsolicited indications. getService() is not a blocking call, so it doesn't help to call
- // it here. Current hack is to call getService() on death notification after a delay.
+ getRadioProxy(null);
}
/** Returns a {@link IRadio} instance or null if the service is not available. */
@@ -369,7 +355,8 @@
}
try {
- mRadioProxy = IRadio.getService(HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId]);
+ mRadioProxy = IRadio.getService(HIDL_SERVICE_NAME[mPhoneId == null ? 0 : mPhoneId],
+ true);
if (mRadioProxy != null) {
mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
mRadioProxyCookie.incrementAndGet());
@@ -383,17 +370,13 @@
}
if (mRadioProxy == null) {
+ // getService() is a blocking call, so this should never happen
+ riljLoge("getRadioProxy: mRadioProxy == null");
if (result != null) {
AsyncResult.forMessage(result, null,
CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
result.sendToTarget();
}
-
- // if service is not up, treat it like death notification to try to get service again
- mRilHandler.sendMessageDelayed(
- mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD,
- mRadioProxyCookie.incrementAndGet()),
- IRADIO_GET_SERVICE_DELAY_MILLIS);
}
return mRadioProxy;
@@ -478,13 +461,6 @@
private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) {
riljLoge(caller + ": " + e);
resetProxyAndRequestList();
-
- // service most likely died, handle exception like death notification to try to get service
- // again
- mRilHandler.sendMessageDelayed(
- mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD,
- mRadioProxyCookie.incrementAndGet()),
- IRADIO_GET_SERVICE_DELAY_MILLIS);
}
private String convertNullToEmptyString(String string) {
@@ -1136,103 +1112,13 @@
return -1;
}
- /**
- * Convert SetupDataCallResult defined in types.hal into DataCallResponse
- * @param dcResult setup data call result
- * @return converted DataCallResponse object
- */
- static DataCallResponse convertDataCallResult(SetupDataCallResult dcResult) {
-
- // Process address
- String[] addresses = null;
- if (!TextUtils.isEmpty(dcResult.addresses)) {
- addresses = dcResult.addresses.split("\\s+");
- }
-
- List<LinkAddress> laList = new ArrayList<>();
- if (addresses != null) {
- for (String address : addresses) {
- address = address.trim();
- if (address.isEmpty()) continue;
-
- try {
- LinkAddress la;
- // Check if the address contains prefix length. If yes, LinkAddress
- // can parse that.
- if (address.split("/").length == 2) {
- la = new LinkAddress(address);
- } else {
- InetAddress ia = NetworkUtils.numericToInetAddress(address);
- la = new LinkAddress(ia, (ia instanceof Inet4Address) ? 32 : 128);
- }
-
- laList.add(la);
- } catch (IllegalArgumentException e) {
- Rlog.e(RILJ_LOG_TAG, "Unknown address: " + address + ", " + e);
- }
- }
- }
-
- // Process dns
- String[] dnses = null;
- if (!TextUtils.isEmpty(dcResult.dnses)) {
- dnses = dcResult.dnses.split("\\s+");
- }
-
- List<InetAddress> dnsList = new ArrayList<>();
- if (dnses != null) {
- for (String dns : dnses) {
- dns = dns.trim();
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(dns);
- dnsList.add(ia);
- } catch (IllegalArgumentException e) {
- Rlog.e(RILJ_LOG_TAG, "Unknown dns: " + dns + ", exception = " + e);
- }
- }
- }
-
- // Process gateway
- String[] gateways = null;
- if (!TextUtils.isEmpty(dcResult.gateways)) {
- gateways = dcResult.gateways.split("\\s+");
- }
-
- List<InetAddress> gatewayList = new ArrayList<>();
- if (gateways != null) {
- for (String gateway : gateways) {
- gateway = gateway.trim();
- InetAddress ia;
- try {
- ia = NetworkUtils.numericToInetAddress(gateway);
- gatewayList.add(ia);
- } catch (IllegalArgumentException e) {
- Rlog.e(RILJ_LOG_TAG, "Unknown gateway: " + gateway + ", exception = " + e);
- }
- }
- }
-
- return new DataCallResponse(dcResult.status,
- dcResult.suggestedRetryTime,
- dcResult.cid,
- dcResult.active,
- dcResult.type,
- dcResult.ifname,
- laList,
- dnsList,
- gatewayList,
- new ArrayList<>(Arrays.asList(dcResult.pcscf.trim().split("\\s+"))),
- dcResult.mtu
- );
- }
-
@Override
public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
boolean allowRoaming, int reason, LinkProperties linkProperties,
Message result) {
IRadio radioProxy = getRadioProxy(result);
+
if (radioProxy != null) {
RILRequest rr = obtainRequest(RIL_REQUEST_SETUP_DATA_CALL, result,
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index 914acd6..02c7177 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -166,7 +166,7 @@
}
try {
- mRadioConfigProxy = IRadioConfig.getService(RADIO_CONFIG_SERVICE_NAME);
+ mRadioConfigProxy = IRadioConfig.getService(RADIO_CONFIG_SERVICE_NAME, true);
if (mRadioConfigProxy != null) {
mRadioConfigProxy.linkToDeath(mServiceDeathRecipient,
mRadioConfigProxyCookie.incrementAndGet());
@@ -177,7 +177,7 @@
}
} catch (RemoteException | RuntimeException e) {
mRadioConfigProxy = null;
- loge("getRadioConfigProxy: RadioProxy getService/setResponseFunctions: " + e);
+ loge("getRadioConfigProxy: RadioConfigProxy getService/setResponseFunctions: " + e);
}
if (mRadioConfigProxy == null) {
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index 8d77982..d2ad279 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -89,7 +89,6 @@
import android.telephony.PcoData;
import android.telephony.SignalStrength;
import android.telephony.SmsMessage;
-import android.telephony.data.DataCallResponse;
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaInformationRecords;
@@ -254,16 +253,10 @@
public void dataCallListChanged(int indicationType, ArrayList<SetupDataCallResult> dcList) {
mRil.processIndication(indicationType);
- ArrayList<DataCallResponse> response = new ArrayList<>();
-
- for (SetupDataCallResult dcResult : dcList) {
- response.add(RIL.convertDataCallResult(dcResult));
- }
-
- if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, response);
+ if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, dcList);
mRil.mDataCallListChangedRegistrants.notifyRegistrants(
- new AsyncResult(null, response, null));
+ new AsyncResult(null, dcList, null));
}
public void suppSvcNotify(int indicationType, SuppSvcNotification suppSvcNotification) {
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index b636917..d608bda 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -45,7 +45,6 @@
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.telephony.data.DataCallResponse;
import android.text.TextUtils;
import com.android.internal.telephony.dataconnection.KeepaliveStatus;
@@ -1672,11 +1671,10 @@
RILRequest rr = mRil.processResponse(responseInfo);
if (rr != null) {
- DataCallResponse ret = RIL.convertDataCallResult(setupDataCallResult);
if (responseInfo.error == RadioError.NONE) {
- sendMessageResponse(rr.mResult, ret);
+ sendMessageResponse(rr.mResult, setupDataCallResult);
}
- mRil.processResponseDone(rr, responseInfo, ret);
+ mRil.processResponseDone(rr, responseInfo, setupDataCallResult);
}
}
@@ -1767,14 +1765,10 @@
RILRequest rr = mRil.processResponse(responseInfo);
if (rr != null) {
- ArrayList<DataCallResponse> dcResponseList = new ArrayList<>();
- for (SetupDataCallResult dcResult : dataCallResultList) {
- dcResponseList.add(RIL.convertDataCallResult(dcResult));
- }
if (responseInfo.error == RadioError.NONE) {
- sendMessageResponse(rr.mResult, dcResponseList);
+ sendMessageResponse(rr.mResult, dataCallResultList);
}
- mRil.processResponseDone(rr, responseInfo, dcResponseList);
+ mRil.processResponseDone(rr, responseInfo, dataCallResultList);
}
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 7c5842f..2b6acdb 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -33,9 +33,6 @@
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.hardware.radio.V1_0.CellInfoType;
-import android.hardware.radio.V1_0.DataRegStateResult;
-import android.hardware.radio.V1_0.RegState;
-import android.hardware.radio.V1_0.VoiceRegStateResult;
import android.os.AsyncResult;
import android.os.BaseBundle;
import android.os.Build;
@@ -50,33 +47,42 @@
import android.os.WorkSource;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentity;
+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.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
+import android.telephony.DataSpecificRegistrationStates;
+import android.telephony.NetworkRegistrationState;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
+import android.telephony.VoiceSpecificRegistrationStates;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.LocalLog;
import android.util.Pair;
+import android.util.SparseArray;
import android.util.TimeUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
import com.android.internal.telephony.uicc.IccRecords;
@@ -452,6 +458,9 @@
private String mRegistrationDeniedReason;
private String mCurrentCarrier = null;
+ private final TransportManager mTransportManager;
+ private final SparseArray<NetworkRegistrationManager> mRegStateManagers = new SparseArray<>();
+
/* list of LTE EARFCNs (E-UTRA Absolute Radio Frequency Channel Number,
* Reference: 3GPP TS 36.104 5.4.3)
* inclusive ranges for which the lte rsrp boost is applied */
@@ -482,9 +491,17 @@
.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
mRestrictedState = new RestrictedState();
+ mTransportManager = new TransportManager();
+
+ for (int transportType : mTransportManager.getAvailableTransports()) {
+ mRegStateManagers.append(transportType, new NetworkRegistrationManager(
+ transportType, phone));
+ mRegStateManagers.get(transportType).registerForNetworkRegistrationStateChanged(
+ this, EVENT_NETWORK_STATE_CHANGED, null);
+ }
+
mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null);
mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
- mCi.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null);
mCr = phone.getContext().getContentResolver();
@@ -854,55 +871,37 @@
}
}
- private void processCellLocationInfo(CellLocation cellLocation,
- VoiceRegStateResult voiceRegStateResult) {
+ private void processCellLocationInfo(CellLocation cellLocation, CellIdentity cellIdentity) {
if (mPhone.isPhoneTypeGsm()) {
int psc = -1;
int cid = -1;
int lac = -1;
- switch(voiceRegStateResult.cellIdentity.cellInfoType) {
- case CellInfoType.GSM: {
- if (voiceRegStateResult.cellIdentity.cellIdentityGsm.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityGsm cellIdentityGsm =
- voiceRegStateResult.cellIdentity.cellIdentityGsm.get(0);
- cid = cellIdentityGsm.cid;
- lac = cellIdentityGsm.lac;
+ if (cellIdentity != null) {
+ switch (cellIdentity.getType()) {
+ case CellInfoType.GSM: {
+ cid = ((CellIdentityGsm) cellIdentity).getCid();
+ lac = ((CellIdentityGsm) cellIdentity).getLac();
+ break;
}
- break;
- }
- case CellInfoType.WCDMA: {
- if (voiceRegStateResult.cellIdentity.cellIdentityWcdma.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityWcdma cellIdentityWcdma =
- voiceRegStateResult.cellIdentity.cellIdentityWcdma.get(0);
- cid = cellIdentityWcdma.cid;
- lac = cellIdentityWcdma.lac;
- psc = cellIdentityWcdma.psc;
+ case CellInfoType.WCDMA: {
+ cid = ((CellIdentityWcdma) cellIdentity).getCid();
+ lac = ((CellIdentityWcdma) cellIdentity).getLac();
+ psc = ((CellIdentityWcdma) cellIdentity).getPsc();
+ break;
}
- break;
- }
- case CellInfoType.TD_SCDMA: {
- if (voiceRegStateResult.cellIdentity.cellIdentityTdscdma.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityTdscdma
- cellIdentityTdscdma =
- voiceRegStateResult.cellIdentity.cellIdentityTdscdma.get(0);
- cid = cellIdentityTdscdma.cid;
- lac = cellIdentityTdscdma.lac;
+ case CellInfoType.TD_SCDMA: {
+ cid = ((CellIdentityTdscdma) cellIdentity).getCid();
+ lac = ((CellIdentityTdscdma) cellIdentity).getLac();
+ break;
}
- break;
- }
- case CellInfoType.LTE: {
- if (voiceRegStateResult.cellIdentity.cellIdentityLte.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityLte cellIdentityLte =
- voiceRegStateResult.cellIdentity.cellIdentityLte.get(0);
- cid = cellIdentityLte.ci;
-
- /* Continuing the historical behaviour of using tac as lac. */
- lac = cellIdentityLte.tac;
+ case CellInfoType.LTE: {
+ cid = ((CellIdentityLte) cellIdentity).getCi();
+ lac = ((CellIdentityLte) cellIdentity).getTac();
+ break;
}
- break;
- }
- default: {
- break;
+ default: {
+ break;
+ }
}
}
// LAC and CID are -1 if not avail
@@ -915,21 +914,19 @@
int systemId = 0;
int networkId = 0;
- switch(voiceRegStateResult.cellIdentity.cellInfoType) {
- case CellInfoType.CDMA: {
- if (voiceRegStateResult.cellIdentity.cellIdentityCdma.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityCdma cellIdentityCdma =
- voiceRegStateResult.cellIdentity.cellIdentityCdma.get(0);
- baseStationId = cellIdentityCdma.baseStationId;
- baseStationLatitude = cellIdentityCdma.latitude;
- baseStationLongitude = cellIdentityCdma.longitude;
- systemId = cellIdentityCdma.systemId;
- networkId = cellIdentityCdma.networkId;
+ if (cellIdentity != null) {
+ switch (cellIdentity.getType()) {
+ case CellInfoType.CDMA: {
+ baseStationId = ((CellIdentityCdma) cellIdentity).getBasestationId();
+ baseStationLatitude = ((CellIdentityCdma) cellIdentity).getLatitude();
+ baseStationLongitude = ((CellIdentityCdma) cellIdentity).getLongitude();
+ systemId = ((CellIdentityCdma) cellIdentity).getSystemId();
+ networkId = ((CellIdentityCdma) cellIdentity).getNetworkId();
+ break;
}
- break;
- }
- default: {
- break;
+ default: {
+ break;
+ }
}
}
@@ -945,19 +942,17 @@
}
}
- private int getLteEarfcn(DataRegStateResult dataRegStateResult) {
+ private int getLteEarfcn(CellIdentity cellIdentity) {
int lteEarfcn = INVALID_LTE_EARFCN;
- switch(dataRegStateResult.cellIdentity.cellInfoType) {
- case CellInfoType.LTE: {
- if (dataRegStateResult.cellIdentity.cellIdentityLte.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityLte cellIdentityLte =
- dataRegStateResult.cellIdentity.cellIdentityLte.get(0);
- lteEarfcn = cellIdentityLte.earfcn;
+ if (cellIdentity != null) {
+ switch (cellIdentity.getType()) {
+ case CellInfoType.LTE: {
+ lteEarfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
+ break;
}
- break;
- }
- default: {
- break;
+ default: {
+ break;
+ }
}
}
@@ -1103,7 +1098,9 @@
case EVENT_GET_LOC_DONE:
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- processCellLocationInfo(mCellLoc, (VoiceRegStateResult) ar.result);
+ CellIdentity cellIdentity = ((NetworkRegistrationState) ar.result)
+ .getCellIdentity();
+ processCellLocationInfo(mCellLoc, cellIdentity);
mPhone.notifyLocationChanged();
}
@@ -1176,7 +1173,9 @@
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- mCi.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
+ mRegStateManagers.get(AccessNetworkConstants.TransportType.WWAN)
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ obtainMessage(EVENT_GET_LOC_DONE, null));
}
break;
@@ -1721,47 +1720,25 @@
return cdmaRoaming && !isSameOperatorNameFromSimAndSS(s);
}
- private int getRegStateFromHalRegState(int regState) {
- switch (regState) {
- case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
- return ServiceState.RIL_REG_STATE_NOT_REG;
- case RegState.REG_HOME:
- return ServiceState.RIL_REG_STATE_HOME;
- case RegState.NOT_REG_MT_SEARCHING_OP:
- return ServiceState.RIL_REG_STATE_SEARCHING;
- case RegState.REG_DENIED:
- return ServiceState.RIL_REG_STATE_DENIED;
- case RegState.UNKNOWN:
- return ServiceState.RIL_REG_STATE_UNKNOWN;
- case RegState.REG_ROAMING:
- return ServiceState.RIL_REG_STATE_ROAMING;
- case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
- return ServiceState.RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED;
- case RegState.NOT_REG_MT_SEARCHING_OP_EM:
- return ServiceState.RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED;
- case RegState.REG_DENIED_EM:
- return ServiceState.RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED;
- case RegState.UNKNOWN_EM:
- return ServiceState.RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED;
- default:
- return ServiceState.REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING;
- }
- }
-
void handlePollStateResultMessage(int what, AsyncResult ar) {
int ints[];
switch (what) {
case EVENT_POLL_STATE_REGISTRATION: {
- VoiceRegStateResult voiceRegStateResult = (VoiceRegStateResult) ar.result;
- int registrationState = getRegStateFromHalRegState(voiceRegStateResult.regState);
- int cssIndicator = voiceRegStateResult.cssSupported ? 1 : 0;
+ NetworkRegistrationState regStates = (NetworkRegistrationState) ar.result;
+ VoiceSpecificRegistrationStates voiceSpecificStates =
+ regStates.getVoiceSpecificStates();
+
+ int registrationState = regStates.getRegState();
+ int cssIndicator = voiceSpecificStates.cssSupported ? 1 : 0;
+ int newVoiceRat = ServiceState.networkTypeToRilRadioTechnology(
+ regStates.getAccessNetworkTechnology());
mNewSS.setVoiceRegState(regCodeToServiceState(registrationState));
mNewSS.setCssIndicator(cssIndicator);
- mNewSS.setRilVoiceRadioTechnology(voiceRegStateResult.rat);
+ mNewSS.setRilVoiceRadioTechnology(newVoiceRat);
//Denial reason if registrationState = 3
- int reasonForDenial = voiceRegStateResult.reasonForDenial;
+ int reasonForDenial = regStates.getReasonForDenial();
if (mPhone.isPhoneTypeGsm()) {
mGsmRoaming = regCodeIsRoaming(registrationState);
@@ -1769,27 +1746,15 @@
boolean isVoiceCapable = mPhone.getContext().getResources()
.getBoolean(com.android.internal.R.bool.config_voice_capable);
- if (((registrationState
- == ServiceState.RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED)
- || (registrationState
- == ServiceState.RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED)
- || (registrationState
- == ServiceState.RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED)
- || (registrationState
- == ServiceState.RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED))
- && isVoiceCapable) {
- mEmergencyOnly = true;
- } else {
- mEmergencyOnly = false;
- }
+ mEmergencyOnly = regStates.isEmergencyEnabled();
} else {
- int roamingIndicator = voiceRegStateResult.roamingIndicator;
+ int roamingIndicator = voiceSpecificStates.roamingIndicator;
//Indicates if current system is in PR
- int systemIsInPrl = voiceRegStateResult.systemIsInPrl;
+ int systemIsInPrl = voiceSpecificStates.systemIsInPrl;
//Is default roaming indicator from PRL
- int defaultRoamingIndicator = voiceRegStateResult.defaultRoamingIndicator;
+ int defaultRoamingIndicator = voiceSpecificStates.defaultRoamingIndicator;
mRegistrationState = registrationState;
// When registration state is roaming and TSB58
@@ -1806,12 +1771,10 @@
int systemId = 0;
int networkId = 0;
- if (voiceRegStateResult.cellIdentity.cellInfoType == CellInfoType.CDMA
- && voiceRegStateResult.cellIdentity.cellIdentityCdma.size() == 1) {
- android.hardware.radio.V1_0.CellIdentityCdma cellIdentityCdma =
- voiceRegStateResult.cellIdentity.cellIdentityCdma.get(0);
- systemId = cellIdentityCdma.systemId;
- networkId = cellIdentityCdma.networkId;
+ CellIdentity cellIdentity = regStates.getCellIdentity();
+ if (cellIdentity != null && cellIdentity.getType() == CellInfoType.CDMA) {
+ systemId = ((CellIdentityCdma) cellIdentity).getSystemId();
+ networkId = ((CellIdentityCdma) cellIdentity).getNetworkId();
}
mNewSS.setSystemAndNetworkId(systemId, networkId);
@@ -1828,34 +1791,37 @@
}
}
- processCellLocationInfo(mNewCellLoc, voiceRegStateResult);
+ processCellLocationInfo(mNewCellLoc, regStates.getCellIdentity());
if (DBG) {
log("handlPollVoiceRegResultMessage: regState=" + registrationState
- + " radioTechnology=" + voiceRegStateResult.rat);
+ + " radioTechnology=" + newVoiceRat);
}
break;
}
case EVENT_POLL_STATE_GPRS: {
- DataRegStateResult dataRegStateResult = (DataRegStateResult) ar.result;
- int regState = getRegStateFromHalRegState(dataRegStateResult.regState);
- int dataRegState = regCodeToServiceState(regState);
- int newDataRat = dataRegStateResult.rat;
- mNewSS.setDataRegState(dataRegState);
+ NetworkRegistrationState regStates = (NetworkRegistrationState) ar.result;
+ DataSpecificRegistrationStates dataSpecificStates =
+ regStates.getDataSpecificStates();
+ int regState = regStates.getRegState();
+ int serviceState = regCodeToServiceState(regState);
+ int newDataRat = ServiceState.networkTypeToRilRadioTechnology(
+ regStates.getAccessNetworkTechnology());
+ mNewSS.setDataRegState(serviceState);
mNewSS.setRilDataRadioTechnology(newDataRat);
if (mPhone.isPhoneTypeGsm()) {
- mNewReasonDataDenied = dataRegStateResult.reasonDataDenied;
- mNewMaxDataCalls = dataRegStateResult.maxDataCalls;
+ mNewReasonDataDenied = regStates.getReasonForDenial();
+ mNewMaxDataCalls = dataSpecificStates.maxDataCalls;
mDataRoaming = regCodeIsRoaming(regState);
// Save the data roaming state reported by modem registration before resource
// overlay or carrier config possibly overrides it.
mNewSS.setDataRoamingFromRegistration(mDataRoaming);
if (DBG) {
- log("handlPollStateResultMessage: GsmSST setDataRegState=" + dataRegState
+ log("handlPollStateResultMessage: GsmSST dataServiceState=" + serviceState
+ " regState=" + regState
+ " dataRadioTechnology=" + newDataRat);
}
@@ -1868,7 +1834,7 @@
mNewSS.setDataRoamingFromRegistration(isDataRoaming);
if (DBG) {
- log("handlPollStateResultMessage: cdma setDataRegState=" + dataRegState
+ log("handlPollStateResultMessage: cdma dataServiceState=" + serviceState
+ " regState=" + regState
+ " dataRadioTechnology=" + newDataRat);
}
@@ -1896,13 +1862,13 @@
// overlay or carrier config possibly overrides it.
mNewSS.setDataRoamingFromRegistration(isDataRoaming);
if (DBG) {
- log("handlPollStateResultMessage: CdmaLteSST setDataRegState="
- + dataRegState + " regState=" + regState + " dataRadioTechnology="
+ log("handlPollStateResultMessage: CdmaLteSST dataServiceState="
+ + serviceState + " regState=" + regState + " dataRadioTechnology="
+ newDataRat);
}
}
- updateServiceStateLteEarfcnBoost(mNewSS, getLteEarfcn(dataRegStateResult));
+ updateServiceStateLteEarfcnBoost(mNewSS, getLteEarfcn(regStates.getCellIdentity()));
break;
}
@@ -2567,15 +2533,19 @@
default:
// Issue all poll-related commands at once then count down the responses, which
// are allowed to arrive out-of-order
+ // TODO: Add WLAN support.
mPollingContext[0]++;
mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR, mPollingContext));
mPollingContext[0]++;
- mCi.getDataRegistrationState(obtainMessage(EVENT_POLL_STATE_GPRS, mPollingContext));
+ mRegStateManagers.get(AccessNetworkConstants.TransportType.WWAN)
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+ obtainMessage(EVENT_POLL_STATE_GPRS, mPollingContext));
mPollingContext[0]++;
- mCi.getVoiceRegistrationState(obtainMessage(EVENT_POLL_STATE_REGISTRATION,
- mPollingContext));
+ mRegStateManagers.get(AccessNetworkConstants.TransportType.WWAN)
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ obtainMessage(EVENT_POLL_STATE_REGISTRATION, mPollingContext));
if (mPhone.isPhoneTypeGsm()) {
mPollingContext[0]++;
@@ -3122,8 +3092,8 @@
* to service state */
private int regCodeToServiceState(int code) {
switch (code) {
- case ServiceState.RIL_REG_STATE_HOME:
- case ServiceState.RIL_REG_STATE_ROAMING:
+ case NetworkRegistrationState.REG_STATE_HOME:
+ case NetworkRegistrationState.REG_STATE_ROAMING:
return ServiceState.STATE_IN_SERVICE;
default:
return ServiceState.STATE_OUT_OF_SERVICE;
@@ -3135,7 +3105,7 @@
* returns true if registered roam, false otherwise
*/
private boolean regCodeIsRoaming (int code) {
- return ServiceState.RIL_REG_STATE_ROAMING == code;
+ return NetworkRegistrationState.REG_STATE_ROAMING == code;
}
private boolean isSameOperatorNameFromSimAndSS(ServiceState s) {
diff --git a/src/java/com/android/internal/telephony/SubscriptionMonitor.java b/src/java/com/android/internal/telephony/SubscriptionMonitor.java
index 8ccec6f..4307875 100644
--- a/src/java/com/android/internal/telephony/SubscriptionMonitor.java
+++ b/src/java/com/android/internal/telephony/SubscriptionMonitor.java
@@ -70,7 +70,7 @@
public SubscriptionMonitor(ITelephonyRegistry tr, Context context,
SubscriptionController subscriptionController, int numPhones) {
try {
- tr.addOnSubscriptionsChangedListener(context.getOpPackageName(),
+ tr.addOnSubscriptionsChangedListener("SubscriptionMonitor",
mSubscriptionsChangedListener);
} catch (RemoteException e) {
}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index 8ef4a2a..e379a69 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -21,6 +21,7 @@
import android.os.Handler;
import android.os.IDeviceIdleController;
import android.os.ServiceManager;
+import android.telephony.AccessNetworkConstants.TransportType;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
@@ -71,19 +72,12 @@
return new NitzStateMachine(phone);
}
- /**
- * Returns a new {@link TimeServiceHelper} instance.
- */
- public TimeServiceHelper makeTimeServiceHelper(Context context) {
- return new TimeServiceHelper(context);
- }
-
public SimActivationTracker makeSimActivationTracker(Phone phone) {
return new SimActivationTracker(phone);
}
public DcTracker makeDcTracker(Phone phone) {
- return new DcTracker(phone);
+ return new DcTracker(phone, TransportType.WWAN);
}
public CarrierSignalAgent makeCarrierSignalAgent(Phone phone) {
diff --git a/src/java/com/android/internal/telephony/TelephonyTester.java b/src/java/com/android/internal/telephony/TelephonyTester.java
index b59fcb6..16fac4d 100644
--- a/src/java/com/android/internal/telephony/TelephonyTester.java
+++ b/src/java/com/android/internal/telephony/TelephonyTester.java
@@ -23,14 +23,15 @@
import android.net.Uri;
import android.os.BadParcelableException;
import android.os.Build;
+import android.telephony.NetworkRegistrationState;
import android.telephony.Rlog;
import android.telephony.ServiceState;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsConferenceState;
+import android.telephony.ims.ImsExternalCallState;
+import android.telephony.ims.ImsReasonInfo;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
-import com.android.ims.ImsConferenceState;
-import com.android.ims.ImsExternalCallState;
-import com.android.ims.ImsReasonInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
@@ -338,12 +339,12 @@
}
if (mServiceStateTestIntent.hasExtra(EXTRA_VOICE_REG_STATE)) {
ss.setVoiceRegState(mServiceStateTestIntent.getIntExtra(EXTRA_VOICE_REG_STATE,
- ServiceState.RIL_REG_STATE_UNKNOWN));
+ NetworkRegistrationState.REG_STATE_UNKNOWN));
log("Override voice reg state with " + ss.getVoiceRegState());
}
if (mServiceStateTestIntent.hasExtra(EXTRA_DATA_REG_STATE)) {
ss.setDataRegState(mServiceStateTestIntent.getIntExtra(EXTRA_DATA_REG_STATE,
- ServiceState.RIL_REG_STATE_UNKNOWN));
+ NetworkRegistrationState.REG_STATE_UNKNOWN));
log("Override data reg state with " + ss.getDataRegState());
}
if (mServiceStateTestIntent.hasExtra(EXTRA_VOICE_RAT)) {
diff --git a/src/java/com/android/internal/telephony/TimeServiceHelper.java b/src/java/com/android/internal/telephony/TimeServiceHelper.java
index fb1efd0..94b094f 100644
--- a/src/java/com/android/internal/telephony/TimeServiceHelper.java
+++ b/src/java/com/android/internal/telephony/TimeServiceHelper.java
@@ -91,6 +91,20 @@
}
/**
+ * Returns the same value as {@link System#currentTimeMillis()}.
+ */
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ /**
+ * Returns the same value as {@link SystemClock#elapsedRealtime()}.
+ */
+ public long elapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
+
+ /**
* Returns true if the device has an explicit time zone set.
*/
public boolean isTimeZoneSettingInitialized() {
diff --git a/src/java/com/android/internal/telephony/TimeZoneLookupHelper.java b/src/java/com/android/internal/telephony/TimeZoneLookupHelper.java
index 8b3276b..101fddd 100644
--- a/src/java/com/android/internal/telephony/TimeZoneLookupHelper.java
+++ b/src/java/com/android/internal/telephony/TimeZoneLookupHelper.java
@@ -16,12 +16,11 @@
package com.android.internal.telephony;
-import android.util.TimeUtils;
+import android.text.TextUtils;
import libcore.util.CountryTimeZones;
import libcore.util.TimeZoneFinder;
-import java.util.Arrays;
import java.util.Date;
import java.util.TimeZone;
@@ -30,72 +29,150 @@
*/
// Non-final to allow mocking.
public class TimeZoneLookupHelper {
- private static final int MS_PER_HOUR = 60 * 60 * 1000;
/**
- * List of ISO codes for countries that can have an offset of
- * GMT+0 when not in daylight savings time. This ignores some
- * small places such as the Canary Islands (Spain) and
- * Danmarkshavn (Denmark). The list must be sorted by code.
+ * The result of looking up a time zone using offset information (and possibly more).
*/
- private static final String[] GMT_COUNTRY_CODES = {
- "bf", // Burkina Faso
- "ci", // Cote d'Ivoire
- "eh", // Western Sahara
- "fo", // Faroe Islands, Denmark
- "gb", // United Kingdom of Great Britain and Northern Ireland
- "gh", // Ghana
- "gm", // Gambia
- "gn", // Guinea
- "gw", // Guinea Bissau
- "ie", // Ireland
- "lr", // Liberia
- "is", // Iceland
- "ma", // Morocco
- "ml", // Mali
- "mr", // Mauritania
- "pt", // Portugal
- "sl", // Sierra Leone
- "sn", // Senegal
- "st", // Sao Tome and Principe
- "tg", // Togo
- };
+ public static final class OffsetResult {
+
+ /** A zone that matches the supplied criteria. See also {@link #isOnlyMatch}. */
+ public final String zoneId;
+
+ /** True if there is only one matching time zone for the supplied criteria. */
+ public final boolean isOnlyMatch;
+
+ public OffsetResult(String zoneId, boolean isOnlyMatch) {
+ this.zoneId = zoneId;
+ this.isOnlyMatch = isOnlyMatch;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ OffsetResult result = (OffsetResult) o;
+
+ if (isOnlyMatch != result.isOnlyMatch) {
+ return false;
+ }
+ return zoneId.equals(result.zoneId);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = zoneId.hashCode();
+ result = 31 * result + (isOnlyMatch ? 1 : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Result{"
+ + "zoneId='" + zoneId + '\''
+ + ", isOnlyMatch=" + isOnlyMatch
+ + '}';
+ }
+ }
+
+ /**
+ * The result of looking up a time zone using country information.
+ */
+ public static final class CountryResult {
+
+ /** A time zone for the country. */
+ public final String zoneId;
+
+ /**
+ * True if all the time zones in the country have the same offset at {@link #whenMillis}.
+ */
+ public final boolean allZonesHaveSameOffset;
+
+ /** The time associated with {@link #allZonesHaveSameOffset}. */
+ public final long whenMillis;
+
+ public CountryResult(String zoneId, boolean allZonesHaveSameOffset, long whenMillis) {
+ this.zoneId = zoneId;
+ this.allZonesHaveSameOffset = allZonesHaveSameOffset;
+ this.whenMillis = whenMillis;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ CountryResult that = (CountryResult) o;
+
+ if (allZonesHaveSameOffset != that.allZonesHaveSameOffset) {
+ return false;
+ }
+ if (whenMillis != that.whenMillis) {
+ return false;
+ }
+ return zoneId.equals(that.zoneId);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = zoneId.hashCode();
+ result = 31 * result + (allZonesHaveSameOffset ? 1 : 0);
+ result = 31 * result + (int) (whenMillis ^ (whenMillis >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "CountryResult{"
+ + "zoneId='" + zoneId + '\''
+ + ", allZonesHaveSameOffset=" + allZonesHaveSameOffset
+ + ", whenMillis=" + whenMillis
+ + '}';
+ }
+ }
+
+ private static final int MS_PER_HOUR = 60 * 60 * 1000;
+
+ /** The last CountryTimeZones object retrieved. */
+ private CountryTimeZones mLastCountryTimeZones;
public TimeZoneLookupHelper() {}
/**
- * Finds a time zone ID that fits the supplied NITZ and country information.
+ * Looks for a time zone for the supplied NITZ and country information.
*
* <p><em>Note:</em> When there are multiple matching zones then one of the matching candidates
- * will be returned. If the current device default zone matches it will be returned in
- * preference to other candidates. This method can return {@code null} if no matching time
- * zones are found.
+ * will be returned in the result. If the current device default zone matches it will be
+ * returned in preference to other candidates. This method can return {@code null} if no
+ * matching time zones are found.
*/
- public String guessZoneIdByNitzCountry(NitzData nitzData, String isoCountryCode) {
- return guessZoneIdByInstantOffsetDstCountry(
- nitzData.getCurrentTimeInMillis(),
- nitzData.getLocalOffsetMillis(),
- nitzData.isDst(),
- isoCountryCode);
+ public OffsetResult lookupByNitzCountry(NitzData nitzData, String isoCountryCode) {
+ CountryTimeZones countryTimeZones = getCountryTimeZones(isoCountryCode);
+ if (countryTimeZones == null) {
+ return null;
+ }
+ android.icu.util.TimeZone bias = android.icu.util.TimeZone.getDefault();
+
+ CountryTimeZones.OffsetResult offsetResult = countryTimeZones.lookupByOffsetWithBias(
+ nitzData.getLocalOffsetMillis(), nitzData.isDst(),
+ nitzData.getCurrentTimeInMillis(), bias);
+
+ if (offsetResult == null) {
+ return null;
+ }
+ return new OffsetResult(offsetResult.mTimeZone.getID(), offsetResult.mOneMatch);
}
/**
- * Finds a time zone ID that fits the supplied time / offset and country information.
- *
- * <p><em>Note:</em> When there are multiple matching zones then one of the matching candidates
- * will be returned. If the current device default zone matches it will be returned in
- * preference to other candidates. This method can return {@code null} if no matching time
- * zones are found.
- */
- public String guessZoneIdByInstantOffsetDstCountry(
- long timeMillis, int utcOffsetMillis, boolean isDst, String isoCountryCode) {
- TimeZone timeZone =
- TimeUtils.getTimeZone(utcOffsetMillis, isDst, timeMillis, isoCountryCode);
- return timeZone == null ? null : timeZone.getID();
- }
-
- /**
- * Finds a time zone ID using only information present in the supplied {@link NitzData} object.
+ * Looks for a time zone using only information present in the supplied {@link NitzData} object.
*
* <p><em>Note:</em> Because multiple time zones can have the same offset / DST state at a given
* time this process is error prone; an arbitrary match is returned when there are multiple
@@ -103,9 +180,8 @@
* information provided by NITZ is incorrect. This method can return {@code null} if no matching
* time zones are found.
*/
- public String guessZoneIdByNitz(NitzData nitzData) {
- TimeZone zone = guessZoneByNitzStatic(nitzData);
- return zone == null ? null : zone.getID();
+ public OffsetResult lookupByNitz(NitzData nitzData) {
+ return lookupByNitzStatic(nitzData);
}
/**
@@ -115,59 +191,108 @@
* according to the device's current system clock time). If this is not the case then
* {@code null} can be returned.
*/
- public String guessZoneIdByCountry(String isoCountryCode, long whenMillis) {
- CountryTimeZones countryTimeZones =
- TimeZoneFinder.getInstance().lookupCountryTimeZones(isoCountryCode);
+ public CountryResult lookupByCountry(String isoCountryCode, long whenMillis) {
+ CountryTimeZones countryTimeZones = getCountryTimeZones(isoCountryCode);
if (countryTimeZones == null) {
// Unknown country code.
return null;
}
-
- if (countryTimeZones.isDefaultOkForCountryTimeZoneDetection(whenMillis)) {
- return countryTimeZones.getDefaultTimeZoneId();
+ if (countryTimeZones.getDefaultTimeZoneId() == null) {
+ return null;
}
- return null;
+
+ return new CountryResult(
+ countryTimeZones.getDefaultTimeZoneId(),
+ countryTimeZones.isDefaultOkForCountryTimeZoneDetection(whenMillis),
+ whenMillis);
}
- /** Static method for use by {@link ServiceStateTracker}. */
+ /**
+ * Finds a time zone using only information present in the supplied {@link NitzData} object.
+ * This is a static method for use by {@link ServiceStateTracker}.
+ *
+ * <p><em>Note:</em> Because multiple time zones can have the same offset / DST state at a given
+ * time this process is error prone; an arbitrary match is returned when there are multiple
+ * candidates. The algorithm can also return a non-exact match by assuming that the DST
+ * information provided by NITZ is incorrect. This method can return {@code null} if no matching
+ * time zones are found.
+ */
static TimeZone guessZoneByNitzStatic(NitzData nitzData) {
+ OffsetResult result = lookupByNitzStatic(nitzData);
+ return result != null ? TimeZone.getTimeZone(result.zoneId) : null;
+ }
+
+ private static OffsetResult lookupByNitzStatic(NitzData nitzData) {
int utcOffsetMillis = nitzData.getLocalOffsetMillis();
boolean isDst = nitzData.isDst();
long timeMillis = nitzData.getCurrentTimeInMillis();
- TimeZone guess = guessByInstantOffsetDst(timeMillis, utcOffsetMillis, isDst);
- if (guess == null) {
+ OffsetResult match = lookupByInstantOffsetDst(timeMillis, utcOffsetMillis, isDst);
+ if (match == null) {
// Couldn't find a proper timezone. Perhaps the DST data is wrong.
- guess = guessByInstantOffsetDst(timeMillis, utcOffsetMillis, !isDst);
+ match = lookupByInstantOffsetDst(timeMillis, utcOffsetMillis, !isDst);
}
- return guess;
+ return match;
}
- private static TimeZone guessByInstantOffsetDst(long timeMillis, int utcOffsetMillis,
+ private static OffsetResult lookupByInstantOffsetDst(long timeMillis, int utcOffsetMillis,
boolean isDst) {
int rawOffset = utcOffsetMillis;
if (isDst) {
rawOffset -= MS_PER_HOUR;
}
String[] zones = TimeZone.getAvailableIDs(rawOffset);
- TimeZone guess = null;
+ TimeZone match = null;
Date d = new Date(timeMillis);
+ boolean isOnlyMatch = true;
for (String zone : zones) {
TimeZone tz = TimeZone.getTimeZone(zone);
if (tz.getOffset(timeMillis) == utcOffsetMillis && tz.inDaylightTime(d) == isDst) {
- guess = tz;
- break;
+ if (match == null) {
+ match = tz;
+ } else {
+ isOnlyMatch = false;
+ break;
+ }
}
}
- return guess;
+ if (match == null) {
+ return null;
+ }
+ return new OffsetResult(match.getID(), isOnlyMatch);
}
/**
* Returns {@code true} if the supplied (lower-case) ISO country code is for a country known to
- * use a raw offset of zero from UTC.
+ * use a raw offset of zero from UTC at the time specified.
*/
- public boolean countryUsesUtc(String isoCountryCode) {
- return Arrays.binarySearch(GMT_COUNTRY_CODES, isoCountryCode) >= 0;
+ public boolean countryUsesUtc(String isoCountryCode, long whenMillis) {
+ if (TextUtils.isEmpty(isoCountryCode)) {
+ return false;
+ }
+
+ CountryTimeZones countryTimeZones = getCountryTimeZones(isoCountryCode);
+ return countryTimeZones != null && countryTimeZones.hasUtcZone(whenMillis);
+ }
+
+ private CountryTimeZones getCountryTimeZones(String isoCountryCode) {
+ // A single entry cache of the last CountryTimeZones object retrieved since there should
+ // be strong consistency across calls.
+ synchronized (this) {
+ if (mLastCountryTimeZones != null) {
+ if (mLastCountryTimeZones.isForCountryCode(isoCountryCode)) {
+ return mLastCountryTimeZones;
+ }
+ }
+
+ // Perform the lookup. It's very unlikely to return null, but we won't cache null.
+ CountryTimeZones countryTimeZones =
+ TimeZoneFinder.getInstance().lookupCountryTimeZones(isoCountryCode);
+ if (countryTimeZones != null) {
+ mLastCountryTimeZones = countryTimeZones;
+ }
+ return countryTimeZones;
+ }
}
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index b94c8a1..e7ced2e 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -45,6 +45,7 @@
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
+import android.telephony.data.DataServiceCallback;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Pair;
@@ -54,7 +55,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CallTracker;
import com.android.internal.telephony.CarrierSignalAgent;
-import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -174,6 +174,7 @@
private DcFailCause mDcFailCause;
private Phone mPhone;
+ private DataServiceManager mDataServiceManager;
private LinkProperties mLinkProperties = new LinkProperties();
private long mCreateTime;
private long mLastFailTime;
@@ -197,7 +198,6 @@
static final int BASE = Protocol.BASE_DATA_CONNECTION;
static final int EVENT_CONNECT = BASE + 0;
static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
- static final int EVENT_GET_LAST_FAIL_DONE = BASE + 2;
static final int EVENT_DEACTIVATE_DONE = BASE + 3;
static final int EVENT_DISCONNECT = BASE + 4;
static final int EVENT_RIL_CONNECTED = BASE + 5;
@@ -226,7 +226,6 @@
sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
"EVENT_SETUP_DATA_CONNECTION_DONE";
- sCmdToString[EVENT_GET_LAST_FAIL_DONE - BASE] = "EVENT_GET_LAST_FAIL_DONE";
sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED";
@@ -273,11 +272,13 @@
* @param id the connection id
* @return DataConnection that was created.
*/
- public static DataConnection makeDataConnection(Phone phone, int id,
- DcTracker dct, DcTesterFailBringUpAll failBringUpAll,
- DcController dcc) {
+ public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct,
+ DataServiceManager dataServiceManager,
+ DcTesterFailBringUpAll failBringUpAll,
+ DcController dcc) {
DataConnection dc = new DataConnection(phone,
- "DC-" + mInstanceNumber.incrementAndGet(), id, dct, failBringUpAll, dcc);
+ "DC-" + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager,
+ failBringUpAll, dcc);
dc.start();
if (DBG) dc.log("Made " + dc.getName());
return dc;
@@ -325,11 +326,10 @@
*/
public enum SetupResult {
SUCCESS,
- ERR_BadCommand,
- ERR_UnacceptableParameter,
- ERR_GetLastErrorFromRil,
- ERR_Stale,
- ERR_RilError;
+ ERROR_RADIO_NOT_AVAILABLE,
+ ERROR_INVALID_ARG,
+ ERROR_STALE,
+ ERROR_DATA_SERVICE_SPECIFIC_ERROR;
public DcFailCause mFailCause;
@@ -377,12 +377,12 @@
return ret;
}
+ @VisibleForTesting
public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) {
UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
if (newState == null) return result;
- SetupResult setupResult;
result.newLp = new LinkProperties();
// set link properties based on data call response
@@ -444,7 +444,8 @@
//***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
private DataConnection(Phone phone, String name, int id,
- DcTracker dct, DcTesterFailBringUpAll failBringUpAll,
+ DcTracker dct, DataServiceManager dataServiceManager,
+ DcTesterFailBringUpAll failBringUpAll,
DcController dcc) {
super(name, dcc.getHandler());
setLogRecSize(300);
@@ -453,6 +454,7 @@
mPhone = phone;
mDct = dct;
+ mDataServiceManager = dataServiceManager;
mDcTesterFailBringUpAll = failBringUpAll;
mDcController = dcc;
mId = id;
@@ -480,7 +482,7 @@
/**
* Begin setting up a data connection, calls setupDataCall
* and the ConnectionParams will be returned with the
- * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResult.userObj.
+ * EVENT_SETUP_DATA_CONNECTION_DONE
*
* @param cp is the connection parameters
*/
@@ -512,7 +514,6 @@
mLastFailTime = -1;
mLastFailCause = DcFailCause.NONE;
- // msg.obj will be returned in AsyncResult.userObj;
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
msg.obj = cp;
@@ -529,8 +530,9 @@
boolean allowRoaming = mPhone.getDataRoamingEnabled()
|| (isModemRoaming && !mPhone.getServiceState().getDataRoaming());
- mPhone.mCi.setupDataCall(ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), dp,
- isModemRoaming, allowRoaming, DataService.REQUEST_REASON_NORMAL, null, msg);
+ mDataServiceManager.setupDataCall(
+ ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), dp, isModemRoaming,
+ allowRoaming, DataService.REQUEST_REASON_NORMAL, null, msg);
TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
dp.getProfileId(), dp.getApn(), dp.getProtocol());
}
@@ -543,8 +545,7 @@
/**
* TearDown the data connection when the deactivation is complete a Message with
- * msg.what == EVENT_DEACTIVATE_DONE and msg.obj == AsyncResult with AsyncResult.obj
- * containing the parameter o.
+ * msg.what == EVENT_DEACTIVATE_DONE
*
* @param o is the object returned in the AsyncResult.obj.
*/
@@ -552,7 +553,7 @@
int discReason = DataService.REQUEST_REASON_NORMAL;
ApnContext apnContext = null;
if ((o != null) && (o instanceof DisconnectParams)) {
- DisconnectParams dp = (DisconnectParams)o;
+ DisconnectParams dp = (DisconnectParams) o;
apnContext = dp.mApnContext;
if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF)
|| TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) {
@@ -563,7 +564,7 @@
String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason;
if (DBG) log(str);
if (apnContext != null) apnContext.requestLog(str);
- mPhone.mCi.deactivateDataCall(mCid, discReason,
+ mDataServiceManager.deactivateDataCall(mCid, discReason,
obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o));
}
@@ -719,39 +720,34 @@
}
/**
- * Process setup completion.
+ * Process setup data completion result from data service
*
- * @param ar is the result
- * @return SetupResult.
+ * @param resultCode The result code returned by data service
+ * @param response Data call setup response from data service
+ * @param cp The original connection params used for data call setup
+ * @return Setup result
*/
- private SetupResult onSetupConnectionCompleted(AsyncResult ar) {
- DataCallResponse response = (DataCallResponse) ar.result;
- ConnectionParams cp = (ConnectionParams) ar.userObj;
+ private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode,
+ DataCallResponse response,
+ ConnectionParams cp) {
SetupResult result;
if (cp.mTag != mTag) {
if (DBG) {
log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag);
}
- result = SetupResult.ERR_Stale;
- } else if (ar.exception != null) {
- if (DBG) {
- log("onSetupConnectionCompleted failed, ar.exception=" + ar.exception +
- " response=" + response);
- }
-
- if (ar.exception instanceof CommandException
- && ((CommandException) (ar.exception)).getCommandError()
- == CommandException.Error.RADIO_NOT_AVAILABLE) {
- result = SetupResult.ERR_BadCommand;
+ result = SetupResult.ERROR_STALE;
+ } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
+ result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
+ result.mFailCause = DcFailCause.RADIO_NOT_AVAILABLE;
+ } else if (response.getStatus() != 0) {
+ if (response.getStatus() == DcFailCause.RADIO_NOT_AVAILABLE.getErrorCode()) {
+ result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
result.mFailCause = DcFailCause.RADIO_NOT_AVAILABLE;
} else {
- result = SetupResult.ERR_RilError;
+ result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
result.mFailCause = DcFailCause.fromInt(response.getStatus());
}
- } else if (response.getStatus() != 0) {
- result = SetupResult.ERR_RilError;
- result.mFailCause = DcFailCause.fromInt(response.getStatus());
} else {
if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
mCid = response.getCallId();
@@ -1134,10 +1130,10 @@
result = SetupResult.SUCCESS;
} catch (UnknownHostException e) {
log("setLinkProperties: UnknownHostException " + e);
- result = SetupResult.ERR_UnacceptableParameter;
+ result = SetupResult.ERROR_INVALID_ARG;
}
} else {
- result = SetupResult.ERR_RilError;
+ result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
}
// An error occurred so clear properties
@@ -1232,6 +1228,7 @@
mDct = null;
mApnSetting = null;
mPhone = null;
+ mDataServiceManager = null;
mLinkProperties = null;
mLastFailCause = null;
mUserData = null;
@@ -1338,7 +1335,8 @@
break;
case EVENT_TEAR_DOWN_NOW:
if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW");
- mPhone.mCi.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL, null);
+ mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL,
+ null);
break;
case EVENT_LOST_CONNECTION:
if (DBG) {
@@ -1568,11 +1566,12 @@
break;
case EVENT_SETUP_DATA_CONNECTION_DONE:
- ar = (AsyncResult) msg.obj;
- cp = (ConnectionParams) ar.userObj;
+ cp = (ConnectionParams) msg.obj;
- SetupResult result = onSetupConnectionCompleted(ar);
- if (result != SetupResult.ERR_Stale) {
+ DataCallResponse dataCallResponse =
+ msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
+ SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp);
+ if (result != SetupResult.ERROR_STALE) {
if (mConnectionParams != cp) {
loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams
+ " != cp:" + cp);
@@ -1591,28 +1590,29 @@
mDcFailCause = DcFailCause.NONE;
transitionTo(mActiveState);
break;
- case ERR_BadCommand:
+ case ERROR_RADIO_NOT_AVAILABLE:
// Vendor ril rejected the command and didn't connect.
// Transition to inactive but send notifications after
// we've entered the mInactive state.
mInactiveState.setEnterNotificationParams(cp, result.mFailCause);
transitionTo(mInactiveState);
break;
- case ERR_UnacceptableParameter:
+ case ERROR_INVALID_ARG:
// The addresses given from the RIL are bad
tearDownData(cp);
transitionTo(mDisconnectingErrorCreatingConnection);
break;
- case ERR_RilError:
+ case ERROR_DATA_SERVICE_SPECIFIC_ERROR:
// Retrieve the suggested retry delay from the modem and save it.
// If the modem want us to retry the current APN again, it will
// suggest a positive delay value (in milliseconds). Otherwise we'll get
// NO_SUGGESTED_RETRY_DELAY here.
- long delay = getSuggestedRetryDelay(ar);
+
+ long delay = getSuggestedRetryDelay(dataCallResponse);
cp.mApnContext.setModemSuggestedDelay(delay);
- String str = "DcActivatingState: ERR_RilError "
+ String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR "
+ " delay=" + delay
+ " result=" + result
+ " result.isRestartRadioFail=" +
@@ -1629,7 +1629,7 @@
mInactiveState.setEnterNotificationParams(cp, result.mFailCause);
transitionTo(mInactiveState);
break;
- case ERR_Stale:
+ case ERROR_STALE:
loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE"
+ " tag:" + cp.mTag + " != mTag:" + mTag);
break;
@@ -1638,46 +1638,6 @@
}
retVal = HANDLED;
break;
-
- case EVENT_GET_LAST_FAIL_DONE:
- ar = (AsyncResult) msg.obj;
- cp = (ConnectionParams) ar.userObj;
- if (cp.mTag == mTag) {
- if (mConnectionParams != cp) {
- loge("DcActivatingState: WEIRD mConnectionsParams:" + mConnectionParams
- + " != cp:" + cp);
- }
-
- DcFailCause cause = DcFailCause.UNKNOWN;
-
- if (ar.exception == null) {
- int rilFailCause = ((int[]) (ar.result))[0];
- cause = DcFailCause.fromInt(rilFailCause);
- if (cause == DcFailCause.NONE) {
- if (DBG) {
- log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE"
- + " BAD: error was NONE, change to UNKNOWN");
- }
- cause = DcFailCause.UNKNOWN;
- }
- }
- mDcFailCause = cause;
-
- if (DBG) {
- log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE"
- + " cause=" + cause + " dc=" + DataConnection.this);
- }
-
- mInactiveState.setEnterNotificationParams(cp, cause);
- transitionTo(mInactiveState);
- } else {
- loge("DcActivatingState: stale EVENT_GET_LAST_FAIL_DONE"
- + " tag:" + cp.mTag + " != mTag:" + mTag);
- }
-
- retVal = HANDLED;
- break;
-
default:
if (VDBG) {
log("DcActivatingState not handled msg.what=" +
@@ -1978,8 +1938,7 @@
break;
case EVENT_DEACTIVATE_DONE:
- AsyncResult ar = (AsyncResult) msg.obj;
- DisconnectParams dp = (DisconnectParams) ar.userObj;
+ DisconnectParams dp = (DisconnectParams) msg.obj;
String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount="
+ mApnContexts.size();
@@ -1989,7 +1948,7 @@
if (dp.mTag == mTag) {
// Transition to inactive but send notifications after
// we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams((DisconnectParams) ar.userObj);
+ mInactiveState.setEnterNotificationParams(dp);
transitionTo(mInactiveState);
} else {
if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE"
@@ -2021,8 +1980,7 @@
switch (msg.what) {
case EVENT_DEACTIVATE_DONE:
- AsyncResult ar = (AsyncResult) msg.obj;
- ConnectionParams cp = (ConnectionParams) ar.userObj;
+ ConnectionParams cp = (ConnectionParams) msg.obj;
if (cp.mTag == mTag) {
String str = "DcDisconnectionErrorCreatingConnection" +
" msg.what=EVENT_DEACTIVATE_DONE";
@@ -2274,14 +2232,11 @@
/**
* Using the result of the SETUP_DATA_CALL determine the retry delay.
*
- * @param ar is the result from SETUP_DATA_CALL
+ * @param response The response from setup data call
* @return NO_SUGGESTED_RETRY_DELAY if no retry is needed otherwise the delay to the
* next SETUP_DATA_CALL
*/
- private long getSuggestedRetryDelay(AsyncResult ar) {
-
- DataCallResponse response = (DataCallResponse) ar.result;
-
+ private long getSuggestedRetryDelay(DataCallResponse response) {
/** According to ril.h
* The value < 0 means no value is suggested
* The value 0 means retry should be done ASAP.
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index 185864c..8c3f751 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -41,9 +41,9 @@
import com.android.internal.telephony.Phone;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Data service manager manages handling data requests and responses on data services (e.g.
@@ -51,7 +51,7 @@
*/
public class DataServiceManager {
private static final String TAG = DataServiceManager.class.getSimpleName();
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
static final String DATA_CALL_RESPONSE = "data_call_response";
@@ -69,7 +69,7 @@
private final RegistrantList mServiceBindingChangedRegistrants = new RegistrantList();
- private final Map<CellularDataServiceCallback, Message> mMessageMap = new HashMap<>();
+ private final Map<IBinder, Message> mMessageMap = new ConcurrentHashMap<>();
private final RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
@@ -128,29 +128,33 @@
log("onSetupDataCallComplete. resultCode = " + resultCode + ", response = "
+ response);
}
- Message msg = mMessageMap.remove(CellularDataServiceCallback.this);
- msg.getData().putParcelable(DATA_CALL_RESPONSE, response);
- sendCompleteMessage(msg, resultCode);
+ Message msg = mMessageMap.remove(asBinder());
+ if (msg != null) {
+ msg.getData().putParcelable(DATA_CALL_RESPONSE, response);
+ sendCompleteMessage(msg, resultCode);
+ } else {
+ loge("Unable to find the message for setup call response.");
+ }
}
@Override
public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {
if (DBG) log("onDeactivateDataCallComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(CellularDataServiceCallback.this);
+ Message msg = mMessageMap.remove(asBinder());
sendCompleteMessage(msg, resultCode);
}
@Override
public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {
if (DBG) log("onSetInitialAttachApnComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(CellularDataServiceCallback.this);
+ Message msg = mMessageMap.remove(asBinder());
sendCompleteMessage(msg, resultCode);
}
@Override
public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {
if (DBG) log("onSetDataProfileComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(CellularDataServiceCallback.this);
+ Message msg = mMessageMap.remove(asBinder());
sendCompleteMessage(msg, resultCode);
}
@@ -158,7 +162,7 @@
public void onGetDataCallListComplete(@DataServiceCallback.ResultCode int resultCode,
List<DataCallResponse> dataCallList) {
if (DBG) log("onGetDataCallListComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(CellularDataServiceCallback.this);
+ Message msg = mMessageMap.remove(asBinder());
sendCompleteMessage(msg, resultCode);
}
@@ -266,22 +270,28 @@
public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
boolean allowRoaming, int reason, LinkProperties linkProperties,
Message onCompleteMessage) {
+ if (DBG) log("setupDataCall");
if (!mBound) {
loge("Data service not bound.");
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
return;
}
- CellularDataServiceCallback callback = new CellularDataServiceCallback();
+ CellularDataServiceCallback callback = null;
+ if (onCompleteMessage != null) {
+ callback = new CellularDataServiceCallback();
+ mMessageMap.put(callback.asBinder(), onCompleteMessage);
+ }
try {
mIDataService.setupDataCall(mPhone.getPhoneId(), accessNetworkType, dataProfile,
isRoaming, allowRoaming, reason, linkProperties, callback);
} catch (RemoteException e) {
loge("Cannot invoke setupDataCall on data service.");
+ if (callback != null) {
+ mMessageMap.remove(callback.asBinder());
+ }
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
}
- mMessageMap.put(callback, onCompleteMessage);
}
/**
@@ -298,21 +308,27 @@
* care about the result.
*/
public void deactivateDataCall(int cid, int reason, Message onCompleteMessage) {
+ if (DBG) log("deactivateDataCall");
if (!mBound) {
loge("Data service not bound.");
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
return;
}
- CellularDataServiceCallback callback = new CellularDataServiceCallback();
+ CellularDataServiceCallback callback = null;
+ if (onCompleteMessage != null) {
+ callback = new CellularDataServiceCallback();
+ mMessageMap.put(callback.asBinder(), onCompleteMessage);
+ }
try {
mIDataService.deactivateDataCall(mPhone.getPhoneId(), cid, reason, callback);
} catch (RemoteException e) {
loge("Cannot invoke deactivateDataCall on data service.");
+ if (callback != null) {
+ mMessageMap.remove(callback.asBinder());
+ }
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
}
- mMessageMap.put(callback, onCompleteMessage);
}
/**
@@ -325,22 +341,28 @@
*/
public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
Message onCompleteMessage) {
+ if (DBG) log("setInitialAttachApn");
if (!mBound) {
loge("Data service not bound.");
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
return;
}
- CellularDataServiceCallback callback = new CellularDataServiceCallback();
+ CellularDataServiceCallback callback = null;
+ if (onCompleteMessage != null) {
+ callback = new CellularDataServiceCallback();
+ mMessageMap.put(callback.asBinder(), onCompleteMessage);
+ }
try {
mIDataService.setInitialAttachApn(mPhone.getPhoneId(), dataProfile, isRoaming,
callback);
} catch (RemoteException e) {
loge("Cannot invoke setInitialAttachApn on data service.");
+ if (callback != null) {
+ mMessageMap.remove(callback.asBinder());
+ }
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
}
- mMessageMap.put(callback, onCompleteMessage);
}
/**
@@ -355,21 +377,27 @@
*/
public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
Message onCompleteMessage) {
+ if (DBG) log("setDataProfile");
if (!mBound) {
loge("Data service not bound.");
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
return;
}
- CellularDataServiceCallback callback = new CellularDataServiceCallback();
+ CellularDataServiceCallback callback = null;
+ if (onCompleteMessage != null) {
+ callback = new CellularDataServiceCallback();
+ mMessageMap.put(callback.asBinder(), onCompleteMessage);
+ }
try {
mIDataService.setDataProfile(mPhone.getPhoneId(), dps, isRoaming, callback);
} catch (RemoteException e) {
loge("Cannot invoke setDataProfile on data service.");
+ if (callback != null) {
+ mMessageMap.remove(callback.asBinder());
+ }
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
}
- mMessageMap.put(callback, onCompleteMessage);
}
/**
@@ -379,21 +407,27 @@
* care about the result.
*/
public void getDataCallList(Message onCompleteMessage) {
+ if (DBG) log("getDataCallList");
if (!mBound) {
loge("Data service not bound.");
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
return;
}
- CellularDataServiceCallback callback = new CellularDataServiceCallback();
+ CellularDataServiceCallback callback = null;
+ if (onCompleteMessage != null) {
+ callback = new CellularDataServiceCallback();
+ mMessageMap.put(callback.asBinder(), onCompleteMessage);
+ }
try {
mIDataService.getDataCallList(mPhone.getPhoneId(), callback);
} catch (RemoteException e) {
loge("Cannot invoke getDataCallList on data service.");
+ if (callback != null) {
+ mMessageMap.remove(callback.asBinder());
+ }
sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
}
- mMessageMap.put(callback, onCompleteMessage);
}
/**
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index b4ceff6..8d05be7 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -26,6 +26,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.Message;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.PhoneStateListener;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
@@ -52,9 +53,10 @@
private static final boolean DBG = true;
private static final boolean VDBG = false;
- private Phone mPhone;
- private DcTracker mDct;
- private DcTesterDeactivateAll mDcTesterDeactivateAll;
+ private final Phone mPhone;
+ private final DcTracker mDct;
+ private final DataServiceManager mDataServiceManager;
+ private final DcTesterDeactivateAll mDcTesterDeactivateAll;
// package as its used by Testing code
// @GuardedBy("mDcListAll")
@@ -90,15 +92,17 @@
* @param name to be used for the Controller
* @param phone the phone associated with Dcc and Dct
* @param dct the DataConnectionTracker associated with Dcc
+ * @param dataServiceManager the data service manager that manages data services
* @param handler defines the thread/looper to be used with Dcc
*/
private DcController(String name, Phone phone, DcTracker dct,
- Handler handler) {
+ DataServiceManager dataServiceManager, Handler handler) {
super(name, handler);
setLogRecSize(300);
log("E ctor");
mPhone = phone;
mDct = dct;
+ mDataServiceManager = dataServiceManager;
addState(mDccDefaultState);
setInitialState(mDccDefaultState);
log("X ctor");
@@ -115,15 +119,19 @@
mNetworkPolicyManager = (NetworkPolicyManager) phone.getContext()
.getSystemService(Context.NETWORK_POLICY_SERVICE);
+ mDcTesterDeactivateAll = (Build.IS_DEBUGGABLE)
+ ? new DcTesterDeactivateAll(mPhone, DcController.this, getHandler())
+ : null;
+
if (mTelephonyManager != null) {
mTelephonyManager.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
}
}
- public static DcController makeDcc(Phone phone, DcTracker dct, Handler handler) {
- DcController dcc = new DcController("Dcc", phone, dct, handler);
- dcc.start();
+ public static DcController makeDcc(Phone phone, DcTracker dct,
+ DataServiceManager dataServiceManager, Handler handler) {
+ DcController dcc = new DcController("Dcc", phone, dct, dataServiceManager, handler);
return dcc;
}
@@ -192,14 +200,15 @@
private class DccDefaultState extends State {
@Override
public void enter() {
- mPhone.mCi.registerForRilConnected(getHandler(),
- DataConnection.EVENT_RIL_CONNECTED, null);
- mPhone.mCi.registerForDataCallListChanged(getHandler(),
- DataConnection.EVENT_DATA_STATE_CHANGED, null);
- if (Build.IS_DEBUGGABLE) {
- mDcTesterDeactivateAll =
- new DcTesterDeactivateAll(mPhone, DcController.this, getHandler());
+ if (mPhone != null && mDataServiceManager.getTransportType()
+ == TransportType.WWAN) {
+ mPhone.mCi.registerForRilConnected(getHandler(),
+ DataConnection.EVENT_RIL_CONNECTED, null);
}
+
+ mDataServiceManager.registerForDataCallListChanged(getHandler(),
+ DataConnection.EVENT_DATA_STATE_CHANGED);
+
if (mNetworkPolicyManager != null) {
mNetworkPolicyManager.registerListener(mListener);
}
@@ -207,10 +216,12 @@
@Override
public void exit() {
- if (mPhone != null) {
+ if (mPhone != null & mDataServiceManager.getTransportType()
+ == TransportType.WWAN) {
mPhone.mCi.unregisterForRilConnected(getHandler());
- mPhone.mCi.unregisterForDataCallListChanged(getHandler());
}
+ mDataServiceManager.unregisterForDataCallListChanged(getHandler());
+
if (mDcTesterDeactivateAll != null) {
mDcTesterDeactivateAll.dispose();
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index dd20592..eb6735b 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -54,6 +54,7 @@
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Telephony;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.PcoData;
@@ -563,14 +564,17 @@
private BroadcastReceiver mProvisionBroadcastReceiver;
private ProgressDialog mProvisioningSpinner;
- public boolean mImsRegistrationState = false;
+ private final DataServiceManager mDataServiceManager;
+
+ private final int mTransportType;
//***** Constructor
- public DcTracker(Phone phone) {
+ public DcTracker(Phone phone, int transportType) {
super();
mPhone = phone;
-
if (DBG) log("DCT.constructor");
+ mTransportType = transportType;
+ mDataServiceManager = new DataServiceManager(phone, transportType);
mResolver = mPhone.getContext().getContentResolver();
mUiccController = UiccController.getInstance();
@@ -601,7 +605,7 @@
HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
dcHandlerThread.start();
Handler dcHandler = new Handler(dcHandlerThread.getLooper());
- mDcc = DcController.makeDcc(mPhone, this, dcHandler);
+ mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
mDataConnectionTracker = this;
@@ -640,6 +644,8 @@
mProvisionActionName = null;
mSettingsObserver = new SettingsObserver(null, this);
mDataEnabledSettings = null;
+ mTransportType = 0;
+ mDataServiceManager = null;
}
public void registerServiceStateTrackerEvents() {
@@ -670,11 +676,13 @@
}
private void registerForAllEvents() {
- mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
- mPhone.mCi.registerForOffOrNotAvailable(this,
- DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCi.registerForDataCallListChanged(this,
- DctConstants.EVENT_DATA_STATE_CHANGED, null);
+ if (mTransportType == TransportType.WWAN) {
+ mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
+ mPhone.mCi.registerForOffOrNotAvailable(this,
+ DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
+ mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
+ }
+
// Note, this is fragile - the Phone is now presenting a merged picture
// of PS (volte) & CS and by diving into its internals you're just seeing
// the CS data. This works well for the purposes this is currently used for
@@ -685,12 +693,12 @@
mPhone.getCallTracker().registerForVoiceCallStarted(this,
DctConstants.EVENT_VOICE_CALL_STARTED, null);
registerServiceStateTrackerEvents();
- // SubscriptionManager.registerForDdsSwitch(this,
- // DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS, null);
mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
mPhone.getCarrierActionAgent().registerForCarrierAction(
CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
DctConstants.EVENT_SET_CARRIER_DATA_ENABLED, null, false);
+ mDataServiceManager.registerForServiceBindingChanged(this,
+ DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED, null);
}
public void dispose() {
@@ -732,37 +740,24 @@
private void unregisterForAllEvents() {
//Unregister for all events
- mPhone.mCi.unregisterForAvailable(this);
- mPhone.mCi.unregisterForOffOrNotAvailable(this);
+ if (mTransportType == TransportType.WWAN) {
+ mPhone.mCi.unregisterForAvailable(this);
+ mPhone.mCi.unregisterForOffOrNotAvailable(this);
+ mPhone.mCi.unregisterForPcoData(this);
+ }
+
IccRecords r = mIccRecords.get();
if (r != null) {
r.unregisterForRecordsLoaded(this);
mIccRecords.set(null);
}
- mPhone.mCi.unregisterForDataCallListChanged(this);
mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
unregisterServiceStateTrackerEvents();
- //SubscriptionManager.unregisterForDdsSwitch(this);
mPhone.mCi.unregisterForPcoData(this);
mPhone.getCarrierActionAgent().unregisterForCarrierAction(this,
CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED);
- }
-
- /**
- * Called when EVENT_RESET_DONE is received so goto
- * IDLE state and send notifications to those interested.
- *
- * TODO - currently unused. Needs to be hooked into DataConnection cleanup
- * TODO - needs to pass some notion of which connection is reset..
- */
- private void onResetDone(AsyncResult ar) {
- if (DBG) log("EVENT_RESET_DONE");
- String reason = null;
- if (ar.userObj instanceof String) {
- reason = (String) ar.userObj;
- }
- gotoIdleAndNotifyDataConnection(reason);
+ mDataServiceManager.unregisterForServiceBindingChanged(this);
}
/**
@@ -2080,7 +2075,7 @@
} else {
if (DBG) log("setInitialAttachApn: X selected Apn=" + initialAttachApnSetting);
- mPhone.mCi.setInitialAttachApn(createDataProfile(initialAttachApnSetting),
+ mDataServiceManager.setInitialAttachApn(createDataProfile(initialAttachApnSetting),
mPhone.getServiceState().getDataRoamingFromRegistration(), null);
}
}
@@ -2124,12 +2119,6 @@
return null;
}
- // TODO: For multiple Active APNs not exactly sure how to do this.
- private void gotoIdleAndNotifyDataConnection(String reason) {
- if (DBG) log("gotoIdleAndNotifyDataConnection: reason=" + reason);
- notifyDataConnection(reason);
- }
-
/**
* "Active" here means ApnContext isEnabled() and not in FAILED state
* @param apnContext to compare with
@@ -3277,7 +3266,7 @@
}
}
if (dps.size() > 0) {
- mPhone.mCi.setDataProfile(dps.toArray(new DataProfile[0]),
+ mDataServiceManager.setDataProfile(dps,
mPhone.getServiceState().getDataRoamingFromRegistration(), null);
}
}
@@ -3397,8 +3386,8 @@
if (DBG) log("createDataConnection E");
int id = mUniqueIdGenerator.getAndIncrement();
- DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
- this, mDcTesterFailBringUpAll, mDcc);
+ DataConnection conn = DataConnection.makeDataConnection(mPhone, id, this,
+ mDataServiceManager, mDcTesterFailBringUpAll, mDcc);
mDataConnections.put(id, conn);
DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
@@ -3783,12 +3772,6 @@
case DctConstants.EVENT_VOICE_CALL_ENDED:
onVoiceCallEnded();
break;
-
- case DctConstants.EVENT_RESET_DONE: {
- if (DBG) log("EVENT_RESET_DONE");
- onResetDone((AsyncResult) msg.obj);
- break;
- }
case DctConstants.CMD_SET_USER_DATA_ENABLE: {
final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
if (DBG) log("CMD_SET_USER_DATA_ENABLE enabled=" + enabled);
@@ -3933,11 +3916,6 @@
}
break;
}
- case DctConstants.EVENT_DATA_STATE_CHANGED: {
- // no longer do anything, but still registered - clean up log
- // TODO - why are we still registering?
- break;
- }
case DctConstants.EVENT_PCO_DATA_RECEIVED: {
handlePcoData((AsyncResult)msg.obj);
break;
@@ -3948,6 +3926,8 @@
case DctConstants.EVENT_DATA_RECONNECT:
onDataReconnect(msg.getData());
break;
+ case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
+ onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
default:
Rlog.e("DcTracker", "Unhandled event=" + msg);
break;
@@ -4571,36 +4551,37 @@
final int recoveryAction = getRecoveryAction();
TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
switch (recoveryAction) {
- case RecoveryAction.GET_DATA_CALL_LIST:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() get data call list");
- mPhone.mCi.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED));
- putRecoveryAction(RecoveryAction.CLEANUP);
- break;
- case RecoveryAction.CLEANUP:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv);
- if (DBG) log("doRecovery() cleanup all connections");
- cleanUpAllConnections(Phone.REASON_PDP_RESET);
- putRecoveryAction(RecoveryAction.REREGISTER);
- break;
- case RecoveryAction.REREGISTER:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() re-register");
- mPhone.getServiceStateTracker().reRegisterNetwork(null);
- putRecoveryAction(RecoveryAction.RADIO_RESTART);
- break;
- case RecoveryAction.RADIO_RESTART:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
- mSentSinceLastRecv);
- if (DBG) log("restarting radio");
- restartRadio();
- putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
- break;
- default:
- throw new RuntimeException("doRecovery: Invalid recoveryAction=" +
- recoveryAction);
+ case RecoveryAction.GET_DATA_CALL_LIST:
+ EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
+ mSentSinceLastRecv);
+ if (DBG) log("doRecovery() get data call list");
+ mDataServiceManager.getDataCallList(obtainMessage());
+ putRecoveryAction(RecoveryAction.CLEANUP);
+ break;
+ case RecoveryAction.CLEANUP:
+ EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP,
+ mSentSinceLastRecv);
+ if (DBG) log("doRecovery() cleanup all connections");
+ cleanUpAllConnections(Phone.REASON_PDP_RESET);
+ putRecoveryAction(RecoveryAction.REREGISTER);
+ break;
+ case RecoveryAction.REREGISTER:
+ EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
+ mSentSinceLastRecv);
+ if (DBG) log("doRecovery() re-register");
+ mPhone.getServiceStateTracker().reRegisterNetwork(null);
+ putRecoveryAction(RecoveryAction.RADIO_RESTART);
+ break;
+ case RecoveryAction.RADIO_RESTART:
+ EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
+ mSentSinceLastRecv);
+ if (DBG) log("restarting radio");
+ restartRadio();
+ putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST);
+ break;
+ default:
+ throw new RuntimeException("doRecovery: Invalid recoveryAction="
+ + recoveryAction);
}
mSentSinceLastRecv = 0;
}
@@ -4827,4 +4808,12 @@
apn.roamingProtocol, bearerBitmap, apn.mtu, apn.mvnoType, apn.mvnoMatchData,
apn.modemCognitive);
}
+
+ private void onDataServiceBindingChanged(boolean bound) {
+ if (bound) {
+ mDcc.start();
+ } else {
+ mDcc.dispose();
+ }
+ }
}
diff --git a/src/java/com/android/internal/telephony/ims/ImsConfigCompatAdapter.java b/src/java/com/android/internal/telephony/ims/ImsConfigCompatAdapter.java
new file mode 100644
index 0000000..90d415e
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsConfigCompatAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * 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.ims;
+
+import android.os.RemoteException;
+import android.telephony.ims.stub.ImsConfigImplBase;
+import android.util.Log;
+
+import com.android.ims.internal.IImsConfig;
+
+public class ImsConfigCompatAdapter extends ImsConfigImplBase {
+
+ private static final String TAG = "ImsConfigCompatAdapter";
+
+ private final IImsConfig mOldConfigInterface;
+
+ // Compat constants
+ public static final int UNKNOWN = -1;
+ public static final int SUCCESS = 0;
+ public static final int FAILED = 1;
+
+ public ImsConfigCompatAdapter(IImsConfig config) {
+ mOldConfigInterface = config;
+ }
+
+ @Override
+ public int setConfig(int item, int value) {
+ try {
+ if (mOldConfigInterface.setProvisionedValue(item, value) == SUCCESS) {
+ return CONFIG_RESULT_SUCCESS;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "setConfig: item=" + item + " value=" + value + "failed: "
+ + e.getMessage());
+ }
+ return CONFIG_RESULT_FAILED;
+ }
+
+ @Override
+ public int setConfig(int item, String value) {
+ try {
+ if (mOldConfigInterface.setProvisionedStringValue(item, value) == SUCCESS) {
+ return CONFIG_RESULT_SUCCESS;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "setConfig: item=" + item + " value=" + value + "failed: "
+ + e.getMessage());
+ }
+ return CONFIG_RESULT_FAILED;
+ }
+
+ @Override
+ public int getConfigInt(int item) {
+ try {
+ int value = mOldConfigInterface.getProvisionedValue(item);
+ if (value != UNKNOWN) {
+ return value;
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "getConfigInt: item=" + item + "failed: " + e.getMessage());
+ }
+ return CONFIG_RESULT_UNKNOWN;
+ }
+
+ @Override
+ public String getConfigString(int item) {
+ try {
+ return mOldConfigInterface.getProvisionedStringValue(item);
+ } catch (RemoteException e) {
+ Log.w(TAG, "getConfigInt: item=" + item + "failed: " + e.getMessage());
+ }
+ return null;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/ImsRegistrationCompatAdapter.java b/src/java/com/android/internal/telephony/ims/ImsRegistrationCompatAdapter.java
new file mode 100644
index 0000000..5a51fd7
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsRegistrationCompatAdapter.java
@@ -0,0 +1,114 @@
+/*
+ * 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.ims;
+
+import static android.telephony.ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
+import static android.telephony.ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+
+import android.net.Uri;
+import android.os.RemoteException;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.ArrayMap;
+
+import com.android.ims.internal.IImsRegistrationListener;
+
+import java.util.Map;
+
+public class ImsRegistrationCompatAdapter extends ImsRegistrationImplBase {
+
+ // Maps "RAT" based radio technologies to ImsRegistrationImplBase definitions.
+ private static final Map<Integer, Integer> RADIO_TECH_MAPPER = new ArrayMap<>(2);
+ static {
+ RADIO_TECH_MAPPER.put(RIL_RADIO_TECHNOLOGY_LTE, REGISTRATION_TECH_LTE);
+ RADIO_TECH_MAPPER.put(RIL_RADIO_TECHNOLOGY_IWLAN, REGISTRATION_TECH_IWLAN);
+ }
+
+ // Trampolines "old" listener events to the new interface.
+ private final IImsRegistrationListener mListener = new IImsRegistrationListener.Stub() {
+ @Override
+ public void registrationConnected() throws RemoteException {
+ onRegistered(REGISTRATION_TECH_NONE);
+ }
+
+ @Override
+ public void registrationProgressing() throws RemoteException {
+ onRegistering(REGISTRATION_TECH_NONE);
+ }
+
+ @Override
+ public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
+ onRegistered(RADIO_TECH_MAPPER.getOrDefault(imsRadioTech, REGISTRATION_TECH_NONE));
+ }
+
+ @Override
+ public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
+ onRegistering(RADIO_TECH_MAPPER.getOrDefault(imsRadioTech, REGISTRATION_TECH_NONE));
+ }
+
+ @Override
+ public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
+ onDeregistered(imsReasonInfo);
+ }
+
+ @Override
+ public void registrationResumed() throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationSuspended() throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationServiceCapabilityChanged(int serviceClass, int event)
+ throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
+ int[] disabledFeatures) throws RemoteException {
+ // Implemented in the MMTel Adapter
+ }
+
+ @Override
+ public void voiceMessageCountUpdate(int count) throws RemoteException {
+ // Implemented in the MMTel Adapter
+ }
+
+ @Override
+ public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
+ onSubscriberAssociatedUriChanged(uris);
+ }
+
+ @Override
+ public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
+ throws RemoteException {
+ onTechnologyChangeFailed(RADIO_TECH_MAPPER.getOrDefault(targetAccessTech,
+ REGISTRATION_TECH_NONE), imsReasonInfo);
+ }
+ };
+
+ /**
+ * Need access to the listener in order to register for events in MMTelFeature adapter
+ */
+ public IImsRegistrationListener getRegistrationListener() {
+ return mListener;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index bb785e6..a7eac71 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -32,6 +32,11 @@
import android.os.UserHandle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsService;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.feature.ImsFeature;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -39,9 +44,6 @@
import android.util.Pair;
import android.util.SparseArray;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsRcsFeature;
-import com.android.ims.internal.IImsRegistration;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneConstants;
@@ -72,7 +74,6 @@
private static final String TAG = "ImsResolver";
- public static final String SERVICE_INTERFACE = "android.telephony.ims.ImsService";
public static final String METADATA_EMERGENCY_MMTEL_FEATURE =
"android.telephony.ims.EMERGENCY_MMTEL_FEATURE";
public static final String METADATA_MMTEL_FEATURE = "android.telephony.ims.MMTEL_FEATURE";
@@ -93,6 +94,8 @@
public static class ImsServiceInfo {
public ComponentName name;
public Set<Integer> supportedFeatures;
+ public boolean supportsEmergencyMmTel = false;
+ public ImsServiceControllerFactory controllerFactory;
@Override
public boolean equals(Object o) {
@@ -102,15 +105,19 @@
ImsServiceInfo that = (ImsServiceInfo) o;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
- return supportedFeatures != null ? supportedFeatures.equals(that.supportedFeatures)
- : that.supportedFeatures == null;
-
+ if (supportedFeatures != null ? !supportedFeatures.equals(that.supportedFeatures)
+ : that.supportedFeatures != null) {
+ return false;
+ }
+ return controllerFactory != null ? controllerFactory.equals(that.controllerFactory)
+ : that.controllerFactory == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (supportedFeatures != null ? supportedFeatures.hashCode() : 0);
+ result = 31 * result + (controllerFactory != null ? controllerFactory.hashCode() : 0);
return result;
}
}
@@ -195,14 +202,59 @@
@VisibleForTesting
public interface ImsServiceControllerFactory {
/**
- * Returns the ImsServiceController created usiing the context and componentName supplied.
- * Used for DI when testing.
+ * @return the Service Interface String used for binding the ImsService.
*/
- ImsServiceController get(Context context, ComponentName componentName);
+ String getServiceInterface();
+ /**
+ * @return the ImsServiceController created using the context and componentName supplied.
+ */
+ ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks);
}
- private ImsServiceControllerFactory mImsServiceControllerFactory = (context, componentName) ->
- new ImsServiceController(context, componentName, this);
+ private ImsServiceControllerFactory mImsServiceControllerFactory =
+ new ImsServiceControllerFactory() {
+
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ return new ImsServiceController(context, componentName, callbacks);
+ }
+ };
+
+ private ImsServiceControllerFactory mImsServiceControllerFactoryCompat =
+ new ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return android.telephony.ims.compat.ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ return new ImsServiceControllerCompat(context, componentName, callbacks);
+ }
+ };
+
+ private ImsServiceControllerFactory mImsServiceControllerFactoryStaticBindingCompat =
+ new ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ // The static method of binding does not use service interfaces.
+ return null;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ return new ImsServiceControllerStaticCompat(context, componentName, callbacks);
+ }
+ };
private final CarrierConfigManager mCarrierConfigManager;
private final Context mContext;
@@ -210,6 +262,7 @@
// ImsServiceController callbacks.
private final Object mBoundServicesLock = new Object();
private final int mNumSlots;
+ private final boolean mIsDynamicBinding;
// Synchronize all messages on a handler to ensure that the cache includes the most recent
// version of the installed ImsServices.
@@ -247,27 +300,40 @@
private Set<ImsServiceInfo> mInstalledServicesCache = new ArraySet<>();
// not locked, only accessed on a handler thread.
private Set<ImsServiceController> mActiveControllers = new ArraySet<>();
+ // Only used as the
+ private final ComponentName mStaticComponent;
- public ImsResolver(Context context, String defaultImsPackageName, int numSlots) {
+ public ImsResolver(Context context, String defaultImsPackageName, int numSlots,
+ boolean isDynamicBinding) {
mContext = context;
mDeviceService = defaultImsPackageName;
mNumSlots = numSlots;
+ mIsDynamicBinding = isDynamicBinding;
+ mStaticComponent = new ComponentName(mContext, ImsResolver.class);
+ if (!mIsDynamicBinding) {
+ Log.i(TAG, "ImsResolver initialized with static binding.");
+ mDeviceService = mStaticComponent.getPackageName();
+ }
mCarrierConfigManager = (CarrierConfigManager) mContext.getSystemService(
Context.CARRIER_CONFIG_SERVICE);
mCarrierServices = new String[numSlots];
mBoundImsServicesByFeature = Stream.generate(SparseArray<ImsServiceController>::new)
.limit(mNumSlots).collect(Collectors.toList());
- IntentFilter appChangedFilter = new IntentFilter();
- appChangedFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- appChangedFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- appChangedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- appChangedFilter.addDataScheme("package");
- context.registerReceiverAsUser(mAppChangedReceiver, UserHandle.ALL, appChangedFilter, null,
- null);
+ // Only register for Package/CarrierConfig updates if dynamic binding.
+ if(mIsDynamicBinding) {
+ IntentFilter appChangedFilter = new IntentFilter();
+ appChangedFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ appChangedFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ appChangedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ appChangedFilter.addDataScheme("package");
+ context.registerReceiverAsUser(mAppChangedReceiver, UserHandle.ALL, appChangedFilter,
+ null,
+ null);
- context.registerReceiver(mConfigChangedReceiver, new IntentFilter(
- CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ context.registerReceiver(mConfigChangedReceiver, new IntentFilter(
+ CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+ }
}
@VisibleForTesting
@@ -298,51 +364,62 @@
}
/**
- * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id or {@link null} if
+ * Notify ImsService to enable IMS for the framework. This will trigger IMS registration and
+ * trigger ImsFeature status updates.
+ */
+ public void enableIms(int slotId) {
+ SparseArray<ImsServiceController> controllers = getImsServiceControllers(slotId);
+ if (controllers != null) {
+ for (int i = 0; i < controllers.size(); i++) {
+ int key = controllers.keyAt(i);
+ controllers.get(key).enableIms(slotId);
+ }
+ }
+ }
+
+ /**
+ * Notify ImsService to disable IMS for the framework. This will trigger IMS de-registration and
+ * trigger ImsFeature capability status to become false.
+ */
+ public void disableIms(int slotId) {
+ SparseArray<ImsServiceController> controllers = getImsServiceControllers(slotId);
+ if (controllers != null) {
+ for (int i = 0; i < controllers.size(); i++) {
+ int key = controllers.keyAt(i);
+ controllers.get(key).disableIms(slotId);
+ }
+ }
+ }
+
+ /**
+ * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id or {@link null} if
* the service is not available. If an IImsMMTelFeature is available, the
* {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
- * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
+ * @param slotId The SIM slot that we are requesting the {@link IImsMmTelFeature} for.
* @param callback Listener that will send updates to ImsManager when there are updates to
* the feature.
- * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
+ * @return {@link IImsMmTelFeature} interface or {@link null} if it is unavailable.
*/
- public IImsMMTelFeature getMMTelFeatureAndListen(int slotId,
- IImsServiceFeatureCallback callback) {
- ImsServiceController controller = getImsServiceControllerAndListen(slotId, ImsFeature.MMTEL,
- callback);
- return (controller != null) ? controller.getMMTelFeature(slotId) : null;
- }
-
- /**
- * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id for emergency
- * calling or {@link null} if the service is not available. If an IImsMMTelFeature is
- * available, the {@link IImsServiceFeatureCallback} callback is registered as a listener for
- * feature updates.
- * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
- * @param callback listener that will send updates to ImsManager when there are updates to
- * the feature.
- * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
- */
- public IImsMMTelFeature getEmergencyMMTelFeatureAndListen(int slotId,
+ public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
IImsServiceFeatureCallback callback) {
ImsServiceController controller = getImsServiceControllerAndListen(slotId,
- ImsFeature.EMERGENCY_MMTEL, callback);
- return (controller != null) ? controller.getEmergencyMMTelFeature(slotId) : null;
+ ImsFeature.FEATURE_MMTEL, callback);
+ return (controller != null) ? controller.getMmTelFeature(slotId) : null;
}
/**
- * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id for emergency
+ * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for emergency
* calling or {@link null} if the service is not available. If an IImsMMTelFeature is
* available, the {@link IImsServiceFeatureCallback} callback is registered as a listener for
* feature updates.
- * @param slotId The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
+ * @param slotId The SIM slot that we are requesting the {@link IImsRcsFeature} for.
* @param callback listener that will send updates to ImsManager when there are updates to
* the feature.
- * @return {@link IImsMMTelFeature} interface or {@link null} if it is unavailable.
+ * @return {@link IImsRcsFeature} interface or {@link null} if it is unavailable.
*/
public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
- ImsServiceController controller = getImsServiceControllerAndListen(slotId, ImsFeature.RCS,
- callback);
+ ImsServiceController controller = getImsServiceControllerAndListen(slotId,
+ ImsFeature.FEATURE_RCS, callback);
return (controller != null) ? controller.getRcsFeature(slotId) : null;
}
@@ -358,6 +435,18 @@
return null;
}
+ /**
+ * Returns the ImsConfig structure associated with the slotId and feature specified.
+ */
+ public @Nullable IImsConfig getImsConfig(int slotId, int feature)
+ throws RemoteException {
+ ImsServiceController controller = getImsServiceController(slotId, feature);
+ if (controller != null) {
+ return controller.getConfig(slotId);
+ }
+ return null;
+ }
+
@VisibleForTesting
public ImsServiceController getImsServiceController(int slotId, int feature) {
if (slotId < 0 || slotId >= mNumSlots) {
@@ -374,6 +463,19 @@
return controller;
}
+ private SparseArray<ImsServiceController> getImsServiceControllers(int slotId) {
+ if (slotId < 0 || slotId >= mNumSlots) {
+ return null;
+ }
+ synchronized (mBoundServicesLock) {
+ SparseArray<ImsServiceController> services = mBoundImsServicesByFeature.get(slotId);
+ if (services == null) {
+ return null;
+ }
+ return services;
+ }
+ }
+
@VisibleForTesting
public ImsServiceController getImsServiceControllerAndListen(int slotId, int feature,
IImsServiceFeatureCallback callback) {
@@ -387,8 +489,8 @@
}
private void putImsController(int slotId, int feature, ImsServiceController controller) {
- if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.INVALID
- || feature >= ImsFeature.MAX) {
+ if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.FEATURE_INVALID
+ || feature >= ImsFeature.FEATURE_MAX) {
Log.w(TAG, "putImsController received invalid parameters - slot: " + slotId
+ ", feature: " + feature);
return;
@@ -406,8 +508,8 @@
}
private ImsServiceController removeImsController(int slotId, int feature) {
- if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.INVALID
- || feature >= ImsFeature.MAX) {
+ if (slotId < 0 || slotId >= mNumSlots || feature <= ImsFeature.FEATURE_INVALID
+ || feature >= ImsFeature.FEATURE_MAX) {
Log.w(TAG, "removeImsController received invalid parameters - slot: " + slotId
+ ", feature: " + feature);
return null;
@@ -427,7 +529,6 @@
}
}
-
// Update the current cache with the new ImsService(s) if it has been added or update the
// supported IMS features if they have changed.
// Called from the handler ONLY
@@ -568,7 +669,7 @@
if (info == null) {
return;
}
- ImsServiceController controller = mImsServiceControllerFactory.get(mContext, info.name);
+ ImsServiceController controller = info.controllerFactory.create(mContext, info.name, this);
HashSet<Pair<Integer, Integer>> features = calculateFeaturesToCreate(info);
// Only bind if there are features that will be created by the service.
if (features.size() > 0) {
@@ -710,8 +811,36 @@
// get all packages that support ImsServices.
private List<ImsServiceInfo> getImsServiceInfo(String packageName) {
List<ImsServiceInfo> infos = new ArrayList<>();
+ if (!mIsDynamicBinding) {
+ // always return the same ImsService info.
+ infos.addAll(getStaticImsService());
+ } else {
+ // Search for Current ImsService implementations
+ infos.addAll(searchForImsServices(packageName, mImsServiceControllerFactory));
+ // Search for compat ImsService Implementations
+ infos.addAll(searchForImsServices(packageName, mImsServiceControllerFactoryCompat));
+ }
+ return infos;
+ }
- Intent serviceIntent = new Intent(SERVICE_INTERFACE);
+ private List<ImsServiceInfo> getStaticImsService() {
+ List<ImsServiceInfo> infos = new ArrayList<>();
+
+ ImsServiceInfo info = new ImsServiceInfo();
+ info.name = mStaticComponent;
+ info.supportedFeatures = new HashSet<>(ImsFeature.FEATURE_MAX);
+ info.controllerFactory = mImsServiceControllerFactoryStaticBindingCompat;
+ info.supportsEmergencyMmTel = true;
+ info.supportedFeatures.add(ImsFeature.FEATURE_MMTEL);
+ infos.add(info);
+ return infos;
+ }
+
+ private List<ImsServiceInfo> searchForImsServices(String packageName,
+ ImsServiceControllerFactory controllerFactory) {
+ List<ImsServiceInfo> infos = new ArrayList<>();
+
+ Intent serviceIntent = new Intent(controllerFactory.getServiceInterface());
serviceIntent.setPackage(packageName);
PackageManager packageManager = mContext.getPackageManager();
@@ -724,25 +853,26 @@
if (serviceInfo != null) {
ImsServiceInfo info = new ImsServiceInfo();
info.name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
- info.supportedFeatures = new HashSet<>(ImsFeature.MAX);
+ info.supportedFeatures = new HashSet<>(ImsFeature.FEATURE_MAX);
+ info.controllerFactory = controllerFactory;
// Add all supported features
if (serviceInfo.metaData != null) {
if (serviceInfo.metaData.getBoolean(METADATA_EMERGENCY_MMTEL_FEATURE, false)) {
- info.supportedFeatures.add(ImsFeature.EMERGENCY_MMTEL);
+ info.supportsEmergencyMmTel = true;
}
if (serviceInfo.metaData.getBoolean(METADATA_MMTEL_FEATURE, false)) {
- info.supportedFeatures.add(ImsFeature.MMTEL);
+ info.supportedFeatures.add(ImsFeature.FEATURE_MMTEL);
}
if (serviceInfo.metaData.getBoolean(METADATA_RCS_FEATURE, false)) {
- info.supportedFeatures.add(ImsFeature.RCS);
+ info.supportedFeatures.add(ImsFeature.FEATURE_RCS);
}
}
// Check manifest permission to be sure that the service declares the correct
// permissions.
if (TextUtils.equals(serviceInfo.permission,
Manifest.permission.BIND_IMS_SERVICE)) {
- Log.d(TAG, "ImsService added to cache: " + info.name + " with features: "
- + info.supportedFeatures);
+ Log.d(TAG, "ImsService (" + serviceIntent + ") added to cache: "
+ + info.name + " with features: " + info.supportedFeatures);
infos.add(info);
} else {
Log.w(TAG, "ImsService does not have 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 284c9de..34fcb81 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -27,15 +27,17 @@
import android.os.IInterface;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.ims.ImsService;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsServiceController;
import android.telephony.ims.feature.ImsFeature;
import android.util.Log;
import android.util.Pair;
import com.android.ims.internal.IImsFeatureStatusCallback;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsRcsFeature;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsServiceController;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ExponentialBackoff;
@@ -94,7 +96,7 @@
try {
service.linkToDeath(mImsDeathRecipient, 0);
mImsServiceControllerBinder = service;
- mIImsServiceController = IImsServiceController.Stub.asInterface(service);
+ setServiceController(service);
// create all associated features in the ImsService
for (Pair<Integer, Integer> i : mImsFeatures) {
addImsServiceFeature(i);
@@ -118,7 +120,7 @@
synchronized (mLock) {
mIsBinding = false;
}
- if (mIImsServiceController != null) {
+ if (isServiceControllerAvailable()) {
mImsServiceControllerBinder.unlinkToDeath(mImsDeathRecipient, 0);
}
notifyAllFeaturesRemoved();
@@ -164,9 +166,7 @@
private static final String LOG_TAG = "ImsServiceController";
private static final int REBIND_START_DELAY_MS = 2 * 1000; // 2 seconds
private static final int REBIND_MAXIMUM_DELAY_MS = 60 * 1000; // 1 minute
- private final Context mContext;
private final ComponentName mComponentName;
- private final Object mLock = new Object();
private final HandlerThread mHandlerThread = new HandlerThread("ImsServiceControllerHandler");
private final IPackageManager mPackageManager;
private ImsServiceControllerCallbacks mCallbacks;
@@ -187,6 +187,9 @@
// Only added or removed, never accessed on purpose.
private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>();
+ protected final Object mLock = new Object();
+ protected final Context mContext;
+
private class ImsFeatureContainer {
public int slotId;
public int featureType;
@@ -324,15 +327,19 @@
if (!mIsBound && !mIsBinding) {
mIsBinding = true;
mImsFeatures = imsFeatureSet;
- Intent imsServiceIntent = new Intent(ImsResolver.SERVICE_INTERFACE).setComponent(
+ Intent imsServiceIntent = new Intent(getServiceInterface()).setComponent(
mComponentName);
mImsServiceConnection = new ImsServiceConnection();
int serviceFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
| Context.BIND_IMPORTANT;
Log.i(LOG_TAG, "Binding ImsService:" + mComponentName);
try {
- return mContext.bindService(imsServiceIntent, mImsServiceConnection,
- serviceFlags);
+ boolean bindSucceeded = startBindToService(imsServiceIntent,
+ mImsServiceConnection, serviceFlags);
+ if (!bindSucceeded) {
+ mBackoff.notifyFailed();
+ }
+ return bindSucceeded;
} catch (Exception e) {
mBackoff.notifyFailed();
Log.e(LOG_TAG, "Error binding (" + mComponentName + ") with exception: "
@@ -347,6 +354,15 @@
}
/**
+ * Starts the bind to the ImsService. Overridden by subclasses that need to access the service
+ * in a different fashion.
+ */
+ protected boolean startBindToService(Intent intent, ImsServiceConnection connection,
+ int flags) {
+ return mContext.bindService(intent, connection, flags);
+ }
+
+ /**
* Calls {@link IImsServiceController#removeImsFeature} on all features that the
* ImsService supports and then unbinds the service.
*/
@@ -421,33 +437,34 @@
}
}
- /**
- * Return the {@Link MMTelFeature} binder on the slot associated with the slotId.
- * Used for normal calling.
- */
- public IImsMMTelFeature getMMTelFeature(int slotId) {
- synchronized (mLock) {
- ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.MMTEL);
- if (f == null) {
- Log.w(LOG_TAG, "Requested null MMTelFeature on slot " + slotId);
- return null;
- }
- return f.resolve(IImsMMTelFeature.class);
+ public void enableIms(int slotId) {
+ try {
+ mIImsServiceController.enableIms(slotId);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Couldn't enable IMS: " + e.getMessage());
+ }
+ }
+
+ public void disableIms(int slotId) {
+ try {
+ mIImsServiceController.disableIms(slotId);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Couldn't disable IMS: " + e.getMessage());
}
}
/**
* Return the {@Link MMTelFeature} binder on the slot associated with the slotId.
- * Used for emergency calling only.
+ * Used for normal calling.
*/
- public IImsMMTelFeature getEmergencyMMTelFeature(int slotId) {
+ public IImsMmTelFeature getMmTelFeature(int slotId) {
synchronized (mLock) {
- ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.EMERGENCY_MMTEL);
+ ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.FEATURE_MMTEL);
if (f == null) {
- Log.w(LOG_TAG, "Requested null Emergency MMTelFeature on slot " + slotId);
+ Log.w(LOG_TAG, "Requested null MMTelFeature on slot " + slotId);
return null;
}
- return f.resolve(IImsMMTelFeature.class);
+ return f.resolve(IImsMmTelFeature.class);
}
}
@@ -456,7 +473,7 @@
*/
public IImsRcsFeature getRcsFeature(int slotId) {
synchronized (mLock) {
- ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.RCS);
+ ImsFeatureContainer f = getImsFeatureContainer(slotId, ImsFeature.FEATURE_RCS);
if (f == null) {
Log.w(LOG_TAG, "Requested null RcsFeature on slot " + slotId);
return null;
@@ -474,6 +491,35 @@
}
}
+ /**
+ * @return the IImsConfig that corresponds to the slot id specified.
+ */
+ public IImsConfig getConfig(int slotId) throws RemoteException {
+ synchronized (mLock) {
+ return mIImsServiceController.getConfig(slotId);
+ }
+ }
+
+ protected String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ /**
+ * Sets the IImsServiceController instance. Overridden by compat layers to set compatibility
+ * versions of this service controller.
+ */
+ protected void setServiceController(IBinder serviceController) {
+ mIImsServiceController = IImsServiceController.Stub.asInterface(serviceController);
+ }
+
+ /**
+ * Check to see if the service controller is available, overridden for compat versions,
+ * @return true if available, false otherwise;
+ */
+ protected boolean isServiceControllerAvailable() {
+ return mIImsServiceController != null;
+ }
+
private void removeImsServiceFeatureListener() {
synchronized (mLock) {
mImsStatusCallbacks.clear();
@@ -553,7 +599,7 @@
// This method should only be called when synchronized on mLock
private void addImsServiceFeature(Pair<Integer, Integer> featurePair) throws RemoteException {
- if (mIImsServiceController == null || mCallbacks == null) {
+ if (!isServiceControllerAvailable() || mCallbacks == null) {
Log.w(LOG_TAG, "addImsServiceFeature called with null values.");
return;
}
@@ -571,7 +617,7 @@
// This method should only be called when synchronized on mLock
private void removeImsServiceFeature(Pair<Integer, Integer> featurePair)
throws RemoteException {
- if (mIImsServiceController == null || mCallbacks == null) {
+ if (!isServiceControllerAvailable() || mCallbacks == null) {
Log.w(LOG_TAG, "removeImsServiceFeature called with null values.");
return;
}
@@ -582,7 +628,7 @@
if (callbackToRemove != null) {
mFeatureStatusCallbacks.remove(callbackToRemove);
}
- mIImsServiceController.removeImsFeature(featurePair.first, featurePair.second,
+ removeImsFeature(featurePair.first, featurePair.second,
(callbackToRemove != null ? callbackToRemove.getCallback() : null));
removeImsFeatureBinder(featurePair.first, featurePair.second);
// Signal ImsResolver to change supported ImsFeatures for this ImsServiceController
@@ -594,17 +640,15 @@
sendImsFeatureRemovedCallback(featurePair.first, featurePair.second);
}
- // This method should only be called when already synchronized on mLock;
- private IInterface createImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
+ // This method should only be called when already synchronized on mLock.
+ // overridden by compat layer to create features
+ protected IInterface createImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
throws RemoteException {
switch (featureType) {
- case ImsFeature.EMERGENCY_MMTEL: {
- return mIImsServiceController.createEmergencyMMTelFeature(slotId, c);
+ case ImsFeature.FEATURE_MMTEL: {
+ return mIImsServiceController.createMmTelFeature(slotId, c);
}
- case ImsFeature.MMTEL: {
- return mIImsServiceController.createMMTelFeature(slotId, c);
- }
- case ImsFeature.RCS: {
+ case ImsFeature.FEATURE_RCS: {
return mIImsServiceController.createRcsFeature(slotId, c);
}
default:
@@ -612,6 +656,12 @@
}
}
+ // overridden by compat layer to remove features
+ protected void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ mIImsServiceController.removeImsFeature(slotId, featureType, c);
+ }
+
// This method should only be called when synchronized on mLock
private void addImsFeatureBinder(int slotId, int featureType, IInterface b) {
mImsFeatureBinders.add(new ImsFeatureContainer(slotId, featureType, b));
@@ -651,7 +701,7 @@
mImsDeathRecipient = null;
mImsServiceConnection = null;
mImsServiceControllerBinder = null;
- mIImsServiceController = null;
+ setServiceController(null);
mIsBound = false;
}
}
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java
new file mode 100644
index 0000000..094be71
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java
@@ -0,0 +1,191 @@
+/*
+ * 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.ims;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.compat.ImsService;
+import android.telephony.ims.compat.feature.ImsFeature;
+import android.telephony.ims.compat.feature.MMTelFeature;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.ims.internal.IImsFeatureStatusCallback;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsServiceController;
+
+/**
+ * Manages the Binding lifecycle of one ImsService as well as the relevant ImsFeatures that the
+ * ImsService will support.
+ *
+ * Compatibility interface for interacting with older implementations of ImsService. The older
+ * ImsService implementation is contained within the android.telephony.ims.compat.* namspace.
+ * Newer implementations of ImsService should use the current APIs contained in
+ * android.telephony.ims.compat.*.
+ */
+public class ImsServiceControllerCompat extends ImsServiceController {
+
+ private static final String TAG = "ImsSCCompat";
+
+ private IImsServiceController mServiceController;
+
+ private final SparseArray<MmTelFeatureCompatAdapter> mMmTelCompatAdapters = new SparseArray<>();
+ private final SparseArray<ImsConfigCompatAdapter> mConfigCompatAdapters = new SparseArray<>();
+ private final SparseArray<ImsRegistrationCompatAdapter> mRegCompatAdapters =
+ new SparseArray<>();
+
+ public ImsServiceControllerCompat(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ super(context, componentName, callbacks);
+ }
+
+ @Override
+ protected String getServiceInterface() {
+ // Return compatibility version of String.
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ /**
+ * Converts the new command to {@link MMTelFeature#turnOnIms()}.
+ */
+ @Override
+ public void enableIms(int slotId) {
+ MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId);
+ if (adapter == null) {
+ Log.w(TAG, "enableIms: adapter null for slot :" + slotId);
+ return;
+ }
+ try {
+ adapter.enableIms();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Couldn't enable IMS: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Converts the new command to {@link MMTelFeature#turnOffIms()}.
+ */
+ @Override
+ public void disableIms(int slotId) {
+ MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId);
+ if (adapter == null) {
+ Log.w(TAG, "enableIms: adapter null for slot :" + slotId);
+ return;
+ }
+ try {
+ adapter.disableIms();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Couldn't enable IMS: " + e.getMessage());
+ }
+ }
+
+ /**
+ * @return the IImsRegistration that corresponds to the slot id specified.
+ */
+ public IImsRegistration getRegistration(int slotId) throws RemoteException {
+ ImsRegistrationCompatAdapter adapter = mRegCompatAdapters.get(slotId);
+ if (adapter == null) {
+ Log.w(TAG, "getRegistration: Registration does not exist for slot " + slotId);
+ return null;
+ }
+ return adapter.getBinder();
+ }
+
+ /**
+ * @return the IImsConfig that corresponds to the slot id specified.
+ */
+ public IImsConfig getConfig(int slotId) throws RemoteException {
+ ImsConfigCompatAdapter adapter = mConfigCompatAdapters.get(slotId);
+ if (adapter == null) {
+ Log.w(TAG, "getConfig: Config does not exist for slot " + slotId);
+ return null;
+ }
+ return adapter.getIImsConfig();
+ }
+
+ @Override
+ protected IInterface createImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ switch (featureType) {
+ case ImsFeature.MMTEL: {
+ return createMMTelCompat(slotId, c);
+ }
+ case ImsFeature.RCS: {
+ return createRcsFeature(slotId, c);
+ }
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ protected void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ if (featureType == ImsFeature.MMTEL) {
+ mMmTelCompatAdapters.remove(slotId);
+ mRegCompatAdapters.remove(slotId);
+ mConfigCompatAdapters.remove(slotId);
+ }
+ mServiceController.removeImsFeature(slotId, featureType, c);
+ }
+
+ @Override
+ protected void setServiceController(IBinder serviceController) {
+ mServiceController = IImsServiceController.Stub.asInterface(serviceController);
+ }
+
+ @Override
+ protected boolean isServiceControllerAvailable() {
+ return mServiceController != null;
+ }
+
+ protected MmTelInterfaceAdapter getInterface(int slotId, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ IImsMMTelFeature feature = mServiceController.createMMTelFeature(slotId, c);
+ if (feature == null) {
+ Log.w(TAG, "createMMTelCompat: createMMTelFeature returned null.");
+ return null;
+ }
+ return new MmTelInterfaceAdapter(slotId, feature.asBinder());
+ }
+
+ private IImsMmTelFeature createMMTelCompat(int slotId, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ MmTelInterfaceAdapter interfaceAdapter = getInterface(slotId, c);
+ MmTelFeatureCompatAdapter mmTelAdapter = new MmTelFeatureCompatAdapter(mContext, slotId,
+ interfaceAdapter);
+ mMmTelCompatAdapters.put(slotId, mmTelAdapter);
+ ImsRegistrationCompatAdapter regAdapter = new ImsRegistrationCompatAdapter();
+ mmTelAdapter.addRegistrationAdapter(regAdapter);
+ mRegCompatAdapters.put(slotId, regAdapter);
+ mConfigCompatAdapters.put(slotId, new ImsConfigCompatAdapter(
+ mmTelAdapter.getOldConfigInterface()));
+ return mmTelAdapter.getBinder();
+ }
+
+ private IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) {
+ // Return non-null if there is a custom RCS implementation that needs a compatability layer.
+ return null;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceControllerStaticCompat.java b/src/java/com/android/internal/telephony/ims/ImsServiceControllerStaticCompat.java
new file mode 100644
index 0000000..5b080d1
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceControllerStaticCompat.java
@@ -0,0 +1,77 @@
+/*
+ * 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.ims;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.ims.internal.IImsFeatureStatusCallback;
+import com.android.ims.internal.IImsService;
+
+/**
+ * A compat layer for communicating with older devices that still used the ServiceManager to get
+ * the ImsService.
+ */
+
+public class ImsServiceControllerStaticCompat extends ImsServiceControllerCompat {
+
+ private static final String TAG = "ImsSCStaticCompat";
+
+ private static final String IMS_SERVICE_NAME = "ims";
+
+ private IImsService mImsServiceCompat = null;
+
+ public ImsServiceControllerStaticCompat(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ super(context, componentName, callbacks);
+ }
+
+ @Override
+ public boolean startBindToService(Intent intent, ImsServiceConnection connection, int flags) {
+ IBinder binder = ServiceManager.checkService(IMS_SERVICE_NAME);
+
+ if (binder == null) {
+ return false;
+ }
+ // This is a little hacky, but we are going to call the onServiceConnected to "pretend" like
+ // bindService has completed here, which will pass the binder to setServiceController and
+ // set up all supporting structures.
+ connection.onServiceConnected(new ComponentName(mContext,
+ ImsServiceControllerStaticCompat.class), binder);
+ return true;
+ }
+
+ @Override
+ protected void setServiceController(IBinder serviceController) {
+ mImsServiceCompat = IImsService.Stub.asInterface(serviceController);
+ }
+
+ @Override
+ protected MmTelInterfaceAdapter getInterface(int slotId, IImsFeatureStatusCallback c)
+ throws RemoteException {
+ if (mImsServiceCompat == null) {
+ Log.w(TAG, "getInterface: IImsService returned null.");
+ return null;
+ }
+ return new ImsServiceInterfaceAdapter(slotId, mImsServiceCompat.asBinder());
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceInterfaceAdapter.java b/src/java/com/android/internal/telephony/ims/ImsServiceInterfaceAdapter.java
new file mode 100644
index 0000000..f554e6f
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceInterfaceAdapter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.ims;
+
+import android.app.PendingIntent;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.compat.feature.ImsFeature;
+
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.IImsConfig;
+import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMultiEndpoint;
+import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsService;
+import com.android.ims.internal.IImsUt;
+
+/**
+ * Compatibility layer for IImsService implementations of IMS. Converts "generic" MMTel commands
+ * to implementation.
+ */
+
+public class ImsServiceInterfaceAdapter extends MmTelInterfaceAdapter {
+
+ private static final int SERVICE_ID = ImsFeature.MMTEL;
+
+ public ImsServiceInterfaceAdapter(int slotId, IBinder binder) {
+ super(slotId, binder);
+ }
+
+ public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
+ throws RemoteException {
+ return getInterface().open(mSlotId, ImsFeature.MMTEL, incomingCallIntent, listener);
+ }
+
+ public void endSession(int sessionId) throws RemoteException {
+ getInterface().close(sessionId);
+ }
+
+ public boolean isConnected(int callSessionType, int callType) throws RemoteException {
+ return getInterface().isConnected(SERVICE_ID, callSessionType, callType);
+ }
+
+ public boolean isOpened() throws RemoteException {
+ return getInterface().isOpened(SERVICE_ID);
+ }
+
+ public int getFeatureState() throws RemoteException {
+ return ImsFeature.STATE_READY;
+ }
+
+ public void addRegistrationListener(IImsRegistrationListener listener) throws RemoteException {
+ getInterface().addRegistrationListener(mSlotId, ImsFeature.MMTEL, listener);
+ }
+
+ public void removeRegistrationListener(IImsRegistrationListener listener)
+ throws RemoteException {
+ // Not Implemented in the old ImsService. If the registration listener becomes invalid, the
+ // ImsService will remove it.
+ }
+
+ public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType)
+ throws RemoteException {
+ return getInterface().createCallProfile(sessionId, callSessionType, callType);
+ }
+
+ public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
+ throws RemoteException {
+ return getInterface().createCallSession(sessionId, profile, null);
+ }
+
+ public IImsCallSession getPendingCallSession(int sessionId, String callId)
+ throws RemoteException {
+ return getInterface().getPendingCallSession(sessionId, callId);
+ }
+
+ public IImsUt getUtInterface() throws RemoteException {
+ return getInterface().getUtInterface(SERVICE_ID);
+ }
+
+ public IImsConfig getConfigInterface() throws RemoteException {
+ return getInterface().getConfigInterface(mSlotId);
+ }
+
+ public void turnOnIms() throws RemoteException {
+ getInterface().turnOnIms(mSlotId);
+ }
+
+ public void turnOffIms() throws RemoteException {
+ getInterface().turnOffIms(mSlotId);
+ }
+
+ public IImsEcbm getEcbmInterface() throws RemoteException {
+ return getInterface().getEcbmInterface(SERVICE_ID);
+ }
+
+ public void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException {
+ getInterface().setUiTTYMode(SERVICE_ID, uiTtyMode, onComplete);
+ }
+
+ public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
+ return getInterface().getMultiEndpointInterface(SERVICE_ID);
+ }
+
+ private IImsService getInterface() throws RemoteException {
+ IImsService feature = IImsService.Stub.asInterface(mBinder);
+ if (feature == null) {
+ throw new RemoteException("Binder not Available");
+ }
+ return feature;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
new file mode 100644
index 0000000..3236e9a
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/MmTelFeatureCompatAdapter.java
@@ -0,0 +1,542 @@
+/*
+ * 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.ims;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.feature.CapabilityChangeRequest;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.Log;
+
+import com.android.ims.ImsConfigListener;
+import com.android.ims.ImsManager;
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.IImsConfig;
+import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMultiEndpoint;
+import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsUt;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class MmTelFeatureCompatAdapter extends MmTelFeature {
+
+ private static final String TAG = "MmTelFeatureCompat";
+
+ public static final String ACTION_IMS_INCOMING_CALL = "com.android.ims.IMS_INCOMING_CALL";
+
+ private static final int WAIT_TIMEOUT_MS = 5000;
+
+ private final MmTelInterfaceAdapter mCompatFeature;
+ private ImsRegistrationCompatAdapter mRegCompatAdapter;
+ private int mSessionId = -1;
+
+ private static final Map<Integer, Integer> REG_TECH_TO_NET_TYPE = new HashMap<>(2);
+
+ static {
+ REG_TECH_TO_NET_TYPE.put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+ TelephonyManager.NETWORK_TYPE_LTE);
+ REG_TECH_TO_NET_TYPE.put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+ TelephonyManager.NETWORK_TYPE_IWLAN);
+ }
+
+ // Feature Type for compatibility with old "feature" updates
+ public static final int FEATURE_TYPE_UNKNOWN = -1;
+ public static final int FEATURE_TYPE_VOICE_OVER_LTE = 0;
+ public static final int FEATURE_TYPE_VIDEO_OVER_LTE = 1;
+ public static final int FEATURE_TYPE_VOICE_OVER_WIFI = 2;
+ public static final int FEATURE_TYPE_VIDEO_OVER_WIFI = 3;
+ public static final int FEATURE_TYPE_UT_OVER_LTE = 4;
+ public static final int FEATURE_TYPE_UT_OVER_WIFI = 5;
+
+ public static final int FEATURE_UNKNOWN = -1;
+ public static final int FEATURE_DISABLED = 0;
+ public static final int FEATURE_ENABLED = 1;
+
+ private static class ConfigListener extends ImsConfigListener.Stub {
+
+ private final int mCapability;
+ private final int mTech;
+ private final CountDownLatch mLatch;
+
+ public ConfigListener(int capability, int tech, CountDownLatch latch) {
+ mCapability = capability;
+ mTech = tech;
+ mLatch = latch;
+ }
+
+ @Override
+ public void onGetFeatureResponse(int feature, int network, int value, int status)
+ throws RemoteException {
+ if (feature == mCapability && network == mTech) {
+ mLatch.countDown();
+ getFeatureValueReceived(value);
+ } else {
+ Log.i(TAG, "onGetFeatureResponse: response different than requested: feature="
+ + feature + " and network=" + network);
+ }
+ }
+
+ @Override
+ public void onSetFeatureResponse(int feature, int network, int value, int status)
+ throws RemoteException {
+ if (feature == mCapability && network == mTech) {
+ mLatch.countDown();
+ setFeatureValueReceived(value);
+ } else {
+ Log.i(TAG, "onSetFeatureResponse: response different than requested: feature="
+ + feature + " and network=" + network);
+ }
+ }
+
+ @Override
+ public void onGetVideoQuality(int status, int quality) throws RemoteException {
+ }
+
+ @Override
+ public void onSetVideoQuality(int status) throws RemoteException {
+ }
+
+ public void getFeatureValueReceived(int value) {
+ }
+
+ public void setFeatureValueReceived(int value) {
+ }
+ }
+
+ // Trampolines "old" listener events to the new interface.
+ private final IImsRegistrationListener mListener = new IImsRegistrationListener.Stub() {
+ @Override
+ public void registrationConnected() throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationProgressing() throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationResumed() throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationSuspended() throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationServiceCapabilityChanged(int serviceClass, int event)
+ throws RemoteException {
+ // Don't care
+ }
+
+ @Override
+ public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
+ int[] disabledFeatures) throws RemoteException {
+ notifyCapabilitiesStatusChanged(convertCapabilities(enabledFeatures));
+ }
+
+ @Override
+ public void voiceMessageCountUpdate(int count) throws RemoteException {
+ notifyVoiceMessageCountUpdate(count);
+ }
+
+ @Override
+ public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+
+ @Override
+ public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
+ throws RemoteException {
+ // Implemented in the Registration Adapter
+ }
+ };
+
+ /**
+ * Stub implementation of the "old" Registration listener interface that provides no
+ * functionality. Instead, it is used to ensure compatibility with older devices that require
+ * a listener on startSession. The actual Registration Listener Interface is added separately
+ * in ImsRegistration.
+ */
+ private class ImsRegistrationListenerBase extends IImsRegistrationListener.Stub {
+
+ @Override
+ public void registrationConnected() throws RemoteException {
+ }
+
+ @Override
+ public void registrationProgressing() throws RemoteException {
+ }
+
+ @Override
+ public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
+ }
+
+ @Override
+ public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
+ }
+
+ @Override
+ public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
+ }
+
+ @Override
+ public void registrationResumed() throws RemoteException {
+ }
+
+ @Override
+ public void registrationSuspended() throws RemoteException {
+ }
+
+ @Override
+ public void registrationServiceCapabilityChanged(int serviceClass, int event)
+ throws RemoteException {
+ }
+
+ @Override
+ public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
+ int[] disabledFeatures) throws RemoteException {
+ }
+
+ @Override
+ public void voiceMessageCountUpdate(int count) throws RemoteException {
+ }
+
+ @Override
+ public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
+ }
+
+ @Override
+ public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
+ throws RemoteException {
+ }
+ }
+
+ // Handle Incoming Call as PendingIntent, the old method
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "onReceive");
+ if (intent.getAction().equals(ACTION_IMS_INCOMING_CALL)) {
+ Log.i(TAG, "onReceive : incoming call intent.");
+
+ String callId = intent.getStringExtra("android:imsCallID");
+ try {
+ IImsCallSession session = mCompatFeature.getPendingCallSession(mSessionId,
+ callId);
+ notifyIncomingCallSession(session, intent.getExtras());
+ } catch (RemoteException e) {
+ Log.w(TAG, "onReceive: Couldn't get Incoming call session.");
+ }
+ }
+ }
+ };
+
+ public MmTelFeatureCompatAdapter(Context context, int slotId,
+ MmTelInterfaceAdapter compatFeature) {
+ initialize(context, slotId);
+ mCompatFeature = compatFeature;
+ }
+
+ @Override
+ public boolean queryCapabilityConfiguration(int capability, int radioTech) {
+ int capConverted = convertCapability(capability, radioTech);
+ // Wait for the result from the ImsService
+ CountDownLatch latch = new CountDownLatch(1);
+ final int[] returnValue = new int[1];
+ returnValue[0] = FEATURE_UNKNOWN;
+ int regTech = REG_TECH_TO_NET_TYPE.getOrDefault(radioTech,
+ ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
+ try {
+ mCompatFeature.getConfigInterface().getFeatureValue(capConverted, regTech,
+ new ConfigListener(capConverted, regTech, latch) {
+ @Override
+ public void getFeatureValueReceived(int value) {
+ returnValue[0] = value;
+ }
+ });
+ } catch (RemoteException e) {
+ Log.w(TAG, "queryCapabilityConfiguration");
+ }
+ try {
+ latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Log.w(TAG, "queryCapabilityConfiguration - error waiting: " + e.getMessage());
+ }
+ return returnValue[0] == FEATURE_ENABLED;
+ }
+
+ @Override
+ public void changeEnabledCapabilities(CapabilityChangeRequest request,
+ CapabilityCallbackProxy c) {
+ if (request == null) {
+ return;
+ }
+ try {
+ IImsConfig imsConfig = mCompatFeature.getConfigInterface();
+ CountDownLatch latch = new CountDownLatch(1);
+ // Disable Capabilities
+ for (CapabilityChangeRequest.CapabilityPair cap : request.getCapabilitiesToDisable()) {
+ int capConverted = convertCapability(cap.getCapability(), cap.getRadioTech());
+ int radioTechConverted = REG_TECH_TO_NET_TYPE.getOrDefault(cap.getRadioTech(),
+ ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
+ Log.i(TAG, "changeEnabledCapabilities - cap: " + capConverted + " radioTech: "
+ + radioTechConverted + " disabled");
+ imsConfig.setFeatureValue(capConverted, radioTechConverted, FEATURE_DISABLED,
+ new ConfigListener(capConverted, radioTechConverted, latch) {
+ @Override
+ public void setFeatureValueReceived(int value) {
+ if (value != FEATURE_DISABLED) {
+ if (c == null) {
+ return;
+ }
+ c.onChangeCapabilityConfigurationError(cap.getCapability(),
+ cap.getRadioTech(), CAPABILITY_ERROR_GENERIC);
+ }
+ }
+ });
+ latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+ // Enable Capabilities
+ for (CapabilityChangeRequest.CapabilityPair cap : request.getCapabilitiesToEnable()) {
+ int capConverted = convertCapability(cap.getCapability(), cap.getRadioTech());
+ int radioTechConverted = REG_TECH_TO_NET_TYPE.getOrDefault(cap.getRadioTech(),
+ ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
+ Log.i(TAG, "changeEnabledCapabilities - cap: " + capConverted + " radioTech: "
+ + radioTechConverted + " enabled");
+ imsConfig.setFeatureValue(capConverted, radioTechConverted, FEATURE_ENABLED,
+ new ConfigListener(capConverted, radioTechConverted, latch) {
+ @Override
+ public void setFeatureValueReceived(int value) {
+ if (value != FEATURE_ENABLED) {
+ if (c == null) {
+ return;
+ }
+ c.onChangeCapabilityConfigurationError(cap.getCapability(),
+ cap.getRadioTech(), CAPABILITY_ERROR_GENERIC);
+ }
+ }
+ });
+ latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+ } catch (RemoteException | InterruptedException e) {
+ Log.w(TAG, "changeEnabledCapabilities: Error processing: " + e.getMessage());
+ }
+ }
+
+ @Override
+ public ImsCallProfile createCallProfile(int callSessionType, int callType) {
+ try {
+ return mCompatFeature.createCallProfile(mSessionId, callSessionType, callType);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ @Override
+ public IImsCallSession createCallSessionInterface(ImsCallProfile profile)
+ throws RemoteException {
+ return mCompatFeature.createCallSession(mSessionId, profile);
+ }
+
+ @Override
+ public IImsUt getUtInterface() throws RemoteException {
+ return mCompatFeature.getUtInterface();
+ }
+
+ @Override
+ public IImsEcbm getEcbmInterface() throws RemoteException {
+ return mCompatFeature.getEcbmInterface();
+ }
+
+ @Override
+ public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
+ return mCompatFeature.getMultiEndpointInterface();
+ }
+
+ @Override
+ public int getFeatureState() {
+ try {
+ return mCompatFeature.getFeatureState();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void setUiTtyMode(int mode, Message onCompleteMessage) {
+ try {
+ mCompatFeature.setUiTTYMode(mode, onCompleteMessage);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+
+ @Override
+ public void onFeatureRemoved() {
+ mContext.unregisterReceiver(mReceiver);
+ try {
+ mCompatFeature.endSession(mSessionId);
+ mCompatFeature.removeRegistrationListener(mListener);
+ if (mRegCompatAdapter != null) {
+ mCompatFeature.removeRegistrationListener(
+ mRegCompatAdapter.getRegistrationListener());
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "onFeatureRemoved: Couldn't end session: " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onFeatureReady() {
+ Log.i(TAG, "onFeatureReady called!");
+ // This gets called when MmTelFeature.setListener is called. We need to use this time to
+ // call openSession on the old MMTelFeature implementation.
+ IntentFilter intentFilter = new IntentFilter(ImsManager.ACTION_IMS_INCOMING_CALL);
+ mContext.registerReceiver(mReceiver, intentFilter);
+ try {
+ mSessionId = mCompatFeature.startSession(createIncomingCallPendingIntent(),
+ new ImsRegistrationListenerBase());
+ mCompatFeature.addRegistrationListener(mListener);
+ mCompatFeature.addRegistrationListener(mRegCompatAdapter.getRegistrationListener());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Couldn't start compat feature: " + e.getMessage());
+ }
+ }
+
+ public void enableIms() throws RemoteException {
+ mCompatFeature.turnOnIms();
+ }
+
+ public void disableIms() throws RemoteException {
+ mCompatFeature.turnOffIms();
+ }
+
+ public IImsConfig getOldConfigInterface() {
+ try {
+ return mCompatFeature.getConfigInterface();
+ } catch (RemoteException e) {
+ Log.w(TAG, "getOldConfigInterface(): " + e.getMessage());
+ return null;
+ }
+ }
+
+ public void addRegistrationAdapter(ImsRegistrationCompatAdapter regCompat)
+ throws RemoteException {
+ mRegCompatAdapter = regCompat;
+ }
+
+ private MmTelCapabilities convertCapabilities(int[] enabledFeatures) {
+ boolean[] featuresEnabled = new boolean[enabledFeatures.length];
+ for (int i = FEATURE_TYPE_VOICE_OVER_LTE; i <= FEATURE_TYPE_UT_OVER_WIFI
+ && i < enabledFeatures.length; i++) {
+ if (enabledFeatures[i] == i) {
+ featuresEnabled[i] = true;
+ } else if (enabledFeatures[i] == FEATURE_TYPE_UNKNOWN) {
+ // FEATURE_TYPE_UNKNOWN indicates that a feature is disabled.
+ featuresEnabled[i] = false;
+ }
+ }
+ MmTelCapabilities capabilities = new MmTelCapabilities();
+ if (featuresEnabled[FEATURE_TYPE_VOICE_OVER_LTE]
+ || featuresEnabled[FEATURE_TYPE_VOICE_OVER_WIFI]) {
+ // voice is enabled
+ capabilities.addCapabilities(MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ }
+ if (featuresEnabled[FEATURE_TYPE_VIDEO_OVER_LTE]
+ || featuresEnabled[FEATURE_TYPE_VIDEO_OVER_WIFI]) {
+ // video is enabled
+ capabilities.addCapabilities(MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+ }
+ if (featuresEnabled[FEATURE_TYPE_UT_OVER_LTE]
+ || featuresEnabled[FEATURE_TYPE_UT_OVER_WIFI]) {
+ // ut is enabled
+ capabilities.addCapabilities(MmTelCapabilities.CAPABILITY_TYPE_UT);
+ }
+ Log.i(TAG, "convertCapabilities - capabilities: " + capabilities);
+ return capabilities;
+ }
+
+ private PendingIntent createIncomingCallPendingIntent() {
+ Intent intent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ return PendingIntent.getBroadcast(mContext, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ private int convertCapability(int capability, int radioTech) {
+ int capConverted = FEATURE_TYPE_UNKNOWN;
+ if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+ switch (capability) {
+ case MmTelCapabilities.CAPABILITY_TYPE_VOICE:
+ capConverted = FEATURE_TYPE_VOICE_OVER_LTE;
+ break;
+ case MmTelCapabilities.CAPABILITY_TYPE_VIDEO:
+ capConverted = FEATURE_TYPE_VIDEO_OVER_LTE;
+ break;
+ case MmTelCapabilities.CAPABILITY_TYPE_UT:
+ capConverted = FEATURE_TYPE_UT_OVER_LTE;
+ break;
+ }
+ } else if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+ switch (capability) {
+ case MmTelCapabilities.CAPABILITY_TYPE_VOICE:
+ capConverted = FEATURE_TYPE_VOICE_OVER_WIFI;
+ break;
+ case MmTelCapabilities.CAPABILITY_TYPE_VIDEO:
+ capConverted = FEATURE_TYPE_VIDEO_OVER_WIFI;
+ break;
+ case MmTelCapabilities.CAPABILITY_TYPE_UT:
+ capConverted = FEATURE_TYPE_UT_OVER_WIFI;
+ break;
+ }
+ }
+ return capConverted;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/ims/MmTelInterfaceAdapter.java b/src/java/com/android/internal/telephony/ims/MmTelInterfaceAdapter.java
new file mode 100644
index 0000000..ef08133
--- /dev/null
+++ b/src/java/com/android/internal/telephony/ims/MmTelInterfaceAdapter.java
@@ -0,0 +1,128 @@
+/*
+ * 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.ims;
+
+import android.app.PendingIntent;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.ims.ImsCallProfile;
+
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.IImsConfig;
+import com.android.ims.internal.IImsEcbm;
+import com.android.ims.internal.IImsMMTelFeature;
+import com.android.ims.internal.IImsMultiEndpoint;
+import com.android.ims.internal.IImsRegistrationListener;
+import com.android.ims.internal.IImsUt;
+
+/**
+ * Defines "generic" MmTel commands and provides a concrete implementation for compatibility
+ * purposes.
+ */
+
+public class MmTelInterfaceAdapter {
+
+ protected IBinder mBinder;
+ protected int mSlotId;
+
+ public MmTelInterfaceAdapter(int slotId, IBinder binder) {
+ mBinder = binder;
+ mSlotId = slotId;
+ }
+
+ public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
+ throws RemoteException {
+ return getInterface().startSession(incomingCallIntent, listener);
+ }
+
+ public void endSession(int sessionId) throws RemoteException {
+ getInterface().endSession(sessionId);
+ }
+
+ public boolean isConnected(int callSessionType, int callType) throws RemoteException {
+ return getInterface().isConnected(callSessionType, callType);
+ }
+
+ public boolean isOpened() throws RemoteException {
+ return getInterface().isOpened();
+ }
+
+ public int getFeatureState() throws RemoteException {
+ return getInterface().getFeatureStatus();
+ }
+
+ public void addRegistrationListener(IImsRegistrationListener listener) throws RemoteException {
+ getInterface().addRegistrationListener(listener);
+ }
+
+ public void removeRegistrationListener(IImsRegistrationListener listener)
+ throws RemoteException {
+ getInterface().removeRegistrationListener(listener);
+ }
+
+ public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType)
+ throws RemoteException {
+ return getInterface().createCallProfile(sessionId, callSessionType, callType);
+ }
+
+ public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
+ throws RemoteException {
+ return getInterface().createCallSession(sessionId, profile);
+ }
+
+ public IImsCallSession getPendingCallSession(int sessionId, String callId)
+ throws RemoteException {
+ return getInterface().getPendingCallSession(sessionId, callId);
+ }
+
+ public IImsUt getUtInterface() throws RemoteException {
+ return getInterface().getUtInterface();
+ }
+
+ public IImsConfig getConfigInterface() throws RemoteException {
+ return getInterface().getConfigInterface();
+ }
+
+ public void turnOnIms() throws RemoteException {
+ getInterface().turnOnIms();
+ }
+
+ public void turnOffIms() throws RemoteException {
+ getInterface().turnOffIms();
+ }
+
+ public IImsEcbm getEcbmInterface() throws RemoteException {
+ return getInterface().getEcbmInterface();
+ }
+
+ public void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException {
+ getInterface().setUiTTYMode(uiTtyMode, onComplete);
+ }
+
+ public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
+ return getInterface().getMultiEndpointInterface();
+ }
+
+ private IImsMMTelFeature getInterface() throws RemoteException {
+ IImsMMTelFeature feature = IImsMMTelFeature.Stub.asInterface(mBinder);
+ if (feature == null) {
+ throw new RemoteException("Binder not Available");
+ }
+ return feature;
+ }
+}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
index b833533..03ea1c8 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCall.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.imsphone;
+import android.telephony.ims.ImsExternalCallState;
+
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
@@ -25,7 +27,7 @@
/**
* Companion class for {@link ImsExternalConnection}; represents an external call which was
- * received via {@link com.android.ims.ImsExternalCallState} info.
+ * received via {@link ImsExternalCallState} info.
*/
public class ImsExternalCall extends Call {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
index 4bea73d..3227cfa 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
@@ -16,8 +16,8 @@
package com.android.internal.telephony.imsphone;
-import com.android.ims.ImsCallProfile;
-import com.android.ims.ImsExternalCallState;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsExternalCallState;
import com.android.ims.ImsExternalCallStateListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Call;
@@ -31,7 +31,6 @@
import android.os.Message;
import android.telecom.PhoneAccountHandle;
import android.telecom.VideoProfile;
-import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
index 071aebb..a8b07cb 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalConnection.java
@@ -28,11 +28,9 @@
import android.net.Uri;
import android.telecom.PhoneAccount;
import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
-import android.util.Log;
+import android.telephony.ims.ImsExternalCallState;
import java.util.Collections;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -42,7 +40,7 @@
* Package.
*
* Dialog event package information is received from the IMS framework via
- * {@link com.android.ims.ImsExternalCallState} instances.
+ * {@link ImsExternalCallState} instances.
*
* @hide
*/
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 03b280e..706c953 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -69,14 +69,14 @@
import android.telephony.UssdResponse;
import android.text.TextUtils;
-import com.android.ims.ImsCallForwardInfo;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallForwardInfo;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.ImsEcbm;
import com.android.ims.ImsEcbmStateListener;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.ImsSsInfo;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsSsInfo;
import com.android.ims.ImsUtInterface;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Call;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index d5519dd..e573fbd 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -446,10 +446,6 @@
Message response) {
}
- @Override
- public void getDataCallList(Message response) {
- }
-
public List<DataConnection> getCurrentDataConnectionList () {
return null;
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
index b90f64f..cb5917d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCall.java
@@ -28,7 +28,7 @@
import com.android.internal.telephony.Phone;
import com.android.ims.ImsCall;
import com.android.ims.ImsException;
-import com.android.ims.ImsStreamMediaProfile;
+import android.telephony.ims.ImsStreamMediaProfile;
import java.util.List;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 08543bf..13038cd 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.imsphone;
-import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -51,6 +50,9 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsConfigImplBase;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -58,19 +60,18 @@
import android.util.SparseIntArray;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.ImsConfig;
import com.android.ims.ImsConfigListener;
-import com.android.ims.ImsConnectionStateListener;
import com.android.ims.ImsEcbm;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.ims.ImsMultiEndpoint;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.ImsServiceClass;
-import com.android.ims.ImsServiceProxy;
-import com.android.ims.ImsSuppServiceNotification;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsSuppServiceNotification;
import com.android.ims.ImsUtInterface;
+import com.android.ims.MmTelFeatureConnection;
+import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsVideoCallProvider;
import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.ims.internal.VideoPauseTracker;
@@ -131,90 +132,100 @@
private static final boolean VERBOSE_STATE_LOGGING = FORCE_VERBOSE_STATE_LOGGING ||
Rlog.isLoggable(VERBOSE_STATE_TAG, Log.VERBOSE);
- //Indices map to ImsConfig.FeatureConstants
- private boolean[] mImsFeatureEnabled = {false, false, false, false, false, false};
- private final String[] mImsFeatureStrings = {"VoLTE", "ViLTE", "VoWiFi", "ViWiFi",
- "UTLTE", "UTWiFi"};
+ private MmTelFeature.MmTelCapabilities mMmTelCapabilities =
+ new MmTelFeature.MmTelCapabilities();
private TelephonyMetrics mMetrics;
private boolean mCarrierConfigLoaded = false;
+ private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener();
+ private class MmTelFeatureListener extends MmTelFeature.Listener {
+ @Override
+ public void onIncomingCall(IImsCallSession c, Bundle extras) {
+ if (DBG) log("onReceive : incoming call intent");
+
+ if (mImsManager == null) return;
+
+ try {
+ // Network initiated USSD will be treated by mImsUssdListener
+ boolean isUssd = extras.getBoolean(ImsManager.EXTRA_USSD, false);
+ if (isUssd) {
+ if (DBG) log("onReceive : USSD");
+ mUssdSession = mImsManager.takeCall(c, extras, mImsUssdListener);
+ if (mUssdSession != null) {
+ mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
+ }
+ return;
+ }
+
+ boolean isUnknown = extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false);
+ if (DBG) {
+ log("onReceive : isUnknown = " + isUnknown
+ + " fg = " + mForegroundCall.getState()
+ + " bg = " + mBackgroundCall.getState());
+ }
+
+ // Normal MT/Unknown call
+ ImsCall imsCall = mImsManager.takeCall(c, extras, mImsCallListener);
+ ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall,
+ ImsPhoneCallTracker.this,
+ (isUnknown ? mForegroundCall : mRingingCall), isUnknown);
+
+ // If there is an active call.
+ if (mForegroundCall.hasConnections()) {
+ ImsCall activeCall = mForegroundCall.getFirstConnection().getImsCall();
+ if (activeCall != null && imsCall != null) {
+ // activeCall could be null if the foreground call is in a disconnected
+ // state. If either of the calls is null there is no need to check if
+ // one will be disconnected on answer.
+ boolean answeringWillDisconnect =
+ shouldDisconnectActiveCallOnAnswer(activeCall, imsCall);
+ conn.setActiveCallDisconnectedOnAnswer(answeringWillDisconnect);
+ }
+ }
+ conn.setAllowAddCallDuringVideoCall(mAllowAddCallDuringVideoCall);
+ addConnection(conn);
+
+ setVideoCallProvider(conn, imsCall);
+
+ TelephonyMetrics.getInstance().writeOnImsCallReceive(mPhone.getPhoneId(),
+ imsCall.getSession());
+
+ if (isUnknown) {
+ mPhone.notifyUnknownConnection(conn);
+ } else {
+ if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE)
+ || (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE)) {
+ conn.update(imsCall, ImsPhoneCall.State.WAITING);
+ }
+
+ mPhone.notifyNewRingingConnection(conn);
+ mPhone.notifyIncomingRing();
+ }
+
+ updatePhoneState();
+ mPhone.notifyPreciseCallStateChanged();
+ } catch (ImsException e) {
+ loge("onReceive : exception " + e);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onVoiceMessageCountUpdate(int count) {
+ if (mPhone != null && mPhone.mDefaultPhone != null) {
+ if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
+ mPhone.mDefaultPhone.setVoiceMessageCount(count);
+ } else {
+ loge("onVoiceMessageCountUpdate: null phone");
+ }
+ }
+ }
+
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(ImsManager.ACTION_IMS_INCOMING_CALL)) {
- if (DBG) log("onReceive : incoming call intent");
-
- if (mImsManager == null) return;
-
- if (mServiceId < 0) return;
-
- try {
- // Network initiated USSD will be treated by mImsUssdListener
- boolean isUssd = intent.getBooleanExtra(ImsManager.EXTRA_USSD, false);
- if (isUssd) {
- if (DBG) log("onReceive : USSD");
- mUssdSession = mImsManager.takeCall(mServiceId, intent, mImsUssdListener);
- if (mUssdSession != null) {
- mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
- }
- return;
- }
-
- boolean isUnknown = intent.getBooleanExtra(ImsManager.EXTRA_IS_UNKNOWN_CALL,
- false);
- if (DBG) {
- log("onReceive : isUnknown = " + isUnknown +
- " fg = " + mForegroundCall.getState() +
- " bg = " + mBackgroundCall.getState());
- }
-
- // Normal MT/Unknown call
- ImsCall imsCall = mImsManager.takeCall(mServiceId, intent, mImsCallListener);
- ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall,
- ImsPhoneCallTracker.this,
- (isUnknown? mForegroundCall: mRingingCall), isUnknown);
-
- // If there is an active call.
- if (mForegroundCall.hasConnections()) {
- ImsCall activeCall = mForegroundCall.getFirstConnection().getImsCall();
- if (activeCall != null && imsCall != null) {
- // activeCall could be null if the foreground call is in a disconnected
- // state. If either of the calls is null there is no need to check if
- // one will be disconnected on answer.
- boolean answeringWillDisconnect =
- shouldDisconnectActiveCallOnAnswer(activeCall, imsCall);
- conn.setActiveCallDisconnectedOnAnswer(answeringWillDisconnect);
- }
- }
- conn.setAllowAddCallDuringVideoCall(mAllowAddCallDuringVideoCall);
- addConnection(conn);
-
- setVideoCallProvider(conn, imsCall);
-
- TelephonyMetrics.getInstance().writeOnImsCallReceive(mPhone.getPhoneId(),
- imsCall.getSession());
-
- if (isUnknown) {
- mPhone.notifyUnknownConnection(conn);
- } else {
- if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) ||
- (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE)) {
- conn.update(imsCall, ImsPhoneCall.State.WAITING);
- }
-
- mPhone.notifyNewRingingConnection(conn);
- mPhone.notifyIncomingRing();
- }
-
- updatePhoneState();
- mPhone.notifyPreciseCallStateChanged();
- } catch (ImsException e) {
- loge("onReceive : exception " + e);
- } catch (RemoteException e) {
- }
- } else if (intent.getAction().equals(
- CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+ if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
if (subId == mPhone.getSubId()) {
@@ -295,7 +306,6 @@
private int mImsServiceRetryCount;
private ImsManager mImsManager;
private ImsUtInterface mUtInterface;
- private int mServiceId = -1;
private Call.SrvccState mSrvccState = Call.SrvccState.NONE;
@@ -628,12 +638,12 @@
};
// Callback fires when ImsManager MMTel Feature changes state
- private ImsServiceProxy.IFeatureUpdate mNotifyStatusChangedCallback =
- new ImsServiceProxy.IFeatureUpdate() {
+ private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback =
+ new MmTelFeatureConnection.IFeatureUpdate() {
@Override
public void notifyStateChanged() {
try {
- int status = mImsManager.getImsServiceStatus();
+ int status = mImsManager.getImsServiceState();
log("Status Changed: " + status);
switch (status) {
case ImsFeature.STATE_READY: {
@@ -642,7 +652,7 @@
}
case ImsFeature.STATE_INITIALIZING:
// fall through
- case ImsFeature.STATE_NOT_AVAILABLE: {
+ case ImsFeature.STATE_UNAVAILABLE: {
stopListeningForCalls();
break;
}
@@ -691,7 +701,6 @@
mMetrics = TelephonyMetrics.getInstance();
IntentFilter intentfilter = new IntentFilter();
- intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);
intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
intentfilter.addAction(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
mPhone.getContext().registerReceiver(mReceiver, intentfilter);
@@ -751,13 +760,6 @@
return uid;
}
- private PendingIntent createIncomingCallPendingIntent() {
- Intent intent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- return PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- }
-
private void getImsService() throws ImsException {
if (DBG) log("getImsService");
mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
@@ -771,11 +773,13 @@
private void startListeningForCalls() throws ImsException {
mImsServiceRetryCount = 0;
- mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
- createIncomingCallPendingIntent(),
- mImsConnectionStateListener);
+ mImsManager.open(mMmTelFeatureListener);
+ mImsManager.addRegistrationCallback(mImsRegistrationCallback);
+ mImsManager.addCapabilitiesCallback(mImsCapabilityCallback);
- mImsManager.setImsConfigListener(mImsConfigListener);
+ mImsManager.setConfigListener(mImsConfigListener);
+
+ mImsManager.getConfigInterface().addConfigCallback(mConfigCallback);
// Get the ECBM interface and set IMSPhone's listener object for notifications
getEcbmInterface().setEcbmStateListener(mPhone.getImsEcbmStateListener());
@@ -808,15 +812,15 @@
}
private void stopListeningForCalls() {
- try {
- resetImsCapabilities();
- // Only close on valid session.
- if (mImsManager != null && mServiceId > 0) {
- mImsManager.close(mServiceId);
- mServiceId = -1;
+ resetImsCapabilities();
+ // Only close on valid session.
+ if (mImsManager != null) {
+ try {
+ mImsManager.getConfigInterface().removeConfigCallback(mConfigCallback);
+ } catch (ImsException e) {
+ Log.w(LOG_TAG, "stopListeningForCalls: unable to remove config callback.");
}
- } catch (ImsException e) {
- // If the binder is unavailable, then the ImsService doesn't need to close.
+ mImsManager.close();
}
}
@@ -1115,8 +1119,7 @@
try {
String[] callees = new String[] { conn.getAddress() };
- ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
- serviceType, callType);
+ ImsCallProfile profile = mImsManager.createCallProfile(serviceType, callType);
profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);
// Translate call subject intent-extra from Telecom-specific extra key to the
@@ -1147,8 +1150,7 @@
// being sent to the lower layers/to the network.
}
- ImsCall imsCall = mImsManager.makeCall(mServiceId, profile,
- callees, mImsCallListener);
+ ImsCall imsCall = mImsManager.makeCall(profile, callees, mImsCallListener);
conn.setImsCall(imsCall);
mMetrics.writeOnImsCallStart(mPhone.getPhoneId(),
@@ -1710,13 +1712,12 @@
}
String[] callees = new String[] { ussdString };
- ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
+ ImsCallProfile profile = mImsManager.createCallProfile(
ImsCallProfile.SERVICE_TYPE_NORMAL, ImsCallProfile.CALL_TYPE_VOICE);
profile.setCallExtraInt(ImsCallProfile.EXTRA_DIALSTRING,
ImsCallProfile.DIALSTRING_USSD);
- mUssdSession = mImsManager.makeCall(mServiceId, profile,
- callees, mImsUssdListener);
+ mUssdSession = mImsManager.makeCall(profile, callees, mImsUssdListener);
} catch (ImsException e) {
loge("sendUSSD : " + e);
mPhone.sendErrorResponse(response, e);
@@ -2594,7 +2595,7 @@
&& targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN
&& targetAccessTech != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
if (isHandoverFromWifi && imsCall.isVideoCall()) {
- if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) {
+ if (mNotifyHandoverVideoFromWifiToLTE && mIsDataEnabled) {
if (conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) {
log("onCallHandover :: notifying of WIFI to LTE handover.");
conn.onConnectionEvent(
@@ -2760,83 +2761,60 @@
}
};
- /**
- * Listen to the IMS service state change
- *
- */
- private ImsConnectionStateListener mImsConnectionStateListener =
- new ImsConnectionStateListener() {
- @Override
- public void onImsConnected(int imsRadioTech) {
- if (DBG) log("onImsConnected imsRadioTech=" + imsRadioTech);
- mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
- mPhone.setImsRegistered(true);
- mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
- ImsConnectionState.State.CONNECTED, null);
- }
+ private final ImsRegistrationImplBase.Callback mImsRegistrationCallback =
+ new ImsRegistrationImplBase.Callback() {
- @Override
- public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
- if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
- resetImsCapabilities();
- mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
- mPhone.setImsRegistered(false);
- mPhone.processDisconnectReason(imsReasonInfo);
- mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
- ImsConnectionState.State.DISCONNECTED, imsReasonInfo);
- }
+ @Override
+ public void onRegistered(
+ @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+ if (DBG) log("onImsConnected imsRadioTech=" + imsRadioTech);
+ mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
+ mPhone.setImsRegistered(true);
+ mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
+ ImsConnectionState.State.CONNECTED, null);
+ }
- @Override
- public void onImsProgressing(int imsRadioTech) {
- if (DBG) log("onImsProgressing imsRadioTech=" + imsRadioTech);
- mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
- mPhone.setImsRegistered(false);
- mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
- ImsConnectionState.State.PROGRESSING, null);
- }
+ @Override
+ public void onRegistering(
+ @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+ if (DBG) log("onImsProgressing imsRadioTech=" + imsRadioTech);
+ mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
+ mPhone.setImsRegistered(false);
+ mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
+ ImsConnectionState.State.PROGRESSING, null);
+ }
- @Override
- public void onImsResumed() {
- if (DBG) log("onImsResumed");
- mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
- mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
- ImsConnectionState.State.RESUMED, null);
- }
+ @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);
+ mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
+ ImsConnectionState.State.DISCONNECTED, imsReasonInfo);
+ }
- @Override
- public void onImsSuspended() {
- if (DBG) log("onImsSuspended");
- mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
- mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
- ImsConnectionState.State.SUSPENDED, null);
+ @Override
+ public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+ if (DBG) log("registrationAssociatedUriChanged");
+ mPhone.setCurrentSubscriberUris(uris);
+ }
+ };
- }
-
- @Override
- public void onFeatureCapabilityChanged(int serviceClass,
- int[] enabledFeatures, int[] disabledFeatures) {
- if (DBG) log("onFeatureCapabilityChanged");
- SomeArgs args = SomeArgs.obtain();
- args.argi1 = serviceClass;
- args.arg1 = enabledFeatures;
- args.arg2 = disabledFeatures;
- // Remove any pending updates; they're already stale, so no need to process them.
- removeMessages(EVENT_ON_FEATURE_CAPABILITY_CHANGED);
- obtainMessage(EVENT_ON_FEATURE_CAPABILITY_CHANGED, args).sendToTarget();
- }
-
- @Override
- public void onVoiceMessageCountChanged(int count) {
- if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
- mPhone.mDefaultPhone.setVoiceMessageCount(count);
- }
-
- @Override
- public void registrationAssociatedUriChanged(Uri[] uris) {
- if (DBG) log("registrationAssociatedUriChanged");
- mPhone.setCurrentSubscriberUris(uris);
- }
- };
+ private final ImsFeature.CapabilityCallback mImsCapabilityCallback =
+ new ImsFeature.CapabilityCallback() {
+ @Override
+ public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
+ if (DBG) log("onCapabilitiesStatusChanged: " + config);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = config;
+ // Remove any pending updates; they're already stale, so no need to process
+ // them.
+ removeMessages(EVENT_ON_FEATURE_CAPABILITY_CHANGED);
+ obtainMessage(EVENT_ON_FEATURE_CAPABILITY_CHANGED, args).sendToTarget();
+ }
+ };
private ImsConfigListener.Stub mImsConfigListener = new ImsConfigListener.Stub() {
@Override
@@ -2844,8 +2822,7 @@
@Override
public void onSetFeatureResponse(int feature, int network, int value, int status) {
- mMetrics.writeImsSetFeatureValue(
- mPhone.getPhoneId(), feature, network, value, status);
+ mMetrics.writeImsSetFeatureValue(mPhone.getPhoneId(), feature, network, value);
}
@Override
@@ -2856,6 +2833,30 @@
};
+ private final ImsConfigImplBase.Callback mConfigCallback = new ImsConfigImplBase.Callback() {
+ @Override
+ public void onConfigChanged(int item, int value) {
+ sendConfigChangedIntent(item, Integer.toString(value));
+ }
+
+ @Override
+ public void onConfigChanged(int item, String value) {
+ sendConfigChangedIntent(item, value);
+ }
+
+ // send IMS_CONFIG_CHANGED intent for older services that do not implement the new callback
+ // interface.
+ private void sendConfigChangedIntent(int item, String value) {
+ log("sendConfigChangedIntent - [" + item + ", " + value + "]");
+ Intent configChangedIntent = new Intent(ImsConfig.ACTION_IMS_CONFIG_CHANGED);
+ configChangedIntent.putExtra(ImsConfig.EXTRA_CHANGED_ITEM, item);
+ configChangedIntent.putExtra(ImsConfig.EXTRA_NEW_VALUE, value);
+ if (mPhone != null && mPhone.getContext() != null) {
+ mPhone.getContext().sendBroadcast(configChangedIntent);
+ }
+ }
+ };
+
public ImsUtInterface getUtInterface() throws ImsException {
if (mImsManager == null) {
throw getImsManagerIsNullException();
@@ -3005,10 +3006,8 @@
case EVENT_ON_FEATURE_CAPABILITY_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
try {
- int serviceClass = args.argi1;
- int[] enabledFeatures = (int[]) args.arg1;
- int[] disabledFeatures = (int[]) args.arg2;
- handleFeatureCapabilityChanged(serviceClass, enabledFeatures, disabledFeatures);
+ ImsFeature.Capabilities capabilities = (ImsFeature.Capabilities) args.arg1;
+ handleFeatureCapabilityChanged(capabilities);
} finally {
args.recycle();
}
@@ -3135,10 +3134,7 @@
pw.println(" mPhone=" + mPhone);
pw.println(" mDesiredMute=" + mDesiredMute);
pw.println(" mState=" + mState);
- for (int i = 0; i < mImsFeatureEnabled.length; i++) {
- pw.println(" " + mImsFeatureStrings[i] + ": "
- + ((mImsFeatureEnabled[i]) ? "enabled" : "disabled"));
- }
+ pw.println(" mMmTelCapabilities=" + mMmTelCapabilities);
pw.println(" mDefaultDialerUid=" + mDefaultDialerUid.get());
pw.println(" mVtDataUsageSnapshot=" + mVtDataUsageSnapshot);
pw.println(" mVtDataUsageUidSnapshot=" + mVtDataUsageUidSnapshot);
@@ -3172,7 +3168,7 @@
throw getImsManagerIsNullException();
}
- ImsEcbm ecbm = mImsManager.getEcbmInterface(mServiceId);
+ ImsEcbm ecbm = mImsManager.getEcbmInterface();
return ecbm;
}
@@ -3183,7 +3179,7 @@
}
try {
- return mImsManager.getMultiEndpointInterface(mServiceId);
+ return mImsManager.getMultiEndpointInterface();
} catch (ImsException e) {
if (e.getCode() == ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED) {
return null;
@@ -3199,16 +3195,21 @@
}
public boolean isVolteEnabled() {
- return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE];
+ boolean isRadioTechLte = getImsRegistrationTech()
+ == ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+ return isRadioTechLte && mMmTelCapabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
}
public boolean isVowifiEnabled() {
- return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI];
+ boolean isRadioTechIwlan = getImsRegistrationTech()
+ == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+ return isRadioTechIwlan && mMmTelCapabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
}
public boolean isVideoCallEnabled() {
- return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE]
- || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI]);
+ return mMmTelCapabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
}
@Override
@@ -3216,6 +3217,13 @@
return mState;
}
+ private int getImsRegistrationTech() {
+ if (mImsManager != null) {
+ return mImsManager.getRegistrationTech();
+ }
+ return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+ }
+
private void retryGetImsService() {
// The binder connection is already up. Do not try to get it again.
if (mImsManager.isServiceAvailable()) {
@@ -3254,8 +3262,7 @@
}
public boolean isUtEnabled() {
- return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_LTE]
- || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI]);
+ return mMmTelCapabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
}
/**
@@ -3462,8 +3469,6 @@
log("onDataEnabledChanged: enabled=" + enabled + ", reason=" + reason);
- ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setDataEnabled(enabled);
-
mIsDataEnabled = enabled;
if (!mIsViLteDataMetered) {
@@ -3607,9 +3612,7 @@
private void resetImsCapabilities() {
log("Resetting Capabilities...");
- for (int i = 0; i < mImsFeatureEnabled.length; i++) {
- mImsFeatureEnabled[i] = false;
- }
+ mMmTelCapabilities = new MmTelFeature.MmTelCapabilities();
}
/**
@@ -3634,71 +3637,47 @@
return mSupportDowngradeVtToAudio;
}
- private void handleFeatureCapabilityChanged(int serviceClass,
- int[] enabledFeatures, int[] disabledFeatures) {
- if (serviceClass == ImsServiceClass.MMTEL) {
- boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
- // Check enabledFeatures to determine capabilities. We ignore disabledFeatures.
- StringBuilder sb;
- if (DBG) {
- sb = new StringBuilder(120);
- sb.append("handleFeatureCapabilityChanged: ");
- }
- for (int i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
- i <= ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI &&
- i < enabledFeatures.length; i++) {
- if (enabledFeatures[i] == i) {
- // If the feature is set to its own integer value it is enabled.
- if (DBG) {
- sb.append(mImsFeatureStrings[i]);
- sb.append(":true ");
- }
+ @VisibleForTesting
+ public void setDataEnabled(boolean isDataEnabled) {
+ mIsDataEnabled = isDataEnabled;
+ }
- mImsFeatureEnabled[i] = true;
- } else if (enabledFeatures[i]
- == ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
- // FEATURE_TYPE_UNKNOWN indicates that a feature is disabled.
- if (DBG) {
- sb.append(mImsFeatureStrings[i]);
- sb.append(":false ");
- }
+ private void handleFeatureCapabilityChanged(ImsFeature.Capabilities capabilities) {
+ boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
+ // Check enabledFeatures to determine capabilities. We ignore disabledFeatures.
+ StringBuilder sb;
+ if (DBG) {
+ sb = new StringBuilder(120);
+ sb.append("handleFeatureCapabilityChanged: ");
+ }
+ sb.append(capabilities);
+ mMmTelCapabilities = new MmTelFeature.MmTelCapabilities(capabilities);
+ boolean isVideoEnabled = isVideoCallEnabled();
+ boolean isVideoEnabledStatechanged = tmpIsVideoCallEnabled != isVideoEnabled;
+ if (DBG) {
+ sb.append(" isVideoEnabledStateChanged=");
+ sb.append(isVideoEnabledStatechanged);
+ }
- mImsFeatureEnabled[i] = false;
- } else {
- // Feature has unknown state; it is not its own value or -1.
- if (DBG) {
- loge("handleFeatureCapabilityChanged(" + i + ", " + mImsFeatureStrings[i]
- + "): unexpectedValue=" + enabledFeatures[i]);
- }
- }
- }
- boolean isVideoEnabled = isVideoCallEnabled();
- boolean isVideoEnabledStatechanged = tmpIsVideoCallEnabled != isVideoEnabled;
- if (DBG) {
- sb.append(" isVideoEnabledStateChanged=");
- sb.append(isVideoEnabledStatechanged);
- }
+ if (isVideoEnabledStatechanged) {
+ log("handleFeatureCapabilityChanged - notifyForVideoCapabilityChanged="
+ + isVideoEnabled);
+ mPhone.notifyForVideoCapabilityChanged(isVideoEnabled);
+ }
- if (isVideoEnabledStatechanged) {
- log("handleFeatureCapabilityChanged - notifyForVideoCapabilityChanged=" +
- isVideoEnabled);
- mPhone.notifyForVideoCapabilityChanged(isVideoEnabled);
- }
+ if (DBG) log(sb.toString());
- if (DBG) {
- log(sb.toString());
- }
-
- if (DBG) log("handleFeatureCapabilityChanged: isVolteEnabled=" + isVolteEnabled()
+ if (DBG) {
+ log("handleFeatureCapabilityChanged: isVolteEnabled=" + isVolteEnabled()
+ ", isVideoCallEnabled=" + isVideoCallEnabled()
+ ", isVowifiEnabled=" + isVowifiEnabled()
+ ", isUtEnabled=" + isUtEnabled());
-
- mPhone.onFeatureCapabilityChanged();
-
- mMetrics.writeOnImsCapabilities(
- mPhone.getPhoneId(), mImsFeatureEnabled);
}
+
+ mPhone.onFeatureCapabilityChanged();
+
+ mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(), getImsRegistrationTech(),
+ mMmTelCapabilities);
}
@VisibleForTesting
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 5a490ae..6bc0841 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -36,9 +36,9 @@
import android.text.TextUtils;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.ImsException;
-import com.android.ims.ImsStreamMediaProfile;
+import android.telephony.ims.ImsStreamMediaProfile;
import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
index 45b12ea..a72b904 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneMmiCode.java
@@ -40,9 +40,9 @@
import android.text.TextUtils;
import com.android.ims.ImsException;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.ImsSsData;
-import com.android.ims.ImsSsInfo;
+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;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
index dbb4036..3bf304e 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
@@ -16,8 +16,6 @@
package com.android.internal.telephony.imsphone;
-import com.android.ims.ImsCallProfile;
-
/**
* Interface implemented by modules which are capable of performing a pull of an external call.
* This is used to break the dependency between {@link ImsExternalCallTracker} and
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index a0c5630..f93dadb 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.metrics;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ANSWER;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SEND_SMS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEACTIVATE_DATA_CALL;
@@ -34,6 +35,7 @@
import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_PPP;
import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_UNKNOWN;
+import android.hardware.radio.V1_0.SetupDataCallResult;
import android.os.Build;
import android.os.SystemClock;
import android.telephony.Rlog;
@@ -42,13 +44,14 @@
import android.telephony.TelephonyManager;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataService;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.Base64;
import android.util.SparseArray;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsCallSession;
import com.android.internal.telephony.GsmCdmaConnection;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RIL;
@@ -836,26 +839,30 @@
* @param feature IMS feature
* @param network The IMS network type
* @param value The settings. 0 indicates disabled, otherwise enabled.
- * @param status IMS operation status. See OperationStatusConstants for details.
*/
- public void writeImsSetFeatureValue(int phoneId, int feature, int network, int value,
- int status) {
+ public void writeImsSetFeatureValue(int phoneId, int feature, int network, int value) {
TelephonySettings s = new TelephonySettings();
- switch (feature) {
- case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE:
- s.isEnhanced4GLteModeEnabled = (value != 0);
- break;
- case ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI:
- s.isWifiCallingEnabled = (value != 0);
- break;
- case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE:
- s.isVtOverLteEnabled = (value != 0);
- break;
- case ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI:
- s.isVtOverWifiEnabled = (value != 0);
- break;
+ if (network == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+ switch (feature) {
+ case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
+ s.isEnhanced4GLteModeEnabled = (value != 0);
+ break;
+ case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO:
+ s.isVtOverLteEnabled = (value != 0);
+ break;
+ }
+ } else if (network == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+ switch (feature) {
+ case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
+ s.isWifiCallingEnabled = (value != 0);
+ break;
+ case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO:
+ s.isVtOverWifiEnabled = (value != 0);
+ break;
+ }
}
+
// If the settings don't change, we don't log the event.
if (mLastSettings.get(phoneId) != null &&
Arrays.equals(TelephonySettings.toByteArray(mLastSettings.get(phoneId)),
@@ -952,15 +959,27 @@
* @param phoneId Phone id
* @param capabilities IMS capabilities array
*/
- public synchronized void writeOnImsCapabilities(int phoneId, boolean[] capabilities) {
+ public synchronized void writeOnImsCapabilities(int phoneId,
+ @ImsRegistrationImplBase.ImsRegistrationTech int radioTech,
+ MmTelFeature.MmTelCapabilities capabilities) {
ImsCapabilities cap = new ImsCapabilities();
- cap.voiceOverLte = capabilities[0];
- cap.videoOverLte = capabilities[1];
- cap.voiceOverWifi = capabilities[2];
- cap.videoOverWifi = capabilities[3];
- cap.utOverLte = capabilities[4];
- cap.utOverWifi = capabilities[5];
+ if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+ cap.voiceOverLte = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ cap.videoOverLte = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+ cap.utOverLte = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
+
+ } else if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+ cap.voiceOverWifi = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ cap.videoOverWifi = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+ cap.utOverWifi = capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
+ }
TelephonyEvent event = new TelephonyEventBuilder(phoneId).setImsCapabilities(cap).build();
@@ -1312,26 +1331,26 @@
* @param rilSerial RIL request serial number
* @param rilError RIL error
* @param rilRequest RIL request
- * @param response Data call response
+ * @param result Data call result
*/
private void writeOnSetupDataCallResponse(int phoneId, int rilSerial, int rilError,
- int rilRequest, DataCallResponse response) {
+ int rilRequest, SetupDataCallResult result) {
RilSetupDataCallResponse setupDataCallResponse = new RilSetupDataCallResponse();
RilDataCall dataCall = new RilDataCall();
- if (response != null) {
- setupDataCallResponse.status = (response.getStatus() == 0
- ? RilDataCallFailCause.PDP_FAIL_NONE : response.getStatus());
- setupDataCallResponse.suggestedRetryTimeMillis = response.getSuggestedRetryTime();
+ if (result != null) {
+ setupDataCallResponse.status =
+ (result.status == 0 ? RilDataCallFailCause.PDP_FAIL_NONE : result.status);
+ setupDataCallResponse.suggestedRetryTimeMillis = result.suggestedRetryTime;
- dataCall.cid = response.getCallId();
- if (!TextUtils.isEmpty(response.getType())) {
- dataCall.type = toPdpType(response.getType());
+ dataCall.cid = result.cid;
+ if (!TextUtils.isEmpty(result.type)) {
+ dataCall.type = toPdpType(result.type);
}
- if (!TextUtils.isEmpty(response.getIfname())) {
- dataCall.iframe = response.getIfname();
+ if (!TextUtils.isEmpty(result.ifname)) {
+ dataCall.iframe = result.ifname;
}
}
setupDataCallResponse.call = dataCall;
@@ -1419,8 +1438,8 @@
int rilRequest, Object ret) {
switch (rilRequest) {
case RIL_REQUEST_SETUP_DATA_CALL:
- DataCallResponse dataCall = (DataCallResponse) ret;
- writeOnSetupDataCallResponse(phoneId, rilSerial, rilError, rilRequest, dataCall);
+ SetupDataCallResult result = (SetupDataCallResult) ret;
+ writeOnSetupDataCallResponse(phoneId, rilSerial, rilError, rilRequest, result);
break;
case RIL_REQUEST_DEACTIVATE_DATA_CALL:
writeOnDeactivateDataCallResponse(phoneId, rilError);
diff --git a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
index ade427b..0943b78 100755
--- a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -44,7 +44,6 @@
import com.android.internal.telephony.PhoneNotifier;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.uicc.IccFileHandler;
import java.util.ArrayList;
@@ -416,14 +415,6 @@
}
@Override
- public void getDataCallList(Message response) {
- }
-
- public List<DataConnection> getCurrentDataConnectionList () {
- return null;
- }
-
- @Override
public void updateServiceLocation() {
}
diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommands.java b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
index ff8c0a8..cc9886f 100644
--- a/src/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/src/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -17,11 +17,10 @@
package com.android.internal.telephony.test;
import android.hardware.radio.V1_0.DataRegStateResult;
+import android.hardware.radio.V1_0.SetupDataCallResult;
import android.hardware.radio.V1_0.VoiceRegStateResult;
import android.net.KeepalivePacketData;
-import android.net.LinkAddress;
import android.net.LinkProperties;
-import android.net.NetworkUtils;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
@@ -35,6 +34,7 @@
import android.telephony.CellInfoGsm;
import android.telephony.IccOpenLogicalChannelResponse;
import android.telephony.ImsiEncryptionInfo;
+import android.telephony.NetworkRegistrationState;
import android.telephony.NetworkScanRequest;
import android.telephony.Rlog;
import android.telephony.ServiceState;
@@ -61,7 +61,6 @@
import com.android.internal.telephony.uicc.IccSlotStatus;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -120,10 +119,17 @@
int mNetworkType;
String mPin2Code;
boolean mSsnNotifyOn = false;
- private int mVoiceRegState = ServiceState.RIL_REG_STATE_HOME;
+ private int mVoiceRegState = NetworkRegistrationState.REG_STATE_HOME;
private int mVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
- private int mDataRegState = ServiceState.RIL_REG_STATE_HOME;
+ private int mDataRegState = NetworkRegistrationState.REG_STATE_HOME;
private int mDataRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_UMTS;
+ public boolean mCssSupported;
+ public int mRoamingIndicator;
+ public int mSystemIsInPrl;
+ public int mDefaultRoamingIndicator;
+ public int mReasonForDenial;
+ public int mMaxDataCalls;
+
private SignalStrength mSignalStrength;
private List<CellInfo> mCellInfoList;
private int[] mImsRegState;
@@ -138,7 +144,7 @@
int mNextCallFailCause = CallFailCause.NORMAL_CLEARING;
private boolean mDcSuccess = true;
- private DataCallResponse mDcResponse;
+ private SetupDataCallResult mSetupDataCallResult;
private boolean mIsRadioPowerFailResponse = false;
//***** Constructor
@@ -958,6 +964,11 @@
VoiceRegStateResult ret = new VoiceRegStateResult();
ret.regState = mVoiceRegState;
ret.rat = mVoiceRadioTech;
+ ret.cssSupported = mCssSupported;
+ ret.roamingIndicator = mRoamingIndicator;
+ ret.systemIsInPrl = mSystemIsInPrl;
+ ret.defaultRoamingIndicator = mDefaultRoamingIndicator;
+ ret.reasonForDenial = mReasonForDenial;
resultSuccess(result, ret);
}
@@ -984,6 +995,8 @@
DataRegStateResult ret = new DataRegStateResult();
ret.regState = mDataRegState;
ret.rat = mDataRadioTech;
+ ret.maxDataCalls = mMaxDataCalls;
+ ret.reasonDataDenied = mReasonForDenial;
resultSuccess(result, ret);
}
@@ -1111,8 +1124,8 @@
unimplemented(response);
}
- public void setDataCallResponse(final boolean success, final DataCallResponse dcResponse) {
- mDcResponse = dcResponse;
+ public void setDataCallResult(final boolean success, final SetupDataCallResult dcResult) {
+ mSetupDataCallResult = dcResult;
mDcSuccess = success;
}
@@ -1131,22 +1144,30 @@
SimulatedCommandsVerifier.getInstance().setupDataCall(accessNetworkType, dataProfile,
isRoaming, allowRoaming, reason, linkProperties, result);
- if (mDcResponse == null) {
+ if (mSetupDataCallResult == null) {
try {
- mDcResponse = new DataCallResponse(0, -1, 1, 2, "IP", "rmnet_data7",
- Arrays.asList(new LinkAddress("12.34.56.78/32")),
- Arrays.asList(NetworkUtils.numericToInetAddress("98.76.54.32")),
- Arrays.asList(NetworkUtils.numericToInetAddress("11.22.33.44")),
- null, 1440);
+ mSetupDataCallResult = new SetupDataCallResult();
+ mSetupDataCallResult.status = 0;
+ mSetupDataCallResult.suggestedRetryTime = -1;
+ mSetupDataCallResult.cid = 1;
+ mSetupDataCallResult.active = 2;
+ mSetupDataCallResult.type = "IP";
+ mSetupDataCallResult.ifname = "rmnet_data7";
+ mSetupDataCallResult.addresses = "12.34.56.78";
+ mSetupDataCallResult.dnses = "98.76.54.32";
+ mSetupDataCallResult.gateways = "11.22.33.44";
+ mSetupDataCallResult.pcscf = "";
+ mSetupDataCallResult.mtu = 1440;
} catch (Exception e) {
}
}
if (mDcSuccess) {
- resultSuccess(result, mDcResponse);
+ resultSuccess(result, mSetupDataCallResult);
} else {
- resultFail(result, mDcResponse, new RuntimeException("Setup data call failed!"));
+ resultFail(result, mSetupDataCallResult,
+ new RuntimeException("Setup data call failed!"));
}
}
diff --git a/src/java/com/android/internal/telephony/test/TestConferenceEventPackageParser.java b/src/java/com/android/internal/telephony/test/TestConferenceEventPackageParser.java
index 735ed17..62c2a77 100644
--- a/src/java/com/android/internal/telephony/test/TestConferenceEventPackageParser.java
+++ b/src/java/com/android/internal/telephony/test/TestConferenceEventPackageParser.java
@@ -16,7 +16,7 @@
package com.android.internal.telephony.test;
-import com.android.ims.ImsConferenceState;
+import android.telephony.ims.ImsConferenceState;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -26,7 +26,6 @@
import android.util.Log;
import android.util.Xml;
-import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -47,9 +46,9 @@
* </pre>
* <p>
* Note: This XML format is similar to the information stored in the
- * {@link com.android.ims.ImsConferenceState} parcelable. The {@code status} values expected in the
+ * {@link ImsConferenceState} parcelable. The {@code status} values expected in the
* XML are those found in the {@code ImsConferenceState} class (e.g.
- * {@link com.android.ims.ImsConferenceState#STATUS_CONNECTED}).
+ * {@link ImsConferenceState#STATUS_CONNECTED}).
* <p>
* Place a file formatted similar to above in /data/data/com.android.phone/files/ and invoke the
* following command while you have an ongoing IMS call:
@@ -79,10 +78,10 @@
/**
* Parses the conference event package XML file and returns an
- * {@link com.android.ims.ImsConferenceState} instance containing the participants described in
+ * {@link ImsConferenceState} instance containing the participants described in
* the XML file.
*
- * @return The {@link com.android.ims.ImsConferenceState} instance.
+ * @return The {@link ImsConferenceState} instance.
*/
public ImsConferenceState parse() {
ImsConferenceState conferenceState = new ImsConferenceState();
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 56b299a..fa41922 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -302,7 +302,7 @@
| PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS);
return getCarrierPrivilegeStatus(pInfo);
} catch (PackageManager.NameNotFoundException ex) {
- Rlog.e(LOG_TAG, "NameNotFoundException", ex);
+ log("Package " + packageName + " not found for carrier privilege status check");
}
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
}
@@ -690,4 +690,4 @@
return "UNKNOWN";
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/telephonytests/AndroidManifest.xml b/tests/telephonytests/AndroidManifest.xml
index 028b1e0..35ed2fb 100644
--- a/tests/telephonytests/AndroidManifest.xml
+++ b/tests/telephonytests/AndroidManifest.xml
@@ -38,5 +38,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
-
+ <uses-permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE"/>
+ <uses-permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE" />
</manifest>
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java b/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java
new file mode 100644
index 0000000..caa245f
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/ImsCompatTests.java
@@ -0,0 +1,79 @@
+/*
+ * 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 android.telephony.ims;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.aidl.IImsCallSessionListener;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.ims.internal.IImsMMTelFeature;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class ImsCompatTests {
+
+ TestMMTelFeatureCompat mCompatMmTel;
+ IImsMMTelFeature mCompatMmTelBinder;
+
+ TestImsCallSessionCompat mCompatCallSession;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mCompatMmTel = new TestMMTelFeatureCompat();
+ mCompatMmTelBinder = mCompatMmTel.getBinder();
+
+ mCompatCallSession = new TestImsCallSessionCompat();
+ }
+
+ @After
+ public void tearDown() {
+ mCompatMmTel = null;
+ mCompatMmTelBinder = null;
+
+ mCompatCallSession = null;
+ }
+
+ @SmallTest
+ @Test
+ public void testCreateCallSessionCompat() throws Exception {
+ mCompatMmTelBinder.createCallSession(0, new ImsCallProfile());
+ assertTrue(mCompatMmTel.isCreateCallSessionCalled);
+ }
+
+ @SmallTest
+ @Test
+ public void testListenerCompatLayer() throws Exception {
+ IImsCallSessionListener listener = mock(IImsCallSessionListener.class);
+ ImsReasonInfo info = new ImsReasonInfo();
+ mCompatCallSession.setListener(listener);
+
+ mCompatCallSession.mListener.callSessionTerminated(null, info);
+
+ verify(listener).callSessionTerminated(eq(info));
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
index 9bd7d6e..07d3223 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsFeatureTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -17,13 +17,17 @@
package android.telephony.ims;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
-import android.os.IInterface;
+import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.internal.IImsFeatureStatusCallback;
@@ -33,71 +37,198 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class ImsFeatureTest {
- private TestImsFeature mTestImsService;
+ private TestImsFeature mTestImsFeature;
+ private ImsFeature.CapabilityCallback mCapabilityCallback;
@Mock
private IImsFeatureStatusCallback mTestStatusCallback;
@Mock
private IImsFeatureStatusCallback mTestStatusCallback2;
- private class TestImsFeature extends ImsFeature {
-
- public void testSetFeatureState(int featureState) {
- setFeatureState(featureState);
- }
-
- @Override
- public void onFeatureReady() {
-
- }
-
- @Override
- public void onFeatureRemoved() {
-
- }
-
- @Override
- public IInterface getBinder() {
- return null;
- }
- }
-
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTestImsService = new TestImsFeature();
+ mTestImsFeature = new TestImsFeature();
+ mCapabilityCallback = Mockito.spy(new ImsFeature.CapabilityCallback());
+ mTestImsFeature.addCapabilityCallback(mCapabilityCallback);
}
@After
public void tearDown() {
- mTestImsService = null;
+ mTestImsFeature = null;
+ mCapabilityCallback = null;
}
@Test
@SmallTest
public void testSetCallbackAndNotify() throws Exception {
- mTestImsService.addImsFeatureStatusCallback(mTestStatusCallback);
- mTestImsService.addImsFeatureStatusCallback(mTestStatusCallback2);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
- verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_NOT_AVAILABLE));
- verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_NOT_AVAILABLE));
+ verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
+ verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
}
@Test
@SmallTest
public void testSetFeatureAndCheckCallback() throws Exception {
- mTestImsService.addImsFeatureStatusCallback(mTestStatusCallback);
- mTestImsService.addImsFeatureStatusCallback(mTestStatusCallback2);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
+ mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
- mTestImsService.testSetFeatureState(ImsFeature.STATE_READY);
+ mTestImsFeature.testSetFeatureState(ImsFeature.STATE_READY);
verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
- assertEquals(ImsFeature.STATE_READY, mTestImsService.getFeatureState());
+ assertEquals(ImsFeature.STATE_READY, mTestImsFeature.getFeatureState());
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigAdd() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_1));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigAddMultiple() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigHasMultiple() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ assertTrue(c.isCapable(
+ TestImsFeature.CAPABILITY_TEST_1 | TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityConfigRemove() throws Exception {
+ ImsFeature.Capabilities c = new ImsFeature.Capabilities();
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+ c.removeCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+
+ assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
+ }
+
+ @SmallTest
+ @Test
+ public void testSetCapabilityConfig() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ mTestImsFeature.requestChangeEnabledCapabilities(request, null);
+
+ assertEquals(request, mTestImsFeature.lastRequest);
+ }
+
+
+ @SmallTest
+ @Test
+ public void testSetCapabilityConfigError() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ mTestImsFeature.setCapabilitiesResult = ImsFeature.CAPABILITY_ERROR_GENERIC;
+ mTestImsFeature.requestChangeEnabledCapabilities(request, mCapabilityCallback);
+
+ verify(mCapabilityCallback).onChangeCapabilityConfigurationError(
+ eq(TestImsFeature.CAPABILITY_TEST_1),
+ eq(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN),
+ eq(ImsFeature.CAPABILITY_ERROR_GENERIC));
+ assertEquals(request, mTestImsFeature.lastRequest);
+ }
+
+ @SmallTest
+ @Test
+ public void testNotifyCapabilityStatusChanged() throws Exception {
+ ImsFeature.Capabilities status =
+ new ImsFeature.Capabilities();
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ mTestImsFeature.capabilitiesStatusChanged(status);
+
+ assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
+ }
+
+ @SmallTest
+ @Test
+ public void testNotifyCapabilityStatusChangedCallback() throws Exception {
+ ImsFeature.Capabilities status =
+ new ImsFeature.Capabilities();
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
+ status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
+
+ mTestImsFeature.capabilitiesStatusChanged(status);
+
+ assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
+ verify(mCapabilityCallback).onCapabilitiesStatusChanged(eq(status));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityChangeContainsFullSets() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1
+ | TestImsFeature.CAPABILITY_TEST_2,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+ request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_2,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(TestImsFeature.CAPABILITY_TEST_1,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+
+ mTestImsFeature.changeEnabledCapabilities(request, /*Callback*/null);
+
+ assertTrue(request.getCapabilitiesToDisable().containsAll(
+ mTestImsFeature.lastRequest.getCapabilitiesToDisable()));
+ assertTrue(request.getCapabilitiesToEnable().containsAll(
+ mTestImsFeature.lastRequest.getCapabilitiesToEnable()));
+ }
+
+ @SmallTest
+ @Test
+ public void testCapabilityChangeRequestParcel() throws Exception {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
+ // add some capabilities
+ request.addCapabilitiesToEnableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+ request.addCapabilitiesToEnableForTech(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO
+ | MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ Parcel p = Parcel.obtain();
+ request.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ CapabilityChangeRequest result =
+ CapabilityChangeRequest.CREATOR.createFromParcel(p);
+ p.recycle();
+
+ assertEquals(request, result);
}
}
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index 77c81af..65cb5f7 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -28,15 +28,13 @@
import android.os.RemoteException;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.ServiceState;
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
+import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsRegistrationCallback;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
index 6936362..37fe7b7 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -16,8 +16,6 @@
package android.telephony.ims;
-import static com.android.internal.telephony.ims.ImsResolver.SERVICE_INTERFACE;
-
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@@ -25,29 +23,29 @@
import static junit.framework.Assert.fail;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.aidl.IImsServiceController;
import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.MMTelFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.SparseArray;
import com.android.ims.ImsManager;
import com.android.ims.internal.IImsFeatureStatusCallback;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsServiceController;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
/**
* Unit tests for ImsService
@@ -61,21 +59,22 @@
private TestImsService mTestImsService;
private IImsServiceController mTestImsServiceBinder;
- @Mock
private Context mMockContext;
- @Mock
private IImsFeatureStatusCallback mTestCallback;
@Before
public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
+ mMockContext = mock(Context.class);
+ mTestCallback = mock(IImsFeatureStatusCallback.class);
mTestImsService = new TestImsService(mMockContext);
mTestImsServiceBinder = (IImsServiceController) mTestImsService.onBind(
- new Intent(SERVICE_INTERFACE));
+ new Intent(ImsService.SERVICE_INTERFACE));
}
@After
public void tearDown() throws Exception {
+ mMockContext = null;
+ mTestCallback = null;
mTestImsService = null;
mTestImsServiceBinder = null;
}
@@ -83,45 +82,46 @@
@Test
@SmallTest
public void testCreateMMTelFeature() throws RemoteException {
- IImsMMTelFeature f = mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
- mTestImsService.mTestMMTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
+ IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
+ mTestImsService.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
- ImsFeature featureToVerify = features.get(ImsFeature.MMTEL);
- MMTelFeature testMMTelFeature = null;
- if (featureToVerify instanceof MMTelFeature) {
- testMMTelFeature = (MMTelFeature) featureToVerify;
+ ImsFeature featureToVerify = features.get(ImsFeature.FEATURE_MMTEL);
+ MmTelFeature testMMTelFeature = null;
+ if (featureToVerify instanceof MmTelFeature) {
+ testMMTelFeature = (MmTelFeature) featureToVerify;
} else {
fail();
}
- assertEquals(mTestImsService.mSpyMMTelFeature, testMMTelFeature);
+ assertEquals(mTestImsService.mSpyMmTelFeature, testMMTelFeature);
// Verify that upon creating a feature, we assign the callback and get the set feature state
// when querying it.
- verify(mTestImsService.mSpyMMTelFeature).addImsFeatureStatusCallback(eq(mTestCallback));
- assertEquals(ImsFeature.STATE_READY, f.getFeatureStatus());
+ verify(mTestImsService.mSpyMmTelFeature).addImsFeatureStatusCallback(eq(mTestCallback));
+ assertEquals(ImsFeature.STATE_READY, f.getFeatureState());
}
@Test
@SmallTest
public void testRemoveMMTelFeature() throws RemoteException {
- mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
- mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.MMTEL, mTestCallback);
+ mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
+ mTestCallback);
- verify(mTestImsService.mSpyMMTelFeature).onFeatureRemoved();
- verify(mTestImsService.mSpyMMTelFeature).removeImsFeatureStatusCallback(mTestCallback);
+ verify(mTestImsService.mSpyMmTelFeature).onFeatureRemoved();
+ verify(mTestImsService.mSpyMmTelFeature).removeImsFeatureStatusCallback(mTestCallback);
SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
- assertNull(features.get(ImsFeature.MMTEL));
+ assertNull(features.get(ImsFeature.FEATURE_MMTEL));
}
@Test
@SmallTest
public void testCallMethodOnCreatedFeature() throws RemoteException {
- IImsMMTelFeature f = mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
+ IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
- f.isConnected(0/*callSessionType*/, 0 /*callType*/);
+ f.getUtInterface();
- assertTrue(mTestImsService.mTestMMTelFeature.isConnectedCalled);
+ assertTrue(mTestImsService.mTestMmTelFeature.isUtInterfaceCalled);
}
/**
@@ -131,9 +131,9 @@
@Test
@SmallTest
public void testImsServiceUpSentCompat() throws RemoteException {
- mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
- mTestImsService.mSpyMMTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
+ mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext).sendBroadcast(intentCaptor.capture());
@@ -153,9 +153,9 @@
@Test
@SmallTest
public void testImsServiceDownSentCompatInitializing() throws RemoteException {
- mTestImsServiceBinder.createMMTelFeature(TEST_SLOT_0, mTestCallback);
+ mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
- mTestImsService.mSpyMMTelFeature.sendSetFeatureState(ImsFeature.STATE_INITIALIZING);
+ mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_INITIALIZING);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext).sendBroadcast(intentCaptor.capture());
@@ -168,6 +168,23 @@
}
}
+ /**
+ * Tests that the ImsService will return the correct ImsFeatureConfiguration when queried.
+ */
+ @Test
+ @SmallTest
+ public void testQuerySupportedImsFeatures() throws RemoteException {
+ ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
+ .addFeature(ImsFeature.FEATURE_MMTEL)
+ .addFeature(ImsFeature.FEATURE_RCS)
+ .build();
+ mTestImsService.testFeatureConfig = config;
+
+ ImsFeatureConfiguration result = mTestImsServiceBinder.querySupportedImsFeatures();
+
+ assertEquals(config, result);
+ }
+
private void verifyServiceDownSent(Intent testIntent) {
assertEquals(ImsManager.ACTION_IMS_SERVICE_DOWN, testIntent.getAction());
assertEquals(TEST_SLOT_0, testIntent.getIntExtra(ImsManager.EXTRA_PHONE_ID, -1));
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
similarity index 76%
rename from tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java
rename to tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index c2cdd75..ccbc251 100644
--- a/tests/telephonytests/src/android/telephony/ims/internal/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,23 +14,24 @@
* limitations under the License.
*/
-package android.telephony.ims.internal;
+package android.telephony.ims;
import static junit.framework.Assert.assertEquals;
+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.support.test.runner.AndroidJUnit4;
-import android.telephony.ims.internal.aidl.IImsMmTelFeature;
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsCallSessionImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.ImsCallSession;
import org.junit.After;
import org.junit.Before;
@@ -45,7 +46,7 @@
private static final int TEST_CAPABILITY = 1;
private static final int TEST_RADIO_TECH = 0;
- private TestMmTelFeature mFeature;
+ private android.telephony.ims.TestMmTelFeature mFeature;
private IImsMmTelFeature mFeatureBinder;
private ImsFeature.CapabilityCallback mCapabilityCallback;
private MmTelFeature.Listener mListener;
@@ -81,12 +82,13 @@
@Test
public void testNewIncomingCall() throws Exception {
IImsCallSession sessionBinder = Mockito.mock(IImsCallSession.class);
- ImsCallSession session = new ImsCallSession(sessionBinder);
+ ImsCallSessionImplBase session = new ImsCallSessionImplBase();
+ session.setServiceImpl(sessionBinder);
mFeature.incomingCall(session);
- ArgumentCaptor<ImsCallSession> captor = ArgumentCaptor.forClass(ImsCallSession.class);
- verify(mListener).onIncomingCall(captor.capture());
+ ArgumentCaptor<IImsCallSession> captor = ArgumentCaptor.forClass(IImsCallSession.class);
+ verify(mListener).onIncomingCall(captor.capture(), any());
- assertEquals(sessionBinder, captor.getValue().getSession());
+ assertEquals(sessionBinder, captor.getValue());
}
}
diff --git a/tests/telephonytests/src/android/telephony/ims/TestImsCallSessionCompat.java b/tests/telephonytests/src/android/telephony/ims/TestImsCallSessionCompat.java
new file mode 100644
index 0000000..b3c5e00
--- /dev/null
+++ b/tests/telephonytests/src/android/telephony/ims/TestImsCallSessionCompat.java
@@ -0,0 +1,32 @@
+/*
+ * 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 android.telephony.ims;
+
+import android.telephony.ims.compat.stub.ImsCallSessionImplBase;
+
+import com.android.ims.internal.IImsCallSessionListener;
+
+public class TestImsCallSessionCompat extends ImsCallSessionImplBase {
+
+
+ IImsCallSessionListener mListener;
+
+ @Override
+ public void setListener(IImsCallSessionListener listener) {
+ mListener = listener;
+ }
+}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java b/tests/telephonytests/src/android/telephony/ims/TestImsFeature.java
similarity index 89%
rename from tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java
rename to tests/telephonytests/src/android/telephony/ims/TestImsFeature.java
index efbf95e..ec09b4a 100644
--- a/tests/telephonytests/src/android/telephony/ims/internal/TestImsFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestImsFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package android.telephony.ims.internal;
+package android.telephony.ims;
import android.os.IInterface;
-import android.telephony.ims.internal.feature.CapabilityChangeRequest;
-import android.telephony.ims.internal.feature.ImsFeature;
+import android.telephony.ims.feature.CapabilityChangeRequest;
+import android.telephony.ims.feature.ImsFeature;
public class TestImsFeature extends ImsFeature {
diff --git a/tests/telephonytests/src/android/telephony/ims/TestImsService.java b/tests/telephonytests/src/android/telephony/ims/TestImsService.java
index 380d70a..944514a 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestImsService.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestImsService.java
@@ -16,43 +16,46 @@
package android.telephony.ims;
+import static org.mockito.Mockito.spy;
+
import android.content.Context;
-import android.telephony.ims.feature.MMTelFeature;
+import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.stub.ImsFeatureConfiguration;
import org.mockito.MockitoAnnotations;
-import static org.mockito.Mockito.spy;
-
/**
* Test ImsService used by mockito to verify functionality.
*/
-public class TestImsService extends ImsService {
+public class TestImsService extends android.telephony.ims.ImsService {
- public TestMMTelFeature mSpyMMTelFeature;
- public TestMMTelFeature mTestMMTelFeature;
+ public TestMmTelFeature mSpyMmTelFeature;
+ public TestMmTelFeature mTestMmTelFeature;
+
+ public ImsFeatureConfiguration testFeatureConfig;
public TestImsService(Context context) {
attachBaseContext(context);
MockitoAnnotations.initMocks(this);
// Must create real MMTelFeature to initialize ImsFeature objects.
- mTestMMTelFeature = new TestMMTelFeature();
- mSpyMMTelFeature = spy(mTestMMTelFeature);
+ mTestMmTelFeature = new TestMmTelFeature();
+ mSpyMmTelFeature = spy(mTestMmTelFeature);
}
@Override
- public MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) {
+ public MmTelFeature createMmTelFeature(int slotId) {
+ return mSpyMmTelFeature;
+ }
+
+ @Override
+ public RcsFeature createRcsFeature(int slotId) {
return null;
}
@Override
- public MMTelFeature onCreateMMTelImsFeature(int slotId) {
- return mSpyMMTelFeature;
- }
-
- @Override
- public RcsFeature onCreateRcsFeature(int slotId) {
- return null;
+ public ImsFeatureConfiguration querySupportedImsFeatures() {
+ return testFeatureConfig;
}
}
diff --git a/tests/telephonytests/src/android/telephony/ims/TestMMTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMMTelFeatureCompat.java
similarity index 60%
rename from tests/telephonytests/src/android/telephony/ims/TestMMTelFeature.java
rename to tests/telephonytests/src/android/telephony/ims/TestMMTelFeatureCompat.java
index 9e944bf..ee9ac82 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestMMTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMMTelFeatureCompat.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -16,18 +16,22 @@
package android.telephony.ims;
-import android.telephony.ims.feature.MMTelFeature;
+import android.telephony.ims.compat.feature.MMTelFeature;
+
+import com.android.ims.internal.IImsCallSession;
+import com.android.ims.internal.IImsCallSessionListener;
/**
* MMTelFeature implementation used by mockito to test functionality.
*/
-public class TestMMTelFeature extends MMTelFeature {
+public class TestMMTelFeatureCompat extends MMTelFeature {
public boolean isConnectedCalled = false;
+ public boolean isCreateCallSessionCalled = false;
@Override
- public boolean isConnected(int callSessionType, int callType) {
+ public boolean isConnected(int callSessinType, int callType) {
isConnectedCalled = true;
return true;
}
@@ -43,4 +47,12 @@
public void sendSetFeatureState(int state) {
setFeatureState(state);
}
+
+ // Compatibility Method
+ @Override
+ public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
+ IImsCallSessionListener listener) {
+ isCreateCallSessionCalled = true;
+ return null;
+ }
}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
similarity index 80%
rename from tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java
rename to tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
index e960957..795d1c0 100644
--- a/tests/telephonytests/src/android/telephony/ims/internal/TestMmTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,20 +14,18 @@
* limitations under the License.
*/
-package android.telephony.ims.internal;
+package android.telephony.ims;
import android.os.RemoteException;
-import android.telephony.ims.internal.feature.CapabilityChangeRequest;
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.feature.MmTelFeature;
+import android.telephony.ims.feature.CapabilityChangeRequest;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsCallSessionImplBase;
import android.telephony.ims.stub.ImsEcbmImplBase;
import android.telephony.ims.stub.ImsMultiEndpointImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.ImsUtImplBase;
-import com.android.ims.ImsCallProfile;
-import com.android.ims.internal.ImsCallSession;
-
public class TestMmTelFeature extends MmTelFeature {
public boolean queryConfigurationResult = false;
@@ -35,8 +33,8 @@
public CapabilityChangeRequest lastRequest;
public boolean isUtInterfaceCalled = false;
- public void incomingCall(ImsCallSession c) throws RemoteException {
- notifyIncomingCall(c);
+ public void incomingCall(ImsCallSessionImplBase c) throws RemoteException {
+ notifyIncomingCall(c, null);
}
@Override
@@ -45,9 +43,8 @@
}
@Override
- public ImsCallSession createCallSession(ImsCallProfile profile,
- ImsCallSessionListener listener) {
- return super.createCallSession(profile, listener);
+ public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) {
+ return super.createCallSession(profile);
}
@Override
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java
deleted file mode 100644
index 703eede..0000000
--- a/tests/telephonytests/src/android/telephony/ims/internal/ImsFeatureTest.java
+++ /dev/null
@@ -1,234 +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 android.telephony.ims.internal;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-
-import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
-import android.telephony.ims.internal.feature.CapabilityChangeRequest;
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.feature.MmTelFeature;
-import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.ims.internal.IImsFeatureStatusCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class ImsFeatureTest {
-
- private TestImsFeature mTestImsFeature;
- private ImsFeature.CapabilityCallback mCapabilityCallback;
-
- @Mock
- private IImsFeatureStatusCallback mTestStatusCallback;
- @Mock
- private IImsFeatureStatusCallback mTestStatusCallback2;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mTestImsFeature = new TestImsFeature();
- mCapabilityCallback = Mockito.spy(new ImsFeature.CapabilityCallback());
- mTestImsFeature.addCapabilityCallback(mCapabilityCallback);
- }
-
- @After
- public void tearDown() {
- mTestImsFeature = null;
- mCapabilityCallback = null;
- }
-
- @Test
- @SmallTest
- public void testSetCallbackAndNotify() throws Exception {
- mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
- mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
-
- verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
- verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_UNAVAILABLE));
- }
-
- @Test
- @SmallTest
- public void testSetFeatureAndCheckCallback() throws Exception {
- mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback);
- mTestImsFeature.addImsFeatureStatusCallback(mTestStatusCallback2);
-
- mTestImsFeature.testSetFeatureState(ImsFeature.STATE_READY);
-
- verify(mTestStatusCallback).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
- verify(mTestStatusCallback2).notifyImsFeatureStatus(eq(ImsFeature.STATE_READY));
- assertEquals(ImsFeature.STATE_READY, mTestImsFeature.getFeatureState());
- }
-
- @SmallTest
- @Test
- public void testCapabilityConfigAdd() throws Exception {
- ImsFeature.Capabilities c = new ImsFeature.Capabilities();
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
-
- assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_1));
- }
-
- @SmallTest
- @Test
- public void testCapabilityConfigAddMultiple() throws Exception {
- ImsFeature.Capabilities c = new ImsFeature.Capabilities();
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
-
- assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
- }
-
- @SmallTest
- @Test
- public void testCapabilityConfigHasMultiple() throws Exception {
- ImsFeature.Capabilities c = new ImsFeature.Capabilities();
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
-
- assertTrue(c.isCapable(
- TestImsFeature.CAPABILITY_TEST_1 | TestImsFeature.CAPABILITY_TEST_2));
- }
-
- @SmallTest
- @Test
- public void testCapabilityConfigRemove() throws Exception {
- ImsFeature.Capabilities c = new ImsFeature.Capabilities();
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
- c.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
- c.removeCapabilities(TestImsFeature.CAPABILITY_TEST_1);
-
- assertTrue(c.isCapable(TestImsFeature.CAPABILITY_TEST_2));
- }
-
- @SmallTest
- @Test
- public void testSetCapabilityConfig() throws Exception {
- CapabilityChangeRequest request = new CapabilityChangeRequest();
- request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
- ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
-
- mTestImsFeature.requestChangeEnabledCapabilities(request, null);
-
- assertEquals(request, mTestImsFeature.lastRequest);
- }
-
-
- @SmallTest
- @Test
- public void testSetCapabilityConfigError() throws Exception {
- CapabilityChangeRequest request = new CapabilityChangeRequest();
- request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1,
- ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
-
- mTestImsFeature.setCapabilitiesResult = ImsFeature.CAPABILITY_ERROR_GENERIC;
- mTestImsFeature.requestChangeEnabledCapabilities(request, mCapabilityCallback);
-
- verify(mCapabilityCallback).onChangeCapabilityConfigurationError(
- eq(TestImsFeature.CAPABILITY_TEST_1),
- eq(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN),
- eq(ImsFeature.CAPABILITY_ERROR_GENERIC));
- assertEquals(request, mTestImsFeature.lastRequest);
- }
-
- @SmallTest
- @Test
- public void testNotifyCapabilityStatusChanged() throws Exception {
- ImsFeature.Capabilities status =
- new ImsFeature.Capabilities();
- status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
- status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
-
- mTestImsFeature.capabilitiesStatusChanged(status);
-
- assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
- }
-
- @SmallTest
- @Test
- public void testNotifyCapabilityStatusChangedCallback() throws Exception {
- ImsFeature.Capabilities status =
- new ImsFeature.Capabilities();
- status.addCapabilities(TestImsFeature.CAPABILITY_TEST_1);
- status.addCapabilities(TestImsFeature.CAPABILITY_TEST_2);
-
- mTestImsFeature.capabilitiesStatusChanged(status);
-
- assertEquals(status.getMask(), mTestImsFeature.queryCapabilityStatus().getMask());
- verify(mCapabilityCallback).onCapabilitiesStatusChanged(eq(status));
- }
-
- @SmallTest
- @Test
- public void testCapabilityChangeContainsFullSets() throws Exception {
- CapabilityChangeRequest request = new CapabilityChangeRequest();
- request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_1
- | TestImsFeature.CAPABILITY_TEST_2,
- ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
- request.addCapabilitiesToEnableForTech(TestImsFeature.CAPABILITY_TEST_2,
- ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
- request.addCapabilitiesToDisableForTech(TestImsFeature.CAPABILITY_TEST_1,
- ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
-
- mTestImsFeature.changeEnabledCapabilities(request, /*Callback*/null);
-
- assertTrue(request.getCapabilitiesToDisable().containsAll(
- mTestImsFeature.lastRequest.getCapabilitiesToDisable()));
- assertTrue(request.getCapabilitiesToEnable().containsAll(
- mTestImsFeature.lastRequest.getCapabilitiesToEnable()));
- }
-
- @SmallTest
- @Test
- public void testCapabilityChangeRequestParcel() throws Exception {
- CapabilityChangeRequest request = new CapabilityChangeRequest();
- // add some capabilities
- request.addCapabilitiesToEnableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
- ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
- request.addCapabilitiesToEnableForTech(
- MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO
- | MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
- ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
- request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
- ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
- request.addCapabilitiesToDisableForTech(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT,
- ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
-
- Parcel p = Parcel.obtain();
- request.writeToParcel(p, 0);
- p.setDataPosition(0);
- CapabilityChangeRequest result =
- CapabilityChangeRequest.CREATOR.createFromParcel(p);
- p.recycle();
-
- assertEquals(request, result);
- }
-}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java b/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java
deleted file mode 100644
index f4c1149..0000000
--- a/tests/telephonytests/src/android/telephony/ims/internal/ImsServiceTest.java
+++ /dev/null
@@ -1,199 +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 android.telephony.ims.internal;
-
-import static com.android.internal.telephony.ims.ImsResolver.SERVICE_INTERFACE;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.RemoteException;
-import android.support.test.runner.AndroidJUnit4;
-import android.telephony.ims.internal.aidl.IImsMmTelFeature;
-import android.telephony.ims.internal.aidl.IImsServiceController;
-import android.telephony.ims.internal.feature.ImsFeature;
-import android.telephony.ims.internal.feature.MmTelFeature;
-import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.SparseArray;
-
-import com.android.ims.ImsManager;
-import com.android.ims.internal.IImsFeatureStatusCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-/**
- * Unit tests for ImsService
- */
-@RunWith(AndroidJUnit4.class)
-public class ImsServiceTest {
-
- private static final int TEST_SLOT_0 = 0;
- private static final int TEST_SLOT_1 = 1;
-
- private TestImsService mTestImsService;
- private IImsServiceController mTestImsServiceBinder;
-
- private Context mMockContext;
- private IImsFeatureStatusCallback mTestCallback;
-
- @Before
- public void setUp() throws Exception {
- mMockContext = mock(Context.class);
- mTestCallback = mock(IImsFeatureStatusCallback.class);
- mTestImsService = new TestImsService(mMockContext);
- mTestImsServiceBinder = (IImsServiceController) mTestImsService.onBind(
- new Intent(SERVICE_INTERFACE));
- }
-
- @After
- public void tearDown() throws Exception {
- mMockContext = null;
- mTestCallback = null;
- mTestImsService = null;
- mTestImsServiceBinder = null;
- }
-
- @Test
- @SmallTest
- public void testCreateMMTelFeature() throws RemoteException {
- IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
- mTestImsService.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
-
- SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
- ImsFeature featureToVerify = features.get(ImsFeature.FEATURE_MMTEL);
- MmTelFeature testMMTelFeature = null;
- if (featureToVerify instanceof MmTelFeature) {
- testMMTelFeature = (MmTelFeature) featureToVerify;
- } else {
- fail();
- }
- assertEquals(mTestImsService.mSpyMmTelFeature, testMMTelFeature);
- // Verify that upon creating a feature, we assign the callback and get the set feature state
- // when querying it.
- verify(mTestImsService.mSpyMmTelFeature).addImsFeatureStatusCallback(eq(mTestCallback));
- assertEquals(ImsFeature.STATE_READY, f.getFeatureState());
- }
-
- @Test
- @SmallTest
- public void testRemoveMMTelFeature() throws RemoteException {
- mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
-
- mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
- mTestCallback);
-
- verify(mTestImsService.mSpyMmTelFeature).onFeatureRemoved();
- verify(mTestImsService.mSpyMmTelFeature).removeImsFeatureStatusCallback(mTestCallback);
- SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
- assertNull(features.get(ImsFeature.FEATURE_MMTEL));
- }
-
- @Test
- @SmallTest
- public void testCallMethodOnCreatedFeature() throws RemoteException {
- IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
-
- f.getUtInterface();
-
- assertTrue(mTestImsService.mTestMmTelFeature.isUtInterfaceCalled);
- }
-
- /**
- * Tests that the new ImsService still sends the IMS_SERVICE_UP broadcast when the feature is
- * set to ready.
- */
- @Test
- @SmallTest
- public void testImsServiceUpSentCompat() throws RemoteException {
- mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
-
- mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
-
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mMockContext).sendBroadcast(intentCaptor.capture());
- try {
- // Verify IMS_SERVICE_UP is sent
- assertNotNull(intentCaptor.getValue());
- verifyServiceUpSent(intentCaptor.getValue());
- } catch (IndexOutOfBoundsException e) {
- fail("Did not receive all intents");
- }
- }
-
- /**
- * Tests that the new ImsService still sends the IMS_SERVICE_DOWN broadcast when the feature is
- * set to initializing.
- */
- @Test
- @SmallTest
- public void testImsServiceDownSentCompatInitializing() throws RemoteException {
- mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, mTestCallback);
-
- mTestImsService.mSpyMmTelFeature.sendSetFeatureState(ImsFeature.STATE_INITIALIZING);
-
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mMockContext).sendBroadcast(intentCaptor.capture());
- try {
- // IMS_SERVICE_DOWN is sent when the service is STATE_INITIALIZING.
- assertNotNull(intentCaptor.getValue());
- verifyServiceDownSent(intentCaptor.getValue());
- } catch (IndexOutOfBoundsException e) {
- fail("Did not receive all intents");
- }
- }
-
- /**
- * Tests that the ImsService will return the correct ImsFeatureConfiguration when queried.
- */
- @Test
- @SmallTest
- public void testQuerySupportedImsFeatures() throws RemoteException {
- ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder()
- .addFeature(ImsFeature.FEATURE_MMTEL)
- .addFeature(ImsFeature.FEATURE_RCS)
- .build();
- mTestImsService.testFeatureConfig = config;
-
- ImsFeatureConfiguration result = mTestImsServiceBinder.querySupportedImsFeatures();
-
- assertEquals(config, result);
- }
-
- private void verifyServiceDownSent(Intent testIntent) {
- assertEquals(ImsManager.ACTION_IMS_SERVICE_DOWN, testIntent.getAction());
- assertEquals(TEST_SLOT_0, testIntent.getIntExtra(ImsManager.EXTRA_PHONE_ID, -1));
- }
-
- private void verifyServiceUpSent(Intent testIntent) {
- assertEquals(ImsManager.ACTION_IMS_SERVICE_UP, testIntent.getAction());
- assertEquals(TEST_SLOT_0, testIntent.getIntExtra(ImsManager.EXTRA_PHONE_ID, -1));
- }
-}
diff --git a/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java b/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java
deleted file mode 100644
index 97dfff7..0000000
--- a/tests/telephonytests/src/android/telephony/ims/internal/TestImsService.java
+++ /dev/null
@@ -1,58 +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 android.telephony.ims.internal;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.telephony.ims.internal.feature.MmTelFeature;
-import android.telephony.ims.internal.feature.RcsFeature;
-import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
-
-/**
- * Test ImsService used by mockito to verify functionality.
- */
-
-public class TestImsService extends ImsService {
-
- public TestMmTelFeature mSpyMmTelFeature;
- public TestMmTelFeature mTestMmTelFeature;
-
- public ImsFeatureConfiguration testFeatureConfig;
-
- public TestImsService(Context context) {
- attachBaseContext(context);
- // Must create real MMTelFeature to initialize ImsFeature objects.
- mTestMmTelFeature = new TestMmTelFeature();
- mSpyMmTelFeature = spy(mTestMmTelFeature);
- }
-
- @Override
- public ImsFeatureConfiguration querySupportedImsFeatures() {
- return testFeatureConfig;
- }
-
- @Override
- public MmTelFeature createMmTelFeature(int slotId) {
- return mSpyMmTelFeature;
- }
-
- @Override
- public RcsFeature createRcsFeature(int slotId) {
- return null;
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/AnswerToResetTest.java b/tests/telephonytests/src/com/android/internal/telephony/AnswerToResetTest.java
new file mode 100644
index 0000000..d5dc47b
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/AnswerToResetTest.java
@@ -0,0 +1,321 @@
+/*
+ * 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 org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+
+public class AnswerToResetTest {
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestOddLength() {
+ String str = "3B02145";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNull(atr);
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestTooShortLength() {
+ String str = "3B";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNull(atr);
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestNoInterfaceByteNoHistoricalByte() {
+ String str = "3B00";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3B);
+ assertEquals(atr.getFormatByte(), (byte) 0x00);
+ assertTrue(atr.getInterfaceBytes().isEmpty());
+ assertEquals(atr.getHistoricalBytes().length, 0);
+ assertNull(atr.getCheckByte());
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestNoHistoricalByte() {
+ String str = "3F909580B1FE001F4297";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x90);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xB1);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x00, null, (byte) 0x1F);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 0);
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestNoInterfaceByte() {
+ String str = "3F078031A073BE211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x07);
+ assertTrue(atr.getInterfaceBytes().isEmpty());
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect));
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestSuccess() {
+ String str = "3F979580B1FE001F428031A073BE211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xB1);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x00, null, (byte) 0x1F);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestSuccessWithoutCheckByte() {
+ String str = "3F979580B0FE0010428031A073BE2117";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xB0);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x00, null, (byte) 0x10);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+
+ assertEquals(atr.getCheckByte(), null);
+ assertFalse(atr.isEuiccSupported());
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestFailWithoutCheckByte() {
+ String str = "3F979581B0FE0010428031A073BE2117";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNull(atr);
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestFailWithExtraByte() {
+ String str = "3F979580B1FE001F428031A073BE21179718";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNull(atr);
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestEuiccSupported() {
+ String str = "3F979580BFFE8210428031A073BE211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xBF);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x82, null, (byte) 0x10);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+
+ assertTrue(atr.isEuiccSupported());
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestEuiccSupportedWithLowerCaseString() {
+ String str = "3f979580bffe8210428031a073be211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xBF);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x82, null, (byte) 0x10);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+
+ assertTrue(atr.isEuiccSupported());
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestEuiccNotSupportedDueToIncorrectT() {
+ String str = "3F979580BEFE8210428031A073BE211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xBE);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x82, null, (byte) 0x10);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+
+ assertFalse(atr.isEuiccSupported());
+ }
+
+ @Test
+ @SmallTest
+ public void tesAnswerToRestEuiccNotSupportedDueToIncorrectTB() {
+ String str = "3F979580BFFE8110428031A073BE211797";
+ AnswerToReset atr = AnswerToReset.parseAtr(str);
+ assertNotNull(atr);
+ assertEquals(atr.getConventionByte(), (byte) 0x3F);
+ assertEquals(atr.getFormatByte(), (byte) 0x97);
+
+ assertEquals(atr.getInterfaceBytes().size(), 4);
+ AnswerToReset.InterfaceByte expect_t1 =
+ new AnswerToReset.InterfaceByte((byte) 0x95, null, null, (byte) 0x80);
+ AnswerToReset.InterfaceByte expect_t2 =
+ new AnswerToReset.InterfaceByte(null, null, null, (byte) 0xBF);
+ AnswerToReset.InterfaceByte expect_t3 =
+ new AnswerToReset.InterfaceByte((byte) 0xFE, (byte) 0x81, null, (byte) 0x10);
+ AnswerToReset.InterfaceByte expect_t4 =
+ new AnswerToReset.InterfaceByte((byte) 0x42, null, null, null);
+ ArrayList<AnswerToReset.InterfaceByte> expect_ib = new ArrayList<>(
+ Arrays.asList(expect_t1, expect_t2, expect_t3, expect_t4)
+ );
+ assertEquals(expect_ib, atr.getInterfaceBytes());
+
+ assertEquals(atr.getHistoricalBytes().length, 7);
+ byte[] expect_hb = new byte[]{
+ (byte) 0x80, (byte) 0x31, (byte) 0xA0, (byte) 0x73,
+ (byte) 0xBE, (byte) 0x21, (byte) 0x17};
+ assertTrue(Arrays.equals(atr.getHistoricalBytes(), expect_hb));
+
+ assertEquals(atr.getCheckByte(), Byte.valueOf((byte) 0x97));
+
+ assertFalse(atr.isEuiccSupported());
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
new file mode 100644
index 0000000..16bc535
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2016 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.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
+import android.os.RemoteException;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.INetworkService;
+import android.telephony.INetworkServiceCallback;
+import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkService;
+import android.telephony.NetworkServiceCallback;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.internal.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class CellularNetworkServiceTest extends TelephonyTest {
+ CellularNetworkService mCellularNetworkService;
+
+ @Mock
+ private INetworkServiceCallback mCallback;
+
+ private void addNetworkService() {
+ mCellularNetworkService = new CellularNetworkService();
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.packageName = "com.android.phone";
+ serviceInfo.permission = "android.permission.BIND_NETWORK_SERVICE";
+ IntentFilter filter = new IntentFilter();
+ mContextFixture.addService(
+ NetworkService.NETWORK_SERVICE_INTERFACE,
+ null,
+ "com.android.phone",
+ mCellularNetworkService.mBinder,
+ serviceInfo,
+ filter);
+ }
+ INetworkService.Stub mBinder;
+
+ @Before
+ public void setUp() throws Exception {
+
+ logd("CellularNetworkServiceTest +Setup!");
+ super.setUp("CellularNetworkServiceTest");
+
+ mContextFixture.putResource(R.string.config_wwan_network_service_package,
+ "com.android.phone");
+ addNetworkService();
+ mBinder = mCellularNetworkService.mBinder;
+ mBinder.createNetworkServiceProvider(0);
+
+ int dds = SubscriptionManager.getDefaultDataSubscriptionId();
+ doReturn(dds).when(mPhone).getSubId();
+
+ logd("CellularNetworkServiceTest -Setup!");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ @MediumTest
+ public void testGetNetworkRegistrationState() {
+ int voiceRegState = NetworkRegistrationState.REG_STATE_HOME;
+ int dataRegState = NetworkRegistrationState.REG_STATE_HOME;
+ int voiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
+ int dataRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_HSPA;
+ int domain = NetworkRegistrationState.DOMAIN_CS;
+
+ boolean cssSupported = true;
+ int roamingIndicator = 1;
+ int systemIsInPrl = 2;
+ int defaultRoamingIndicator = 3;
+ int reasonForDenial = 0;
+ int maxDataCalls = 4;
+ int[] availableServices = new int[] {
+ NetworkRegistrationState.SERVICE_TYPE_VOICE,
+ NetworkRegistrationState.SERVICE_TYPE_SMS,
+ NetworkRegistrationState.SERVICE_TYPE_VIDEO
+ };
+
+ mSimulatedCommands.setVoiceRegState(voiceRegState);
+ mSimulatedCommands.setVoiceRadioTech(voiceRadioTech);
+ mSimulatedCommands.setDataRegState(dataRegState);
+ mSimulatedCommands.setDataRadioTech(dataRadioTech);
+ mSimulatedCommands.mCssSupported = cssSupported;
+ mSimulatedCommands.mRoamingIndicator = roamingIndicator;
+ mSimulatedCommands.mSystemIsInPrl = systemIsInPrl;
+ mSimulatedCommands.mDefaultRoamingIndicator = defaultRoamingIndicator;
+ mSimulatedCommands.mReasonForDenial = reasonForDenial;
+ mSimulatedCommands.mMaxDataCalls = maxDataCalls;
+
+ mSimulatedCommands.notifyNetworkStateChanged();
+
+ try {
+ mBinder.getNetworkRegistrationState(0, domain, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ waitForMs(1000);
+
+ NetworkRegistrationState expectedState = new NetworkRegistrationState(
+ AccessNetworkConstants.TransportType.WWAN, domain, voiceRegState,
+ ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
+ false, availableServices, null, cssSupported,
+ roamingIndicator, systemIsInPrl, defaultRoamingIndicator);
+
+ try {
+ verify(mCallback, times(1)).onGetNetworkRegistrationStateComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ domain = NetworkRegistrationState.DOMAIN_PS;
+ availableServices = new int[] {NetworkRegistrationState.SERVICE_TYPE_DATA};
+ try {
+ mBinder.getNetworkRegistrationState(0, domain, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ waitForMs(1000);
+
+ expectedState = new NetworkRegistrationState(
+ AccessNetworkConstants.TransportType.WWAN, domain, voiceRegState,
+ ServiceState.rilRadioTechnologyToNetworkType(voiceRadioTech), reasonForDenial,
+ false, availableServices, null, maxDataCalls);
+
+ try {
+ verify(mCallback, times(1)).onGetNetworkRegistrationStateComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
index 87347e5..f9a883a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
@@ -17,8 +17,10 @@
package com.android.internal.telephony;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.os.Handler;
@@ -31,7 +33,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-
+import org.mockito.Mock;
@RunWith(AndroidJUnit4.class)
public class ExponentialBackoffTest extends ImsTestBase {
@@ -40,20 +42,23 @@
private static final int MULTIPLIER = 2;
private ExponentialBackoff mBackoffUnderTest;
- private Handler mHandler = spy(new Handler(Looper.getMainLooper()));
- private Runnable mRunnable = spy(new MyRunnable());
-
- public class MyRunnable implements Runnable {
- @Override
- public void run() {
- // do nothing
- }
- }
+ private Handler mHandler = new Handler(Looper.getMainLooper());
+ @Mock private Runnable mRunnable;
+ @Mock private ExponentialBackoff.HandlerAdapter mHandlerAdapter;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
+ super.setUp();
mBackoffUnderTest = new ExponentialBackoff(
START_DELAY_MS, MAXIMUM_DELAY_MS, MULTIPLIER, mHandler, mRunnable);
+ mBackoffUnderTest.setHandlerAdapter(mHandlerAdapter);
+ doAnswer(invocation -> mHandler.postDelayed((Runnable) invocation.getArguments()[0],
+ (long) invocation.getArguments()[1])
+ ).when(mHandlerAdapter).postDelayed(any(Runnable.class), anyLong());
+ doAnswer(invocation -> {
+ mHandler.removeCallbacks((Runnable) invocation.getArguments()[0]);
+ return null;
+ }).when(mHandlerAdapter).removeCallbacks(any(Runnable.class));
}
@After
@@ -74,10 +79,10 @@
@Test
public void testStopBackoff() {
mBackoffUnderTest.start();
- reset(mHandler);
mBackoffUnderTest.stop();
- verify(mHandler).removeCallbacks(mRunnable);
+ // removeCallbacks is called during start() and stop()
+ verify(mHandlerAdapter, times(2)).removeCallbacks(mRunnable);
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java
index 55add03..a8bf3bd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzStateMachineTest.java
@@ -28,6 +28,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
import com.android.internal.telephony.util.TimeStampedValue;
import org.junit.After;
@@ -51,6 +52,9 @@
@Mock
private TimeZoneLookupHelper mTimeZoneLookupHelper;
+ @Mock
+ private TimeServiceHelper mTimeServiceHelper;
+
private NitzStateMachine mNitzStateMachine;
@Before
@@ -62,8 +66,8 @@
when(mDeviceState.getIgnoreNitz()).thenReturn(false);
when(mDeviceState.getNitzUpdateDiffMillis()).thenReturn(2000);
when(mDeviceState.getNitzUpdateSpacingMillis()).thenReturn(1000 * 60 * 10);
- when(mDeviceState.elapsedRealtime()).thenReturn(123456789L);
- when(mDeviceState.currentTimeMillis()).thenReturn(987654321L);
+ when(mTimeServiceHelper.elapsedRealtime()).thenReturn(123456789L);
+ when(mTimeServiceHelper.currentTimeMillis()).thenReturn(987654321L);
mNitzStateMachine = new NitzStateMachine(
mPhone, mTimeServiceHelper, mDeviceState, mTimeZoneLookupHelper);
@@ -78,8 +82,6 @@
verify(mDeviceState, atLeast(0)).getIgnoreNitz();
verify(mDeviceState, atLeast(0)).getNitzUpdateDiffMillis();
verify(mDeviceState, atLeast(0)).getNitzUpdateSpacingMillis();
- verify(mDeviceState, atLeast(0)).elapsedRealtime();
- verify(mDeviceState, atLeast(0)).currentTimeMillis();
verify(mDeviceState, atLeast(0)).getNetworkCountryIsoForPhone();
verifyNoMoreInteractions(mDeviceState);
@@ -90,6 +92,8 @@
verify(mTimeServiceHelper, atLeast(0)).isTimeDetectionEnabled();
verify(mTimeServiceHelper, atLeast(0)).isTimeZoneDetectionEnabled();
verify(mTimeServiceHelper, atLeast(0)).isTimeZoneSettingInitialized();
+ verify(mTimeServiceHelper, atLeast(0)).elapsedRealtime();
+ verify(mTimeServiceHelper, atLeast(0)).currentTimeMillis();
verifyNoMoreInteractions(mTimeServiceHelper);
super.tearDown();
@@ -110,9 +114,9 @@
TestNitzSignal testNitzSignal = createTestNitzSignal();
// Configure expected time zone lookup and the result.
- String testTimeZoneId = US_TIME_ZONE_ID;
- when(mTimeZoneLookupHelper.guessZoneIdByNitzCountry(
- testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testTimeZoneId);
+ OffsetResult testLookupResult = new OffsetResult(US_TIME_ZONE_ID, true /* oneMatch */);
+ when(mTimeZoneLookupHelper.lookupByNitzCountry(
+ testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testLookupResult);
// Simulate the elapsedRealtime() value incrementing with the passage of time.
incrementSimulatedDeviceClock(1000);
@@ -122,15 +126,15 @@
// Check resulting state and side effects.
long expectedAdjustedCurrentTimeMillis =
- testNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime());
+ testNitzSignal.getAdjustedCurrentTimeMillis(mTimeServiceHelper.elapsedRealtime());
- verifyTimeServiceTimeZoneWasSet(testTimeZoneId);
+ verifyTimeServiceTimeZoneWasSet(testLookupResult.zoneId);
verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis);
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(testNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData());
- assertEquals(testTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ assertEquals(testLookupResult.zoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -149,9 +153,9 @@
TestNitzSignal testNitzSignal = createTestNitzSignal();
// Configure expected time zone lookup and the result.
- String testTimeZoneId = US_TIME_ZONE_ID;
- when(mTimeZoneLookupHelper.guessZoneIdByNitzCountry(
- testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testTimeZoneId);
+ OffsetResult testLookupResult = new OffsetResult(US_TIME_ZONE_ID, true /* oneMatch */);
+ when(mTimeZoneLookupHelper.lookupByNitzCountry(
+ testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testLookupResult);
// Simulate the elapsedRealtime() value incrementing with the passage of time.
incrementSimulatedDeviceClock(1000);
@@ -161,14 +165,14 @@
// Check resulting state and side effects.
long expectedAdjustedCurrentTimeMillis =
- testNitzSignal.getAdjustedCurrentTimeMillis(mDeviceState.elapsedRealtime());
+ testNitzSignal.getAdjustedCurrentTimeMillis(mTimeServiceHelper.elapsedRealtime());
verifyTimeServiceTimeZoneWasNotSet();
verifyTimeServiceTimeWasSet(expectedAdjustedCurrentTimeMillis);
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(testNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData());
- assertEquals(testTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ assertEquals(testLookupResult.zoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -186,9 +190,9 @@
TestNitzSignal testNitzSignal = createTestNitzSignal();
// Configure expected time zone lookup and the result.
- String testTimeZoneId = US_TIME_ZONE_ID;
- when(mTimeZoneLookupHelper.guessZoneIdByNitzCountry(
- testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testTimeZoneId);
+ OffsetResult testLookupResult = new OffsetResult(US_TIME_ZONE_ID, true /* oneMatch */);
+ when(mTimeZoneLookupHelper.lookupByNitzCountry(
+ testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testLookupResult);
// Simulate the elapsedRealtime() value incrementing with the passage of time.
incrementSimulatedDeviceClock(1000);
@@ -197,12 +201,12 @@
mNitzStateMachine.handleNitzReceived(testNitzSignal.asTimeStampedValue());
// Check resulting state and side effects.
- verifyTimeServiceTimeZoneWasSet(testTimeZoneId);
+ verifyTimeServiceTimeZoneWasSet(testLookupResult.zoneId);
verifyTimeServiceTimeWasNotSet();
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(testNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData());
- assertEquals(testTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ assertEquals(testLookupResult.zoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -221,9 +225,9 @@
TestNitzSignal testNitzSignal = createTestNitzSignal();
// Configure expected time zone lookup and the result.
- String testTimeZoneId = US_TIME_ZONE_ID;
- when(mTimeZoneLookupHelper.guessZoneIdByNitzCountry(
- testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testTimeZoneId);
+ OffsetResult testLookupResult = new OffsetResult(US_TIME_ZONE_ID, true /* oneMatch */);
+ when(mTimeZoneLookupHelper.lookupByNitzCountry(
+ testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testLookupResult);
// Simulate the elapsedRealtime() value incrementing with the passage of time.
incrementSimulatedDeviceClock(1000);
@@ -237,7 +241,7 @@
assertTrue(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(testNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData());
- assertEquals(testTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ assertEquals(testLookupResult.zoneId, mNitzStateMachine.getSavedTimeZoneId());
}
@Test
@@ -271,22 +275,22 @@
//
// Configure expected time zone lookup and the result.
- String testTimeZoneId = US_TIME_ZONE_ID;
- when(mTimeZoneLookupHelper.guessZoneIdByNitzCountry(
- testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testTimeZoneId);
+ OffsetResult testLookupResult = new OffsetResult(US_TIME_ZONE_ID, true /* oneMatch */);
+ when(mTimeZoneLookupHelper.lookupByNitzCountry(
+ testNitzSignal.getNitzData(), US_ISO_CODE)).thenReturn(testLookupResult);
// Simulate the country being known.
when(mDeviceState.getNetworkCountryIsoForPhone()).thenReturn(US_ISO_CODE);
mNitzStateMachine.handleNetworkCountryCodeSet(true);
// Check resulting state and side effects.
- verifyTimeServiceTimeZoneWasSet(testTimeZoneId);
+ verifyTimeServiceTimeZoneWasSet(testLookupResult.zoneId);
// TODO(nfuller): The following line should probably be assertTrue but the logic under test
// is probably buggy. Fix.
assertFalse(mNitzStateMachine.getNitzTimeZoneDetectionSuccessful());
assertEquals(testNitzSignal.getNitzData(), mNitzStateMachine.getCachedNitzData());
- assertEquals(testTimeZoneId, mNitzStateMachine.getSavedTimeZoneId());
+ assertEquals(testLookupResult.zoneId, mNitzStateMachine.getSavedTimeZoneId());
}
private void verifyTimeServiceTimeZoneWasNotSet() {
@@ -308,10 +312,10 @@
}
private void incrementSimulatedDeviceClock(int incMillis) {
- long currentElapsedRealtime = mDeviceState.elapsedRealtime();
- when(mDeviceState.elapsedRealtime()).thenReturn(currentElapsedRealtime + incMillis);
- long currentTimeMillis = mDeviceState.currentTimeMillis();
- when(mDeviceState.elapsedRealtime()).thenReturn(currentTimeMillis + incMillis);
+ long currentElapsedRealtime = mTimeServiceHelper.elapsedRealtime();
+ when(mTimeServiceHelper.elapsedRealtime()).thenReturn(currentElapsedRealtime + incMillis);
+ long currentTimeMillis = mTimeServiceHelper.currentTimeMillis();
+ when(mTimeServiceHelper.elapsedRealtime()).thenReturn(currentTimeMillis + incMillis);
}
private static long createTime(TimeZone timeZone, int year, int monthOfYear, int dayOfMonth,
@@ -327,7 +331,7 @@
* receivedRealtimeMillis from the current {@code mDeviceState.elapsedRealtime()}.
*/
private TestNitzSignal createTestNitzSignal() {
- long receivedRealtimeMillis = mDeviceState.elapsedRealtime();
+ long receivedRealtimeMillis = mTimeServiceHelper.elapsedRealtime();
// Create an arbitrary time.
long timeMillis = createTime(TimeZone.getTimeZone("UTC"), 2017, 1, 2, 12, 45, 25);
// Create arbitrary NITZ data.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index d877ac4..6118b62 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -81,7 +81,6 @@
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
-import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
@@ -101,11 +100,8 @@
import android.hardware.radio.V1_0.RadioError;
import android.hardware.radio.V1_0.RadioResponseInfo;
import android.hardware.radio.V1_0.RadioResponseType;
-import android.hardware.radio.V1_0.SetupDataCallResult;
import android.hardware.radio.V1_0.SmsWriteArgs;
import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IPowerManager;
@@ -128,7 +124,6 @@
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
-import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import com.android.internal.telephony.RIL.RilHandler;
@@ -142,10 +137,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Arrays;
public class RILTest extends TelephonyTest {
@@ -1023,18 +1015,6 @@
assertFalse(ril.getWakeLock(RIL.FOR_WAKELOCK).isHeld());
}
- private static Object invokeMethod(
- Object instance, String methodName, Class<?>[] parameterClasses, Object[] parameters) {
- try {
- Method method = instance.getClass().getDeclaredMethod(methodName, parameterClasses);
- method.setAccessible(true);
- return method.invoke(instance, parameters);
- } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- fail(instance.getClass() + " " + methodName + " " + e.getClass().getName());
- }
- return null;
- }
-
private static RadioResponseInfo createFakeRadioResponseInfo(int serial, int error, int type) {
RadioResponseInfo respInfo = new RadioResponseInfo();
respInfo.serial = serial;
@@ -1557,62 +1537,4 @@
return RIL.convertHalCellInfoList_1_2(records);
}
-
- @Test
- public void testConvertDataCallResult() throws Exception {
-
- SetupDataCallResult result = new SetupDataCallResult();
- result.status = 0;
- result.suggestedRetryTime = -1;
- result.cid = 1;
- result.active = 1;
- result.type = "IP";
- result.ifname = "eth0";
- result.addresses = "10.0.2.15";
- result.dnses = "10.0.2.3";
- result.gateways = "10.0.2.15 fe80::2";
- result.pcscf = "";
- result.mtu = 1500;
-
- DataCallResponse response = new DataCallResponse(0, -1, 1, 1, "IP",
- "eth0",
- Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress("10.0.2.15"), 32)),
- Arrays.asList(NetworkUtils.numericToInetAddress("10.0.2.3")),
- Arrays.asList(NetworkUtils.numericToInetAddress("10.0.2.15"),
- NetworkUtils.numericToInetAddress("fe80::2")),
- Arrays.asList(""),
- 1500);
-
- assertEquals(response, invokeMethod(mRILInstance, "convertDataCallResult",
- new Class<?>[] {SetupDataCallResult.class},
- new Object[] {result}));
-
-
- result.status = 0;
- result.suggestedRetryTime = -1;
- result.cid = 0;
- result.active = 2;
- result.type = "IPV4V6";
- result.ifname = "ifname";
- result.addresses = "2607:fb90:a620:651d:eabe:f8da:c107:44be/64";
- result.dnses = "fd00:976a::9 fd00:976a::10";
- result.gateways = "fe80::4c61:1832:7b28:d36c 1.2.3.4";
- result.pcscf = "fd00:976a:c206:20::6 fd00:976a:c206:20::9 fd00:976a:c202:1d::9";
- result.mtu = 1500;
-
- response = new DataCallResponse(0, -1, 0, 2, "IPV4V6",
- "ifname",
- Arrays.asList(new LinkAddress("2607:fb90:a620:651d:eabe:f8da:c107:44be/64")),
- Arrays.asList(NetworkUtils.numericToInetAddress("fd00:976a::9"),
- NetworkUtils.numericToInetAddress("fd00:976a::10")),
- Arrays.asList(NetworkUtils.numericToInetAddress("fe80::4c61:1832:7b28:d36c"),
- NetworkUtils.numericToInetAddress("1.2.3.4")),
- Arrays.asList("fd00:976a:c206:20::6", "fd00:976a:c206:20::9",
- "fd00:976a:c202:1d::9"),
- 1500);
-
- assertEquals(response, invokeMethod(mRILInstance, "convertDataCallResult",
- new Class<?>[] {SetupDataCallResult.class},
- new Object[] {result}));
- }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 5c1c900..d14e1a9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -34,9 +34,8 @@
import android.app.IAlarmManager;
import android.content.Intent;
-import android.hardware.radio.V1_0.CellIdentityGsm;
-import android.hardware.radio.V1_0.CellInfoType;
-import android.hardware.radio.V1_0.VoiceRegStateResult;
+import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
@@ -50,8 +49,11 @@
import android.os.WorkSource;
import android.support.test.filters.FlakyTest;
import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentityGsm;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
+import android.telephony.NetworkRegistrationState;
+import android.telephony.NetworkService;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
@@ -60,6 +62,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
+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;
@@ -88,6 +91,8 @@
@Mock
protected IAlarmManager mAlarmManager;
+ CellularNetworkService mCellularNetworkService;
+
private ServiceStateTracker sst;
private ServiceStateTrackerTestHandler mSSTTestHandler;
private PersistableBundle mBundle;
@@ -117,12 +122,31 @@
}
}
+ private void addNetworkService() {
+ mCellularNetworkService = new CellularNetworkService();
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.packageName = "com.android.phone";
+ serviceInfo.permission = "android.permission.BIND_NETWORK_SERVICE";
+ IntentFilter filter = new IntentFilter();
+ mContextFixture.addService(
+ NetworkService.NETWORK_SERVICE_INTERFACE,
+ null,
+ "com.android.phone",
+ mCellularNetworkService.mBinder,
+ serviceInfo,
+ filter);
+ }
+
@Before
public void setUp() throws Exception {
logd("ServiceStateTrackerTest +Setup!");
super.setUp("ServiceStateTrackerTest");
+ mContextFixture.putResource(R.string.config_wwan_network_service_package,
+ "com.android.phone");
+ addNetworkService();
+
doReturn(true).when(mDct).isDisconnected();
mPhone.mDcTracker = mDct;
@@ -134,9 +158,9 @@
mBundle.putStringArray(
CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.setDataRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
int dds = SubscriptionManager.getDefaultDataSubscriptionId();
@@ -406,12 +430,9 @@
@Test
@MediumTest
public void testGsmCellLocation() {
-
- VoiceRegStateResult result = new VoiceRegStateResult();
- result.cellIdentity.cellInfoType = CellInfoType.GSM;
- result.cellIdentity.cellIdentityGsm.add(new CellIdentityGsm());
- result.cellIdentity.cellIdentityGsm.get(0).lac = 2;
- result.cellIdentity.cellIdentityGsm.get(0).cid = 3;
+ CellIdentityGsm cellIdentityGsm = new CellIdentityGsm(0, 0, 2, 3);
+ NetworkRegistrationState result = new NetworkRegistrationState(
+ 0, 0, 0, 0, 0, false, null, cellIdentityGsm);
sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_GET_LOC_DONE,
new AsyncResult(null, result, null)));
@@ -474,8 +495,8 @@
// Enable roaming and trigger events to notify handler registered
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -486,8 +507,8 @@
assertEquals(EVENT_DATA_ROAMING_ON, messageArgumentCaptor.getValue().what);
// Disable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -496,8 +517,8 @@
sst.unregisterForVoiceRoamingOn(mTestHandler);
// Enable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -511,8 +532,8 @@
public void testRegAndUnregForVoiceRoamingOff() throws Exception {
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -521,8 +542,8 @@
// Disable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -533,8 +554,8 @@
assertEquals(EVENT_DATA_ROAMING_OFF, messageArgumentCaptor.getValue().what);
// Enable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -543,8 +564,8 @@
sst.unregisterForVoiceRoamingOff(mTestHandler);
// Disable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -560,8 +581,8 @@
// Enable roaming and trigger events to notify handler registered
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -572,8 +593,8 @@
assertEquals(EVENT_DATA_ROAMING_ON, messageArgumentCaptor.getValue().what);
// Disable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -582,8 +603,8 @@
sst.unregisterForDataRoamingOn(mTestHandler);
// Enable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -597,8 +618,8 @@
public void testRegAndUnregForDataRoamingOff() throws Exception {
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -607,8 +628,8 @@
// Disable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -619,8 +640,8 @@
assertEquals(EVENT_DATA_ROAMING_OFF, messageArgumentCaptor.getValue().what);
// Enable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -629,8 +650,8 @@
sst.unregisterForDataRoamingOff(mTestHandler);
// Disable roaming
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_HOME);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_HOME);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -653,8 +674,8 @@
sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -675,8 +696,8 @@
sst.unregisterForDataConnectionAttached(mTestHandler);
// set service state in service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -690,8 +711,8 @@
public void testRegAndUnregForDataConnAttach() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -699,8 +720,8 @@
sst.registerForDataConnectionAttached(mTestHandler, EVENT_DATA_CONNECTION_ATTACHED, null);
// set service state in service and trigger events to post message on handler
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -711,8 +732,8 @@
assertEquals(EVENT_DATA_CONNECTION_ATTACHED, messageArgumentCaptor.getValue().what);
// set service state out of service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -721,8 +742,8 @@
sst.unregisterForDataConnectionAttached(mTestHandler);
// set service state in service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -736,15 +757,15 @@
public void testRegAndUnregForDataConnDetach() throws Exception {
// Initially set service state in service
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
sst.registerForDataConnectionDetached(mTestHandler, EVENT_DATA_CONNECTION_DETACHED, null);
// set service state out of service and trigger events to post message on handler
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
@@ -755,8 +776,8 @@
assertEquals(EVENT_DATA_CONNECTION_DETACHED, messageArgumentCaptor.getValue().what);
// set service state in service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -765,8 +786,8 @@
sst.unregisterForDataConnectionDetached(mTestHandler);
// set service state out of service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -778,7 +799,7 @@
@Test
@MediumTest
public void testRegisterForDataRegStateOrRatChange() {
- int drs = sst.mSS.RIL_REG_STATE_HOME;
+ int drs = NetworkRegistrationState.REG_STATE_HOME;
int rat = sst.mSS.RIL_RADIO_TECHNOLOGY_LTE;
sst.mSS.setRilDataRadioTechnology(rat);
sst.mSS.setDataRegState(drs);
@@ -799,8 +820,8 @@
public void testRegAndUnregForNetworkAttached() throws Exception {
// Initially set service state out of service
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -808,8 +829,8 @@
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service and trigger events to post message on handler
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -820,8 +841,8 @@
assertEquals(EVENT_REGISTERED_TO_NETWORK, messageArgumentCaptor.getValue().what);
// set service state out of service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_UNKNOWN);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_UNKNOWN);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -830,8 +851,8 @@
sst.unregisterForNetworkAttached(mTestHandler);
// set service state in service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -854,8 +875,8 @@
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service and trigger events to post message on handler
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -881,8 +902,8 @@
sst.registerForNetworkAttached(mTestHandler, EVENT_REGISTERED_TO_NETWORK, null);
// set service state in service
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(100);
@@ -1021,8 +1042,8 @@
// Enable roaming
doReturn(true).when(mPhone).isPhoneTypeGsm();
- mSimulatedCommands.setVoiceRegState(ServiceState.RIL_REG_STATE_ROAMING);
- mSimulatedCommands.setDataRegState(ServiceState.RIL_REG_STATE_ROAMING);
+ mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_ROAMING);
+ mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_ROAMING);
mSimulatedCommands.notifyNetworkStateChanged();
waitForMs(200);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 443e427..0f75a94 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -47,13 +47,13 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ImsCallProfile;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.util.Log;
import android.util.Singleton;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
import com.android.ims.ImsEcbm;
import com.android.ims.ImsManager;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
@@ -81,6 +81,8 @@
import org.mockito.stubbing.Answer;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -131,8 +133,6 @@
@Mock
protected ImsCall mImsCall;
@Mock
- protected ImsCallProfile mImsCallProfile;
- @Mock
protected ImsEcbm mImsEcbm;
@Mock
protected SubscriptionController mSubscriptionController;
@@ -195,10 +195,9 @@
@Mock
protected NitzStateMachine mNitzStateMachine;
@Mock
- protected TimeServiceHelper mTimeServiceHelper;
- @Mock
protected RadioConfig mMockRadioConfig;
+ protected ImsCallProfile mImsCallProfile;
protected TelephonyManager mTelephonyManager;
protected SubscriptionManager mSubscriptionManager;
protected EuiccManager mEuiccManager;
@@ -310,6 +309,7 @@
MockitoAnnotations.initMocks(this);
mPhones = new Phone[] {mPhone};
+ mImsCallProfile = new ImsCallProfile();
mSimulatedCommands = new SimulatedCommands();
mContextFixture = new ContextFixture();
mContext = mContextFixture.getTestDouble();
@@ -372,8 +372,6 @@
.makeDeviceStateMonitor(nullable(Phone.class));
doReturn(mNitzStateMachine).when(mTelephonyComponentFactory)
.makeNitzStateMachine(nullable(GsmCdmaPhone.class));
- doReturn(mTimeServiceHelper).when(mTelephonyComponentFactory)
- .makeTimeServiceHelper(nullable(Context.class));
//mPhone
doReturn(mContext).when(mPhone).getContext();
@@ -449,7 +447,7 @@
getRilDataRadioTechnology();
doReturn(mPhone).when(mCT).getPhone();
mImsManagerInstances.put(mPhone.getPhoneId(), mImsManager);
- doReturn(mImsEcbm).when(mImsManager).getEcbmInterface(anyInt());
+ doReturn(mImsEcbm).when(mImsManager).getEcbmInterface();
doReturn(mPhone).when(mInboundSmsHandler).getPhone();
doReturn(mImsCallProfile).when(mImsCall).getCallProfile();
doReturn(mIBinder).when(mIIntentSender).asBinder();
@@ -567,4 +565,16 @@
}
}
}
+
+ public static Object invokeMethod(
+ Object instance, String methodName, Class<?>[] parameterClasses, Object[] parameters) {
+ try {
+ Method method = instance.getClass().getDeclaredMethod(methodName, parameterClasses);
+ method.setAccessible(true);
+ return method.invoke(instance, parameters);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ fail(instance.getClass() + " " + methodName + " " + e.getClass().getName());
+ }
+ return null;
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TimeZoneLookupHelperTest.java b/tests/telephonytests/src/com/android/internal/telephony/TimeZoneLookupHelperTest.java
index ae24756..d0eeb43 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TimeZoneLookupHelperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TimeZoneLookupHelperTest.java
@@ -16,6 +16,9 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult;
+import com.android.internal.telephony.TimeZoneLookupHelper.OffsetResult;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -34,6 +37,11 @@
import java.util.concurrent.TimeUnit;
public class TimeZoneLookupHelperTest {
+ // Note: Historical dates are used to avoid the test breaking due to data changes.
+ /* Arbitrary summer date in the Northern hemisphere. */
+ private static final long NH_SUMMER_TIME_MILLIS = createUtcTime(2015, 6, 20, 1, 2, 3);
+ /* Arbitrary winter date in the Northern hemisphere. */
+ private static final long NH_WINTER_TIME_MILLIS = createUtcTime(2015, 1, 20, 1, 2, 3);
private TimeZoneLookupHelper mTimeZoneLookupHelper;
@@ -43,7 +51,7 @@
}
@Test
- public void testGuessZoneIdByNitz() {
+ public void testLookupByNitzdByNitz() {
// Historical dates are used to avoid the test breaking due to data changes.
// However, algorithm updates may change the exact time zone returned, though it shouldn't
// ever be a less exact match.
@@ -63,25 +71,35 @@
int lonWinterOffsetMillis = 0;
int lonWinterDstOffsetMillis = 0;
+ OffsetResult lookupResult;
+
// Summer, known DST state (DST == true).
NitzData lonSummerNitzDataWithOffset = NitzData.parse(lonSummerTimeString + ",4");
- assertTimeZoneId(nhSummerTimeMillis, lonSummerOffsetMillis, lonSummerDstOffsetMillis,
- mTimeZoneLookupHelper.guessZoneIdByNitz(lonSummerNitzDataWithOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(lonSummerNitzDataWithOffset);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, lonSummerOffsetMillis,
+ lonSummerDstOffsetMillis, lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Winter, known DST state (DST == false).
NitzData lonWinterNitzDataWithOffset = NitzData.parse(lonWinterTimeString + ",0");
- assertTimeZoneId(nhWinterTimeMillis, lonWinterOffsetMillis, lonWinterDstOffsetMillis,
- mTimeZoneLookupHelper.guessZoneIdByNitz(lonWinterNitzDataWithOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(lonWinterNitzDataWithOffset);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, lonWinterOffsetMillis,
+ lonWinterDstOffsetMillis, lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Summer, unknown DST state
NitzData lonSummerNitzDataWithoutOffset = NitzData.parse(lonSummerTimeString);
- assertTimeZoneId(nhSummerTimeMillis, lonSummerOffsetMillis, null,
- mTimeZoneLookupHelper.guessZoneIdByNitz(lonSummerNitzDataWithoutOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(lonSummerNitzDataWithoutOffset);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, lonSummerOffsetMillis, null,
+ lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Winter, unknown DST state
NitzData lonWinterNitzDataWithoutOffset = NitzData.parse(lonWinterTimeString);
- assertTimeZoneId(nhWinterTimeMillis, lonWinterOffsetMillis, null,
- mTimeZoneLookupHelper.guessZoneIdByNitz(lonWinterNitzDataWithoutOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(lonWinterNitzDataWithoutOffset);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, lonWinterOffsetMillis, null,
+ lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
}
// Tests for Mountain View, CA, US.
@@ -94,30 +112,40 @@
int mtvWinterOffsetMillis = (int) TimeUnit.HOURS.toMillis(-7);
int mtvWinterDstOffsetMillis = 0;
+ OffsetResult lookupResult;
+
// Summer, known DST state (DST == true).
NitzData mtvSummerNitzDataWithOffset = NitzData.parse(mtvSummerTimeString + ",4");
- assertTimeZoneId(nhSummerTimeMillis, mtvSummerOffsetMillis, mtvSummerDstOffsetMillis,
- mTimeZoneLookupHelper.guessZoneIdByNitz(mtvSummerNitzDataWithOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(mtvSummerNitzDataWithOffset);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, mtvSummerOffsetMillis,
+ mtvSummerDstOffsetMillis, lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Winter, known DST state (DST == false).
NitzData mtvWinterNitzDataWithOffset = NitzData.parse(mtvWinterTimeString + ",0");
- assertTimeZoneId(nhWinterTimeMillis, mtvWinterOffsetMillis, mtvWinterDstOffsetMillis,
- mTimeZoneLookupHelper.guessZoneIdByNitz(mtvWinterNitzDataWithOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(mtvWinterNitzDataWithOffset);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, mtvWinterOffsetMillis,
+ mtvWinterDstOffsetMillis, lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Summer, unknown DST state
NitzData mtvSummerNitzDataWithoutOffset = NitzData.parse(mtvSummerTimeString);
- assertTimeZoneId(nhSummerTimeMillis, mtvSummerOffsetMillis, null,
- mTimeZoneLookupHelper.guessZoneIdByNitz(mtvSummerNitzDataWithoutOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(mtvSummerNitzDataWithoutOffset);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, mtvSummerOffsetMillis, null,
+ lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
// Winter, unknown DST state
NitzData mtvWinterNitzDataWithoutOffset = NitzData.parse(mtvWinterTimeString);
- assertTimeZoneId(nhWinterTimeMillis, mtvWinterOffsetMillis, null,
- mTimeZoneLookupHelper.guessZoneIdByNitz(mtvWinterNitzDataWithoutOffset));
+ lookupResult = mTimeZoneLookupHelper.lookupByNitz(mtvWinterNitzDataWithoutOffset);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, mtvWinterOffsetMillis, null,
+ lookupResult);
+ assertOffsetResultMetadata(false, lookupResult);
}
}
@Test
- public void testGuessZoneIdByNitzCountry() {
+ public void testLookupByNitzCountry() {
// Historical dates are used to avoid the test breaking due to data changes.
// However, algorithm updates may change the exact time zone returned, though it shouldn't
// ever be a less exact match.
@@ -126,8 +154,8 @@
// Two countries in the northern hemisphere that share the same Winter and Summer DST
// offsets at the dates being used.
- String isoCountry1 = "DE"; // Germany
- String isoCountry2 = "ES"; // Spain
+ String deIso = "DE"; // Germany
+ String adIso = "AD"; // Andora
String summerTimeNitzString = "15/06/20,01:02:03+8";
String winterTimeNitzString = "15/01/20,01:02:03+4";
@@ -140,19 +168,22 @@
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
- String country1SummerWithDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry1);
- assertTimeZoneId(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset,
- country1SummerWithDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry1, country1SummerWithDstResult);
+ OffsetResult expectedResult;
- String country2SummerWithDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry2);
- assertTimeZoneId(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset,
- country2SummerWithDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry2, country2SummerWithDstResult);
+ OffsetResult deSummerWithDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, deIso);
+ expectedResult = new OffsetResult("Europe/Berlin", false /* isOnlyMatch */);
+ assertEquals(expectedResult, deSummerWithDstResult);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset,
+ deSummerWithDstResult);
- assertDifferentZoneIds(country1SummerWithDstResult, country2SummerWithDstResult);
+ OffsetResult adSummerWithDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
+ expectedResult = new OffsetResult("Europe/Andorra", true /* isOnlyMatch */);
+ assertEquals(expectedResult, adSummerWithDstResult);
+ assertOffsetResultZoneOffsets(nhSummerTimeMillis, expectedUtcOffset, expectedDstOffset,
+ adSummerWithDstResult);
+ assertOffsetResultZoneCountry(adIso, adSummerWithDstResult);
}
// Winter, known DST state (DST == false)
@@ -164,19 +195,21 @@
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
- String country1WinterWithDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry1);
- assertTimeZoneId(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
- country1WinterWithDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry1, country1WinterWithDstResult);
+ OffsetResult expectedResult;
- String country2WinterWithDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry2);
- assertTimeZoneId(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
- country2WinterWithDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry2, country2WinterWithDstResult);
+ OffsetResult deWinterWithDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, deIso);
+ expectedResult = new OffsetResult("Europe/Berlin", false /* isOnlyMatch */);
+ assertEquals(expectedResult, deWinterWithDstResult);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
+ deWinterWithDstResult);
- assertDifferentZoneIds(country1WinterWithDstResult, country2WinterWithDstResult);
+ OffsetResult adWinterWithDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
+ expectedResult = new OffsetResult("Europe/Andorra", true /* isOnlyMatch */);
+ assertEquals(expectedResult, adWinterWithDstResult);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
+ adWinterWithDstResult);
}
// Summer, unknown DST state
@@ -190,13 +223,13 @@
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
- String country1SummerUnknownDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry1);
- assertNull(country1SummerUnknownDstResult);
+ OffsetResult deSummerUnknownDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, deIso);
+ assertNull(deSummerUnknownDstResult);
- String country2SummerUnknownDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry2);
- assertNull(country2SummerUnknownDstResult);
+ OffsetResult adSummerUnknownDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
+ assertNull(adSummerUnknownDstResult);
}
// Winter, unknown DST state
@@ -207,56 +240,74 @@
assertEquals(expectedUtcOffset, nitzData.getLocalOffsetMillis());
assertEquals(expectedDstOffset, nitzData.getDstAdjustmentMillis());
- String country1WinterUnknownDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry1);
- assertTimeZoneId(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
- country1WinterUnknownDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry1, country1WinterUnknownDstResult);
+ OffsetResult expectedResult;
- String country2WinterUnknownDstResult =
- mTimeZoneLookupHelper.guessZoneIdByNitzCountry(nitzData, isoCountry2);
- assertTimeZoneId(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
- country2WinterUnknownDstResult);
- assertTimeZoneIdUsedInCountry(isoCountry2, country2WinterUnknownDstResult);
+ OffsetResult deWinterUnknownDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, deIso);
+ expectedResult = new OffsetResult("Europe/Berlin", false /* isOnlyMatch */);
+ assertEquals(expectedResult, deWinterUnknownDstResult);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
+ deWinterUnknownDstResult);
- assertDifferentZoneIds(country1WinterUnknownDstResult, country2WinterUnknownDstResult);
+ OffsetResult adWinterUnknownDstResult =
+ mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, adIso);
+ expectedResult = new OffsetResult("Europe/Andorra", true /* isOnlyMatch */);
+ assertEquals(expectedResult, adWinterUnknownDstResult);
+ assertOffsetResultZoneOffsets(nhWinterTimeMillis, expectedUtcOffset, expectedDstOffset,
+ adWinterUnknownDstResult);
}
}
@Test
- public void testGuessZoneIdByCountry() {
+ public void testLookupByCountry() {
// Historical dates are used to avoid the test breaking due to data changes.
long nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
long nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
+ CountryResult expectedResult;
+
// GB has one time zone.
- assertEquals("Europe/London",
- mTimeZoneLookupHelper.guessZoneIdByCountry("gb", nhSummerTimeMillis));
- assertEquals("Europe/London",
- mTimeZoneLookupHelper.guessZoneIdByCountry("gb", nhWinterTimeMillis));
+ expectedResult = new CountryResult("Europe/London", true /* allZonesHaveSameOffset */,
+ nhSummerTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("gb", nhSummerTimeMillis));
+ expectedResult = new CountryResult("Europe/London", true /* allZonesHaveSameOffset */,
+ nhWinterTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("gb", nhWinterTimeMillis));
// DE has two time zones according to data, but they agree on offset.
- assertEquals("Europe/Berlin",
- mTimeZoneLookupHelper.guessZoneIdByCountry("de", nhSummerTimeMillis));
- assertEquals("Europe/Berlin",
- mTimeZoneLookupHelper.guessZoneIdByCountry("de", nhWinterTimeMillis));
+ expectedResult = new CountryResult("Europe/Berlin", true /* allZonesHaveSameOffset */,
+ nhSummerTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("de", nhSummerTimeMillis));
+ expectedResult = new CountryResult("Europe/Berlin", true /* allZonesHaveSameOffset */,
+ nhWinterTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("de", nhWinterTimeMillis));
// US has many time zones that have different offsets.
- assertNull(mTimeZoneLookupHelper.guessZoneIdByCountry("us", nhSummerTimeMillis));
- assertNull(mTimeZoneLookupHelper.guessZoneIdByCountry("us", nhWinterTimeMillis));
+ expectedResult = new CountryResult("America/New_York", false /* allZonesHaveSameOffset */,
+ nhSummerTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("us", nhSummerTimeMillis));
+ expectedResult = new CountryResult("America/New_York", false /* allZonesHaveSameOffset */,
+ nhWinterTimeMillis);
+ assertEquals(expectedResult,
+ mTimeZoneLookupHelper.lookupByCountry("us", nhWinterTimeMillis));
}
@Test
public void testCountryUsesUtc() {
- assertFalse(mTimeZoneLookupHelper.countryUsesUtc("us"));
- assertTrue(mTimeZoneLookupHelper.countryUsesUtc("gb"));
+ assertFalse(mTimeZoneLookupHelper.countryUsesUtc("us", NH_SUMMER_TIME_MILLIS));
+ assertFalse(mTimeZoneLookupHelper.countryUsesUtc("us", NH_WINTER_TIME_MILLIS));
+ assertFalse(mTimeZoneLookupHelper.countryUsesUtc("gb", NH_SUMMER_TIME_MILLIS));
+ assertTrue(mTimeZoneLookupHelper.countryUsesUtc("gb", NH_WINTER_TIME_MILLIS));
}
- private static void assertDifferentZoneIds(String zone1, String zone2) {
- assertFalse("Zone IDs not different, both=" + zone1, zone1.equals(zone2));
- }
-
- private static void assertTimeZoneIdUsedInCountry(String isoCountryCode, String timeZoneId) {
+ private static void assertOffsetResultZoneCountry(
+ String isoCountryCode, OffsetResult lookupResult) {
+ String timeZoneId = lookupResult.zoneId;
List<String> zoneIdsByCountry =
TimeZoneFinder.getInstance().lookupTimeZoneIdsByCountry(isoCountryCode);
assertTrue(timeZoneId + " must be used in " + isoCountryCode,
@@ -264,11 +315,12 @@
}
/**
- * Assert the timeZone has the expected properties at the specified time.
+ * Assert the time zone in the OffsetResult has the expected properties at the specified time.
*/
- private static void assertTimeZoneId(
- long time, int expectedOffsetAtTime, Integer expectedDstAtTime, String timeZoneId) {
- TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
+ private static void assertOffsetResultZoneOffsets(long time, int expectedOffsetAtTime,
+ Integer expectedDstAtTime, OffsetResult lookupResult) {
+
+ TimeZone timeZone = TimeZone.getTimeZone(lookupResult.zoneId);
GregorianCalendar calendar = new GregorianCalendar(timeZone);
calendar.setTimeInMillis(time);
int actualOffsetAtTime =
@@ -285,6 +337,10 @@
}
}
+ private static void assertOffsetResultMetadata(boolean isOnlyMatch, OffsetResult lookupResult) {
+ assertEquals(isOnlyMatch, lookupResult.isOnlyMatch);
+ }
+
private static long createUtcTime(
int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute, int second) {
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
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 975c9a1..2cbfefb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -20,12 +20,14 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
+
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -35,16 +37,18 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkUtils;
-import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.data.DataCallResponse;
@@ -52,6 +56,7 @@
import android.telephony.data.DataService;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.internal.R;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.TelephonyTest;
@@ -126,12 +131,30 @@
public void onLooperPrepared() {
Handler h = new Handler();
- mDcc = DcController.makeDcc(mPhone, mDcTracker, h);
- mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDcTesterFailBringUpAll,
- mDcc);
+ DataServiceManager manager = new DataServiceManager(mPhone, TransportType.WWAN);
+ mDcc = DcController.makeDcc(mPhone, mDcTracker, manager, h);
+ mDcc.start();
+ mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, manager,
+ mDcTesterFailBringUpAll, mDcc);
}
}
+ private void addDataService() {
+ CellularDataService cellularDataService = new CellularDataService();
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.packageName = "com.android.phone";
+ serviceInfo.permission = "android.permission.BIND_DATA_SERVICE";
+ IntentFilter filter = new IntentFilter();
+ mContextFixture.addService(
+ DataService.DATA_SERVICE_INTERFACE,
+ null,
+ "com.android.phone",
+ cellularDataService.mBinder,
+ serviceInfo,
+ filter);
+ }
+
+
@Before
public void setUp() throws Exception {
logd("+Setup!");
@@ -160,9 +183,13 @@
"evdo:131072,262144,1048576,4096,16384,524288",
"lte:524288,1048576,8388608,262144,524288,4194304"});
+ mContextFixture.putResource(R.string.config_wwan_data_service_package,
+ "com.android.phone");
mDcp.mApnContext = mApnContext;
+ addDataService();
+
mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName());
mDataConnectionTestHandler.start();
@@ -185,12 +212,12 @@
return (IState) method.invoke(mDc);
}
- private long getSuggestedRetryDelay(AsyncResult ar) throws Exception {
+ private long getSuggestedRetryDelay(DataCallResponse response) throws Exception {
Class[] cArgs = new Class[1];
- cArgs[0] = AsyncResult.class;
+ cArgs[0] = DataCallResponse.class;
Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs);
method.setAccessible(true);
- return (long) method.invoke(mDc, ar);
+ return (long) method.invoke(mDc, response);
}
private SetupResult setLinkProperties(DataCallResponse response,
@@ -257,8 +284,7 @@
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- AsyncResult ar = new AsyncResult(null, response, null);
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
+ assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
response = new DataCallResponse(0, 1000, 1, 2, "IP", FAKE_IFNAME,
Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
@@ -266,8 +292,7 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- ar = new AsyncResult(null, response, null);
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
+ assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
response = new DataCallResponse(0, 9999, 1, 2, "IP", FAKE_IFNAME,
Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
@@ -275,9 +300,7 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- ar = new AsyncResult(null, response, null);
-
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(ar));
+ assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
}
@Test
@@ -289,8 +312,8 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- AsyncResult ar = new AsyncResult(null, response, null);
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
+
+ assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
response = new DataCallResponse(0, -5, 1, 2, "IP", FAKE_IFNAME,
Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
@@ -298,8 +321,7 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- ar = new AsyncResult(null, response, null);
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
+ assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
response = new DataCallResponse(0, Integer.MIN_VALUE, 1, 2, "IP", FAKE_IFNAME,
Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
@@ -307,8 +329,7 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- ar = new AsyncResult(null, response, null);
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(ar));
+ assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
}
@Test
@@ -321,8 +342,7 @@
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
1440);
- AsyncResult ar = new AsyncResult(null, response, null);
- assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(ar));
+ assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(response));
}
private NetworkInfo getNetworkInfo() throws Exception {
@@ -470,7 +490,7 @@
1440);
LinkProperties linkProperties = new LinkProperties();
- assertEquals(SetupResult.ERR_UnacceptableParameter,
+ assertEquals(SetupResult.ERROR_INVALID_ARG,
setLinkProperties(response, linkProperties));
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
index 0683c48..c86c911 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
@@ -66,6 +66,8 @@
DataConnection mDc;
@Mock
HashMap<ApnContext, ConnectionParams> mApnContexts;
+ @Mock
+ DataServiceManager mDataServiceManager;
UpdateLinkPropertyResult mResult;
@@ -83,7 +85,8 @@
@Override
public void onLooperPrepared() {
mHandler = new Handler();
- mDcc = DcController.makeDcc(mPhone, mDcTracker, mHandler);
+ mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, mHandler);
+ mDcc.start();
setReady(true);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index c6a17dd..f7eed07 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -18,6 +18,7 @@
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static com.android.internal.telephony.dataconnection.ApnSettingTest.createApnSetting;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -39,13 +40,14 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
import android.database.Cursor;
import android.database.MatrixCursor;
-import android.net.LinkAddress;
+import android.hardware.radio.V1_0.SetupDataCallResult;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
-import android.net.NetworkUtils;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.HandlerThread;
@@ -55,12 +57,12 @@
import android.provider.Settings;
import android.provider.Telephony;
import android.support.test.filters.FlakyTest;
+import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.test.mock.MockContentProvider;
@@ -69,6 +71,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
+import com.android.internal.R;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.Phone;
@@ -146,6 +149,21 @@
private final ApnSettingContentProvider mApnSettingContentProvider =
new ApnSettingContentProvider();
+ private void addDataService() {
+ CellularDataService cellularDataService = new CellularDataService();
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.packageName = "com.android.phone";
+ serviceInfo.permission = "android.permission.BIND_DATA_SERVICE";
+ IntentFilter filter = new IntentFilter();
+ mContextFixture.addService(
+ DataService.DATA_SERVICE_INTERFACE,
+ null,
+ "com.android.phone",
+ cellularDataService.mBinder,
+ serviceInfo,
+ filter);
+ }
+
private class DcTrackerTestHandler extends HandlerThread {
private DcTrackerTestHandler(String name) {
@@ -154,7 +172,7 @@
@Override
public void onLooperPrepared() {
- mDct = new DcTracker(mPhone);
+ mDct = new DcTracker(mPhone, TransportType.WWAN);
setReady(true);
}
}
@@ -389,6 +407,9 @@
"evdo:131072,262144,1048576,4096,16384,524288",
"lte:524288,1048576,8388608,262144,524288,4194304"});
+ mContextFixture.putResource(R.string.config_wwan_data_service_package,
+ "com.android.phone");
+
((MockContentResolver) mContext.getContentResolver()).addProvider(
Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
@@ -420,7 +441,8 @@
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mBundle = mContextFixture.getCarrierConfigBundle();
- mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
+ mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
+ addDataService();
mDcTrackerTestHandler = new DcTrackerTestHandler(getClass().getSimpleName());
mDcTrackerTestHandler.start();
@@ -439,14 +461,20 @@
}
// Create a successful data response
- private static DataCallResponse createDataCallResponse() throws Exception {
-
- return new DataCallResponse(0, -1, 1, 2, "IP", FAKE_IFNAME,
- Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
- Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
- Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
- Arrays.asList(FAKE_PCSCF_ADDRESS),
- 1440);
+ private static SetupDataCallResult createSetupDataCallResult() throws Exception {
+ SetupDataCallResult result = new SetupDataCallResult();
+ result.status = 0;
+ result.suggestedRetryTime = -1;
+ result.cid = 1;
+ result.active = 2;
+ result.type = "IP";
+ result.ifname = FAKE_IFNAME;
+ result.addresses = FAKE_ADDRESS;
+ result.dnses = FAKE_DNS;
+ result.gateways = FAKE_GATEWAY;
+ result.pcscf = FAKE_PCSCF_ADDRESS;
+ result.mtu = 1440;
+ return result;
}
private void verifyDataProfile(DataProfile dp, String apn, int profileId,
@@ -512,7 +540,7 @@
mDct.setUserDataEnabled(true);
- mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
+ mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
boolean allowed = isDataAllowed(dataConnectionReasons);
@@ -576,15 +604,17 @@
mDct.setUserDataEnabled(true);
// LOST_CONNECTION(0x10004) is a non-permanent failure, so we'll retry data setup later.
- DataCallResponse dcResponse = new DataCallResponse(0x10004, -1, 1, 2, "IP", FAKE_IFNAME,
+ /*DataCallResponse dcResponse = new DataCallResponse(0x10004, -1, 1, 2, "IP", FAKE_IFNAME,
Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
Arrays.asList(FAKE_PCSCF_ADDRESS),
- 1440);
+ 1440);*/
+ SetupDataCallResult result = createSetupDataCallResult();
+ result.status = 0x10004;
// Simulate RIL fails the data call setup
- mSimulatedCommands.setDataCallResponse(false, dcResponse);
+ mSimulatedCommands.setDataCallResult(false, result);
DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
boolean allowed = isDataAllowed(dataConnectionReasons);
@@ -647,7 +677,7 @@
anyLong(), any(PendingIntent.class));
// This time we'll let RIL command succeed.
- mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
+ mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
// Simulate the timer expires.
Intent intent = new Intent("com.android.internal.telephony.data-reconnect.default");
@@ -841,7 +871,7 @@
mContextFixture.putBooleanResource(
com.android.internal.R.bool.config_auto_attach_data_on_creation, true);
- mSimulatedCommands.setDataCallResponse(true, createDataCallResponse());
+ mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
boolean allowed = isDataAllowed(dataConnectionReasons);
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsCallProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
similarity index 84%
rename from tests/telephonytests/src/android/telephony/ims/ImsCallProfileTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
index bc8d4e1..2ea1f28 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsCallProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsCallProfileTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -11,12 +11,12 @@
* 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.
+ * limitations under the License
*/
// Note: Package name is intentionally wrong for this test; the internal junk class is used to test
// that parcelables of types other than android.* are stripped out.
-package com.android.telephony.ims;
+package com.android.internal.telephony.ims;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -28,13 +28,15 @@
import android.telecom.DisconnectCause;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
- * Tests for the {@link com.android.ims.ImsCallProfile} class.
+ * Tests for the {@link ImsCallProfile} class.
+ *
+ * Test must NOT be in the "android." namespace.
*/
@RunWith(AndroidJUnit4.class)
public class ImsCallProfileTest {
@@ -49,15 +51,15 @@
mTest = in.readInt();
}
- public static final Creator<JunkParcelable> CREATOR = new Creator<JunkParcelable>() {
+ public static final Creator<JunkParcelable> CREATOR = new Creator<ImsCallProfileTest.JunkParcelable>() {
@Override
- public JunkParcelable createFromParcel(Parcel in) {
- return new JunkParcelable(in);
+ public ImsCallProfileTest.JunkParcelable createFromParcel(Parcel in) {
+ return new ImsCallProfileTest.JunkParcelable(in);
}
@Override
- public JunkParcelable[] newArray(int size) {
- return new JunkParcelable[size];
+ public ImsCallProfileTest.JunkParcelable[] newArray(int size) {
+ return new ImsCallProfileTest.JunkParcelable[size];
}
};
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 17ac579..f217c7d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsManagerTest.java
@@ -17,17 +17,20 @@
package com.android.internal.telephony.ims;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
+import android.telephony.ims.stub.ImsConfigImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsConfig;
@@ -39,11 +42,32 @@
import org.junit.Test;
import org.mockito.Mock;
+import java.util.Hashtable;
+
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;
PersistableBundle mBundle;
+
@Mock
IBinder mBinder;
+ @Mock
+ ImsConfigImplBase mImsConfigImplBaseMock;
+ Hashtable<Integer, Integer> mProvisionedIntVals = new Hashtable<>();
+ Hashtable<Integer, String> mProvisionedStringVals = new Hashtable<>();
+ ImsConfigImplBase.ImsConfigStub mImsConfigStub;
+ ImsConfig mImsConfig;
+
+ private final int[] mSubId = {0};
+ private int mPhoneId;
@Before
public void setUp() throws Exception {
@@ -57,6 +81,8 @@
mServiceManagerMockedServices.put("isub", mBinder);
mImsManagerInstances.remove(mPhoneId);
+
+ setDefaultValues();
}
@After
@@ -75,25 +101,16 @@
WFC_IMS_MODE_DEFAULT_VAL);
mBundle.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT,
WFC_IMS_ROAMING_MODE_DEFAULT_VAL);
+ mBundle.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL,
+ ENHANCED_4G_MODE_DEFAULT_VAL);
+ mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, true);
}
- private static final boolean ENHANCED_4G_ENABLE_DEFAULT_VAL = 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 final int[] mSubId = {0};
- private int mPhoneId;
-
@Test @SmallTest
public void testGetDefaultValues() {
doReturn("-1").when(mSubscriptionController)
.getSubscriptionProperty(anyInt(), anyString(), anyString());
- setDefaultValues();
-
ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
assertEquals(WFC_IMS_ENABLE_DEFAULT_VAL, imsManager.isWfcEnabledByUser());
@@ -150,6 +167,9 @@
eq(SubscriptionManager.VT_IMS_ENABLED),
eq("0"));
+ // enhanced 4g mode must be editable to use setEnhanced4gLteModeSetting
+ mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL,
+ ENHANCED_4G_MODE_EDITABLE);
imsManager.setEnhanced4gLteModeSetting(true);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
@@ -162,4 +182,110 @@
eq(SubscriptionManager.WFC_IMS_ENABLED),
eq("1"));
}
+
+ @Test
+ public void testGetProvisionedValues() throws Exception {
+ ImsManager imsManager = initializeProvisionedValues();
+
+ assertEquals(true, imsManager.isWfcProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
+
+ assertEquals(true, imsManager.isVtProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
+
+ assertEquals(true, imsManager.isVolteProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
+
+ // If we call get again, times should still be one because the value should be fetched
+ // from cache.
+ assertEquals(true, imsManager.isWfcProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
+
+ assertEquals(true, imsManager.isVtProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
+
+ assertEquals(true, imsManager.isVolteProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
+ }
+
+ @Test
+ public void testSetProvisionedValues() throws Exception {
+ ImsManager imsManager = initializeProvisionedValues();
+
+ assertEquals(true, imsManager.isWfcProvisionedOnDevice());
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
+
+ imsManager.getConfigInterface().setProvisionedValue(
+ ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED,
+ ImsConfig.FeatureValueConstants.OFF);
+
+ assertEquals(0, (int) mProvisionedIntVals.get(
+ ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
+
+ assertEquals(false, imsManager.isWfcProvisionedOnDevice());
+
+ verify(mImsConfigImplBaseMock, times(1)).setConfig(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED),
+ eq(0));
+ verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
+ eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
+
+ }
+
+ private ImsManager initializeProvisionedValues() {
+ when(mImsConfigImplBaseMock.getConfigInt(anyInt()))
+ .thenAnswer(invocation -> {
+ return getProvisionedInt((Integer) (invocation.getArguments()[0]));
+ });
+
+ when(mImsConfigImplBaseMock.setConfig(anyInt(), anyInt()))
+ .thenAnswer(invocation -> {
+ mProvisionedIntVals.put((Integer) (invocation.getArguments()[0]),
+ (Integer) (invocation.getArguments()[1]));
+ return ImsConfig.OperationStatusConstants.SUCCESS;
+ });
+
+
+ // Configure ImsConfigStub
+ mImsConfigStub = new ImsConfigImplBase.ImsConfigStub(mImsConfigImplBaseMock);
+ doReturn(mImsConfigStub).when(mImsConfigImplBaseMock).getIImsConfig();
+
+ // Configure ImsConfig
+ mImsConfig = new ImsConfig(mImsConfigStub, mContext);
+
+ // Configure ImsManager
+ ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
+ try {
+ replaceInstance(ImsManager.class, "mConfig", imsManager, mImsConfig);
+ } catch (Exception ex) {
+ fail("failed with " + ex);
+ }
+
+ return imsManager;
+ }
+
+ // If the value is ever set, return the set value. If not, return a constant value 1000.
+ private int getProvisionedInt(int item) {
+ if (mProvisionedIntVals.containsKey(item)) {
+ return mProvisionedIntVals.get(item);
+ } else {
+ return ImsConfig.FeatureValueConstants.ON;
+ }
+ }
+
+ // If the value is ever set, return the set value. If not, return a constant value "unset".
+ private String getProvisionedString(int item) {
+ if (mProvisionedStringVals.containsKey(item)) {
+ return mProvisionedStringVals.get(item);
+ } else {
+ return UNSET_PROVISIONED_STRING;
+ }
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
index 4ad0047..e7f701d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
@@ -16,6 +16,20 @@
package com.android.internal.telephony.ims;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -29,6 +43,7 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.telephony.CarrierConfigManager;
+import android.telephony.ims.ImsService;
import android.telephony.ims.feature.ImsFeature;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
@@ -50,18 +65,6 @@
import java.util.Set;
import java.util.stream.Collectors;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Unit tests for ImsResolver
*/
@@ -108,7 +111,6 @@
setupResolver(1/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> features = new HashSet<>();
- features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, features, true));
@@ -137,16 +139,25 @@
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
List<ResolveInfo> info = new ArrayList<>();
Set<String> features = new HashSet<>();
- features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, features, true));
when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
ImsServiceController controller = mock(ImsServiceController.class);
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- when(controller.getComponentName()).thenReturn(componentName);
- return controller;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ when(controller.getComponentName()).thenReturn(componentName);
+ return controller;
+ }
+ });
mTestImsResolver.populateCacheAndStartBind();
@@ -166,16 +177,25 @@
setupResolver(1/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> features = new HashSet<>();
- features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, features, true));
when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
ImsServiceController controller = mock(ImsServiceController.class);
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- when(controller.getComponentName()).thenReturn(componentName);
- return controller;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ when(controller.getComponentName()).thenReturn(componentName);
+ return controller;
+ }
+ });
// Set the CarrierConfig string to null so that ImsResolver will not bind to the available
// Services
@@ -197,7 +217,6 @@
setupResolver(1/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> features = new HashSet<>();
- features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_RCS_FEATURE);
// Use device default package, which will load the ImsService that the device provides
@@ -205,10 +224,20 @@
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, features, true));
when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
ImsServiceController controller = mock(ImsServiceController.class);
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- when(controller.getComponentName()).thenReturn(componentName);
- return controller;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ when(controller.getComponentName()).thenReturn(componentName);
+ return controller;
+ }
+ });
mTestImsResolver.populateCacheAndStartBind();
@@ -233,14 +262,12 @@
setupResolver(1/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
Set<String> carrierFeatures = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
- carrierFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
+ // Carrier service doesn't support the voice feature.
carrierFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Use device default package, which will load the ImsService that the device provides
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
@@ -283,27 +310,20 @@
// Callback from mock ImsServiceControllers
// All features on slot 1 should be the device default
- mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.EMERGENCY_MMTEL, deviceController);
- mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.MMTEL, deviceController);
- mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.RCS, deviceController);
- // The carrier override does not support emergency voice
- mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.EMERGENCY_MMTEL, deviceController);
- // The carrier override contains these features
- mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.MMTEL, carrierController);
- mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.RCS, carrierController);
+ mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.FEATURE_MMTEL, deviceController);
+ mTestImsResolver.imsServiceFeatureCreated(1, ImsFeature.FEATURE_RCS, deviceController);
+ mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.FEATURE_MMTEL, deviceController);
+ // The carrier override contains this feature
+ mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.FEATURE_RCS, carrierController);
// Get the IImsServiceControllers for each feature on each slot and verify they are correct.
assertEquals(deviceController, mTestImsResolver.getImsServiceControllerAndListen(
- 1/*Slot id*/, ImsFeature.EMERGENCY_MMTEL, null));
+ 1 /*Slot id*/, ImsFeature.FEATURE_MMTEL, null));
assertEquals(deviceController, mTestImsResolver.getImsServiceControllerAndListen(
- 1 /*Slot id*/, ImsFeature.MMTEL, null));
+ 1 /*Slot id*/, ImsFeature.FEATURE_RCS, null));
assertEquals(deviceController, mTestImsResolver.getImsServiceControllerAndListen(
- 1 /*Slot id*/, ImsFeature.RCS, null));
- assertEquals(deviceController, mTestImsResolver.getImsServiceControllerAndListen(
- 1 /*Slot id*/, ImsFeature.EMERGENCY_MMTEL, null));
+ 0 /*Slot id*/, ImsFeature.FEATURE_MMTEL, null));
assertEquals(carrierController, mTestImsResolver.getImsServiceControllerAndListen(
- 0 /*Slot id*/, ImsFeature.MMTEL, null));
- assertEquals(carrierController, mTestImsResolver.getImsServiceControllerAndListen(
- 0 /*Slot id*/, ImsFeature.RCS, null));
+ 0 /*Slot id*/, ImsFeature.FEATURE_RCS, null));
}
/**
@@ -316,16 +336,28 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> features = new HashSet<>();
- features.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
features.add(ImsResolver.METADATA_MMTEL_FEATURE);
// Doesn't include RCS feature by default
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, features, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> ImsService.SERVICE_INTERFACE.equals(
+ argument.getAction())), anyInt(), anyInt()))
+ .thenReturn(info);
ImsServiceController controller = mock(ImsServiceController.class);
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- when(controller.getComponentName()).thenReturn(componentName);
- return controller;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ when(controller.getComponentName()).thenReturn(componentName);
+ return controller;
+ }
+ });
// Bind using default features
mTestImsResolver.populateCacheAndStartBind();
@@ -364,7 +396,6 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
@@ -375,7 +406,10 @@
// Use device default package, which will load the ImsService that the device provides
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> ImsService.SERVICE_INTERFACE.equals(
+ argument.getAction())), anyInt(), anyInt()))
+ .thenReturn(info);
ImsServiceController deviceController = mock(ImsServiceController.class);
ImsServiceController carrierController = mock(ImsServiceController.class);
setImsServiceControllerFactory(deviceController, carrierController);
@@ -400,7 +434,6 @@
// add RCS to features list
Set<String> newDeviceFeatures = new HashSet<>();
- newDeviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
newDeviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
newDeviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
info.clear();
@@ -435,7 +468,6 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
@@ -446,7 +478,10 @@
// Use device default package, which will load the ImsService that the device provides
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> ImsService.SERVICE_INTERFACE.equals(
+ argument.getAction())), anyInt(), anyInt()))
+ .thenReturn(info);
ImsServiceController deviceController = mock(ImsServiceController.class);
ImsServiceController carrierController = mock(ImsServiceController.class);
setImsServiceControllerFactory(deviceController, carrierController);
@@ -504,19 +539,20 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
Set<String> carrierFeatures = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
- carrierFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
+ // Carrier service doesn't support the voice feature.
carrierFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Use device default package, which will load the ImsService that the device provides
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> ImsService.SERVICE_INTERFACE.equals(
+ argument.getAction())), anyInt(), anyInt()))
+ .thenReturn(info);
ImsServiceController deviceController = mock(ImsServiceController.class);
ImsServiceController carrierController = mock(ImsServiceController.class);
setImsServiceControllerFactory(deviceController, carrierController);
@@ -559,7 +595,6 @@
convertToHashSet(newCarrierFeatures, 0);
verify(carrierController).changeImsServiceFeatures(newCarrierFeatureSet);
Set<String> newDeviceFeatures = new HashSet<>();
- newDeviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
newDeviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
newDeviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
HashSet<Pair<Integer, Integer>> newDeviceFeatureSet = convertToHashSet(newDeviceFeatures,
@@ -578,14 +613,16 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
// Use device default package, which will load the ImsService that the device provides
info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, deviceFeatures, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> (argument == null || ImsService.SERVICE_INTERFACE
+ .equals(argument.getAction()))), anyInt(), anyInt()))
+ .thenReturn(info);
ImsServiceController deviceController = mock(ImsServiceController.class);
ImsServiceController carrierController = mock(ImsServiceController.class);
setImsServiceControllerFactory(deviceController, carrierController);
@@ -594,11 +631,13 @@
waitForHandlerAction(mTestImsResolver.getHandler(), TEST_TIMEOUT);
Set<String> carrierFeatures = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
- carrierFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
+ // Carrier service doesn't support the voice feature.
carrierFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
- when(mMockPM.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(info);
+ when(mMockPM.queryIntentServicesAsUser(
+ argThat(argument -> (argument == null || ImsService.SERVICE_INTERFACE
+ .equals(argument.getAction()))), anyInt(), anyInt()))
+ .thenReturn(info);
// Tell the package manager that a new carrier app is installed
Intent addPackageIntent = new Intent();
@@ -629,14 +668,12 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
Set<String> carrierFeatures = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
- carrierFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
+ // Carrier service doesn't support the voice feature.
carrierFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
// Use device default package, which will load the ImsService that the device provides
@@ -680,14 +717,12 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
Set<String> carrierFeatures = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
- carrierFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
+ // Carrier service doesn't support the voice feature.
carrierFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, true));
// Use device default package, which will load the ImsService that the device provides
@@ -726,17 +761,16 @@
setupResolver(2/*numSlots*/);
List<ResolveInfo> info = new ArrayList<>();
Set<String> deviceFeatures = new HashSet<>();
- deviceFeatures.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
deviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
// Set the carrier override package for slot 0
setConfigCarrierString(0, TEST_CARRIER_DEFAULT_NAME.getPackageName());
Set<String> carrierFeatures1 = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
+ // Carrier service 1
carrierFeatures1.add(ImsResolver.METADATA_MMTEL_FEATURE);
carrierFeatures1.add(ImsResolver.METADATA_RCS_FEATURE);
Set<String> carrierFeatures2 = new HashSet<>();
- // Carrier service doesn't support the emergency voice feature.
+ // Carrier service 2 doesn't support the voice feature.
carrierFeatures2.add(ImsResolver.METADATA_RCS_FEATURE);
info.add(getResolveInfo(TEST_CARRIER_2_DEFAULT_NAME, carrierFeatures2, true));
info.add(getResolveInfo(TEST_CARRIER_DEFAULT_NAME, carrierFeatures1, true));
@@ -787,7 +821,7 @@
}
mTestImsResolver = new ImsResolver(mMockContext, TEST_DEVICE_DEFAULT_NAME.getPackageName(),
- numSlots);
+ numSlots, true);
ArgumentCaptor<BroadcastReceiver> packageBroadcastCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -803,36 +837,58 @@
private void setImsServiceControllerFactory(ImsServiceController deviceController,
ImsServiceController carrierController) {
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- if (TEST_DEVICE_DEFAULT_NAME.getPackageName().equals(componentName.getPackageName())) {
- when(deviceController.getComponentName()).thenReturn(componentName);
- return deviceController;
- } else if (TEST_CARRIER_DEFAULT_NAME.getPackageName().equals(
- componentName.getPackageName())) {
- when(carrierController.getComponentName()).thenReturn(componentName);
- return carrierController;
- }
- return null;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ if (TEST_DEVICE_DEFAULT_NAME.getPackageName().equals(
+ componentName.getPackageName())) {
+ when(deviceController.getComponentName()).thenReturn(componentName);
+ return deviceController;
+ } else if (TEST_CARRIER_DEFAULT_NAME.getPackageName().equals(
+ componentName.getPackageName())) {
+ when(carrierController.getComponentName()).thenReturn(componentName);
+ return carrierController;
+ }
+ return null;
+ }
+ });
}
private void setImsServiceControllerFactory(ImsServiceController deviceController,
ImsServiceController carrierController1, ImsServiceController carrierController2) {
- mTestImsResolver.setImsServiceControllerFactory((context, componentName) -> {
- if (TEST_DEVICE_DEFAULT_NAME.getPackageName().equals(componentName.getPackageName())) {
- when(deviceController.getComponentName()).thenReturn(componentName);
- return deviceController;
- } else if (TEST_CARRIER_DEFAULT_NAME.getPackageName().equals(
- componentName.getPackageName())) {
- when(carrierController1.getComponentName()).thenReturn(componentName);
- return carrierController1;
- } else if (TEST_CARRIER_2_DEFAULT_NAME.getPackageName().equals(
- componentName.getPackageName())) {
- when(carrierController2.getComponentName()).thenReturn(componentName);
- return carrierController2;
- }
- return null;
- });
+ mTestImsResolver.setImsServiceControllerFactory(
+ new ImsResolver.ImsServiceControllerFactory() {
+ @Override
+ public String getServiceInterface() {
+ return ImsService.SERVICE_INTERFACE;
+ }
+
+ @Override
+ public ImsServiceController create(Context context, ComponentName componentName,
+ ImsServiceController.ImsServiceControllerCallbacks callbacks) {
+ if (TEST_DEVICE_DEFAULT_NAME.getPackageName().equals(
+ componentName.getPackageName())) {
+ when(deviceController.getComponentName()).thenReturn(componentName);
+ return deviceController;
+ } else if (TEST_CARRIER_DEFAULT_NAME.getPackageName().equals(
+ componentName.getPackageName())) {
+ when(carrierController1.getComponentName()).thenReturn(componentName);
+ return carrierController1;
+ } else if (TEST_CARRIER_2_DEFAULT_NAME.getPackageName().equals(
+ componentName.getPackageName())) {
+ when(carrierController2.getComponentName()).thenReturn(componentName);
+ return carrierController2;
+ }
+ return null;
+ }
+ });
}
@@ -850,12 +906,10 @@
private int metadataStringToFeature(String f) {
switch (f) {
- case ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE:
- return ImsFeature.EMERGENCY_MMTEL;
case ImsResolver.METADATA_MMTEL_FEATURE:
- return ImsFeature.MMTEL;
+ return ImsFeature.FEATURE_MMTEL;
case ImsResolver.METADATA_RCS_FEATURE:
- return ImsFeature.RCS;
+ return ImsFeature.FEATURE_RCS;
}
return -1;
}
@@ -868,17 +922,17 @@
for (String f : features) {
switch (f) {
case ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE:
- if (!sInfo.supportedFeatures.contains(ImsFeature.EMERGENCY_MMTEL)) {
+ if (!sInfo.supportedFeatures.contains(ImsFeature.FEATURE_EMERGENCY_MMTEL)) {
return false;
}
break;
case ImsResolver.METADATA_MMTEL_FEATURE:
- if (!sInfo.supportedFeatures.contains(ImsFeature.MMTEL)) {
+ if (!sInfo.supportedFeatures.contains(ImsFeature.FEATURE_MMTEL)) {
return false;
}
break;
case ImsResolver.METADATA_RCS_FEATURE:
- if (!sInfo.supportedFeatures.contains(ImsFeature.RCS)) {
+ if (!sInfo.supportedFeatures.contains(ImsFeature.FEATURE_RCS)) {
return false;
}
break;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
index 1902d1e..9a7f111 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
@@ -38,10 +38,10 @@
import android.os.RemoteException;
import android.support.test.filters.FlakyTest;
import android.support.test.runner.AndroidJUnit4;
+import android.telephony.ims.ImsService;
import android.util.Pair;
import com.android.ims.internal.IImsServiceFeatureCallback;
-import com.android.internal.telephony.ims.ImsServiceController.RebindRetry;
import org.junit.After;
import org.junit.Before;
@@ -61,7 +61,8 @@
@Ignore
public class ImsServiceControllerTest extends ImsTestBase {
- private static final RebindRetry REBIND_RETRY = new RebindRetry() {
+ private static final ImsServiceController.RebindRetry REBIND_RETRY =
+ new ImsServiceController.RebindRetry() {
@Override
public long getStartDelay() {
return 50;
@@ -121,7 +122,7 @@
| Context.BIND_IMPORTANT;
verify(mMockContext).bindService(intentCaptor.capture(), any(), eq(expectedFlags));
Intent testIntent = intentCaptor.getValue();
- assertEquals(ImsResolver.SERVICE_INTERFACE, testIntent.getAction());
+ assertEquals(ImsService.SERVICE_INTERFACE, testIntent.getAction());
assertEquals(mTestComponentName, testIntent.getComponent());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/TestImsServiceControllerAdapter.java b/tests/telephonytests/src/com/android/internal/telephony/ims/TestImsServiceControllerAdapter.java
index 22e114e..294d6f2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/TestImsServiceControllerAdapter.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/TestImsServiceControllerAdapter.java
@@ -17,12 +17,17 @@
package com.android.internal.telephony.ims;
import android.os.RemoteException;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.aidl.IImsMmTelFeature;
+import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsServiceController;
+import android.telephony.ims.aidl.IImsServiceControllerListener;
+import android.telephony.ims.stub.ImsConfigImplBase;
+import android.telephony.ims.stub.ImsFeatureConfiguration;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import com.android.ims.internal.IImsFeatureStatusCallback;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsRcsFeature;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsServiceController;
import static org.mockito.Mockito.spy;
@@ -37,37 +42,58 @@
public class ImsServiceControllerBinder extends IImsServiceController.Stub {
@Override
- public IImsMMTelFeature createEmergencyMMTelFeature(int slotId, IImsFeatureStatusCallback c)
- throws RemoteException {
- mStatusCallback = c;
- return TestImsServiceControllerAdapter.this.createEmergencyMMTelFeature(slotId);
+ public void setListener(IImsServiceControllerListener l) {
}
@Override
- public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c)
- throws RemoteException {
- mStatusCallback = c;
+ public IImsMmTelFeature createMmTelFeature(int slotId, IImsFeatureStatusCallback c) {
return TestImsServiceControllerAdapter.this.createMMTelFeature(slotId);
}
@Override
- public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c)
- throws RemoteException {
- mStatusCallback = c;
+ public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) {
return TestImsServiceControllerAdapter.this.createRcsFeature(slotId);
}
@Override
- public void removeImsFeature(int slotId, int feature, IImsFeatureStatusCallback c)
+ public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
throws RemoteException {
- TestImsServiceControllerAdapter.this.removeImsFeature(slotId, feature);
+ TestImsServiceControllerAdapter.this.removeImsFeature(slotId, featureType);
}
@Override
- public IImsRegistration getRegistration(int i) throws RemoteException {
+ public ImsFeatureConfiguration querySupportedImsFeatures() {
return null;
}
+ @Override
+ public void notifyImsServiceReadyForFeatureCreation() {
+ }
+
+ @Override
+ public void notifyImsFeatureReady(int slotId, int featureType)
+ throws RemoteException {
+ }
+
+ @Override
+ public IImsConfig getConfig(int slotId) throws RemoteException {
+ return new ImsConfigImplBase().getIImsConfig();
+ }
+
+ @Override
+ public IImsRegistration getRegistration(int slotId) throws RemoteException {
+ return new ImsRegistrationImplBase().getBinder();
+ }
+
+ @Override
+ public void enableIms(int slotId) {
+ }
+
+ @Override
+ public void disableIms(int slotId) {
+
+ }
+
}
private ImsServiceControllerBinder mBinder;
@@ -81,12 +107,7 @@
}
// Used by Mockito for verification that this method is being called in spy
- public IImsMMTelFeature createEmergencyMMTelFeature(int slotId) {
- return null;
- }
-
- // Used by Mockito for verification that this method is being called in spy
- public IImsMMTelFeature createMMTelFeature(int slotId) {
+ public IImsMmTelFeature createMMTelFeature(int slotId) {
return null;
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
index 120874b..2a2e38f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
@@ -17,14 +17,12 @@
package com.android.internal.telephony.imsphone;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
-import com.android.internal.telephony.Call;
+import android.telephony.ims.ImsCallProfile;
+
import com.android.internal.telephony.TelephonyTest;
import org.junit.After;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
index 8baa6cd..80be96c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
@@ -23,8 +23,8 @@
import android.net.Uri;
import android.support.test.filters.FlakyTest;
-import com.android.ims.ImsCallProfile;
-import com.android.ims.ImsExternalCallState;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsExternalCallState;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
index 5f88bb1..c602108 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
@@ -26,8 +26,8 @@
import android.support.test.filters.FlakyTest;
import android.test.suitebuilder.annotation.SmallTest;
+import android.telephony.ims.ImsStreamMediaProfile;
-import com.android.ims.ImsStreamMediaProfile;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.TelephonyTest;
@@ -42,7 +42,7 @@
ImsPhoneConnection mConnection1;
@Mock
ImsPhoneConnection mConnection2;
- @Mock
+
ImsStreamMediaProfile mMediaProfile;
private ImsPhoneCall mImsCallUT;
@@ -53,6 +53,7 @@
replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);
mImsCallUT = new ImsPhoneCall(mImsCT, ImsPhoneCall.CONTEXT_FOREGROUND);
+ mMediaProfile = new ImsStreamMediaProfile();
}
@After
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index 6f9b7de..4cda187 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -29,14 +29,13 @@
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isNull;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.app.PendingIntent;
import android.content.Context;
-import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
@@ -47,18 +46,18 @@
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsCall;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.ImsConfig;
-import com.android.ims.ImsConnectionStateListener;
import com.android.ims.ImsException;
-import com.android.ims.ImsManager;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.ImsServiceClass;
-import com.android.ims.ImsStreamMediaProfile;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsStreamMediaProfile;
+import com.android.ims.internal.IImsCallSession;
+import android.telephony.ims.ImsCallSession;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandsInterface;
@@ -79,7 +78,8 @@
public class ImsPhoneCallTrackerTest extends TelephonyTest {
private ImsPhoneCallTracker mCTUT;
private ImsCTHandlerThread mImsCTHandlerThread;
- private ImsConnectionStateListener mImsConnectionStateListener;
+ private MmTelFeature.Listener mMmTelListener;
+ private ImsFeature.CapabilityCallback mCapabilityCallback;
private ImsCall.Listener mImsCallListener;
private ImsCall mImsCall;
private ImsCall mSecondImsCall;
@@ -89,6 +89,10 @@
private ImsCallSession mImsCallSession;
@Mock
private SharedPreferences mSharedPreferences;
+ @Mock
+ private ImsPhoneConnection.Listener mImsPhoneConnectionListener;
+ @Mock
+ private ImsConfig mImsConfig;
private Handler mCTHander;
private class ImsCTHandlerThread extends HandlerThread {
@@ -170,20 +174,14 @@
mSecondImsCall = spy(new ImsCall(mContext, mImsCallProfile));
imsCallMocking(mImsCall);
imsCallMocking(mSecondImsCall);
- doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceStatus();
- doReturn(mImsCallProfile).when(mImsManager).createCallProfile(eq(mServiceId),
- anyInt(), anyInt());
+ doReturn(ImsFeature.STATE_READY).when(mImsManager).getImsServiceState();
+ doReturn(mImsCallProfile).when(mImsManager).createCallProfile(anyInt(), anyInt());
- //cache the listener
- doAnswer(new Answer<Integer>() {
- @Override
- public Integer answer(InvocationOnMock invocation) throws Throwable {
- mImsConnectionStateListener =
- (ImsConnectionStateListener) invocation.getArguments()[2];
- return mServiceId;
- }
- }).when(mImsManager).open(anyInt(), (PendingIntent) any(),
- (ImsConnectionStateListener) any());
+ doAnswer(invocation -> {
+ mMmTelListener = (MmTelFeature.Listener) invocation.getArguments()[0];
+ return null;
+ }).when(mImsManager).open(any(MmTelFeature.Listener.class));
+
doAnswer(new Answer<ImsCall>() {
@Override
@@ -192,18 +190,27 @@
(ImsCall.Listener) invocation.getArguments()[2];
return mImsCall;
}
- }).when(mImsManager).takeCall(eq(mServiceId), (Intent) any(), (ImsCall.Listener) any());
+ }).when(mImsManager).takeCall(any(), any(), any());
doAnswer(new Answer<ImsCall>() {
@Override
public ImsCall answer(InvocationOnMock invocation) throws Throwable {
- mImsCallListener =
- (ImsCall.Listener) invocation.getArguments()[3];
+ mImsCallListener = (ImsCall.Listener) invocation.getArguments()[2];
+ mSecondImsCall.setListener(mImsCallListener);
+
return mSecondImsCall;
}
- }).when(mImsManager).makeCall(eq(mServiceId), eq(mImsCallProfile), (String []) any(),
+ }).when(mImsManager).makeCall(eq(mImsCallProfile), (String []) any(),
(ImsCall.Listener) any());
+ doAnswer(invocation -> {
+ mCapabilityCallback = (ImsFeature.CapabilityCallback) invocation.getArguments()[0];
+ return mCapabilityCallback;
+
+ }).when(mImsManager).addCapabilitiesCallback(any(ImsFeature.CapabilityCallback.class));
+
+ doReturn(mImsConfig).when(mImsManager).getConfigInterface();
+
mImsCTHandlerThread = new ImsCTHandlerThread(this.getClass().getSimpleName());
mImsCTHandlerThread.start();
@@ -223,28 +230,28 @@
@Test
@SmallTest
public void testImsFeatureCapabilityChange() {
- int[] featureEnableArray = {-1, -1, -1, -1, -1, -1},
- featureDisableArray = {-1, -1, -1, -1, -1, -1};
+ doReturn(ImsRegistrationImplBase.REGISTRATION_TECH_LTE).when(
+ mImsManager).getRegistrationTech();
assertFalse(mCTUT.isVolteEnabled());
assertFalse(mCTUT.isVideoCallEnabled());
- //enable VoLTE feature
- featureEnableArray[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE] =
- ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
- mImsConnectionStateListener.onFeatureCapabilityChanged(ImsServiceClass.MMTEL,
- featureEnableArray,
- featureDisableArray);
+
+ // enable only Voice
+ ImsFeature.Capabilities caps = new ImsFeature.Capabilities();
+ caps.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ mCapabilityCallback.onCapabilitiesStatusChanged(caps);
waitForHandlerAction(mCTHander, 1000);
+
assertTrue(mCTUT.isVolteEnabled());
assertFalse(mCTUT.isVideoCallEnabled());
// video call not enabled
verify(mImsPhone, times(0)).notifyForVideoCapabilityChanged(anyBoolean());
verify(mImsPhone, times(1)).onFeatureCapabilityChanged();
+
// enable video call
- featureEnableArray[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE] =
- ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE;
- mImsConnectionStateListener.onFeatureCapabilityChanged(ImsServiceClass.MMTEL,
- featureEnableArray,
- featureDisableArray);
+ ImsFeature.Capabilities capsVideo = new ImsFeature.Capabilities();
+ capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ capsVideo.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+ mCapabilityCallback.onCapabilitiesStatusChanged(capsVideo);
waitForHandlerAction(mCTHander, 1000);
assertTrue(mCTUT.isVideoCallEnabled());
verify(mImsPhone, times(1)).notifyForVideoCapabilityChanged(eq(true));
@@ -256,8 +263,7 @@
assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
assertFalse(mCTUT.mRingingCall.isRinging());
// mock a MT call
- Intent mIntent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
- mContext.sendBroadcast(mIntent);
+ mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
verify(mImsPhone, times(1)).notifyNewRingingConnection((Connection) any());
verify(mImsPhone, times(1)).notifyIncomingRing();
assertEquals(PhoneConstants.State.RINGING, mCTUT.getState());
@@ -326,14 +332,13 @@
assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
// mock a new MT
try {
- doReturn(mSecondImsCall).when(mImsManager).takeCall(eq(0), (Intent) any(),
- (ImsCall.Listener) any());
+ doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
+ any(Bundle.class), any(ImsCall.Listener.class));
} catch (Exception ex) {
ex.printStackTrace();
Assert.fail("unexpected exception thrown" + ex.getMessage());
}
- Intent mIntent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
- mContext.sendBroadcast(mIntent);
+ mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
verify(mImsPhone, times(2)).notifyNewRingingConnection((Connection) any());
verify(mImsPhone, times(2)).notifyIncomingRing();
@@ -405,11 +410,11 @@
ArgumentCaptor<ImsCallProfile> profileCaptor = ArgumentCaptor.forClass(
ImsCallProfile.class);
- verify(mImsManager, times(1)).makeCall(eq(0), eq(mImsCallProfile),
- eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
+ verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
+ eq(new String[]{"+17005554141"}), any());
// Because this is an emergency call, we expect caller id to be visible now.
- verify(mImsCallProfile).setCallExtraInt(ImsCallProfile.EXTRA_OIR,
+ assertEquals(mImsCallProfile.getCallExtraInt(ImsCallProfile.EXTRA_OIR),
CommandsInterface.CLIR_SUPPRESSION);
} catch (CallStateException cse) {
cse.printStackTrace();
@@ -429,7 +434,7 @@
assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
try {
mCTUT.dial("+17005554141", ImsCallProfile.CALL_TYPE_VOICE, null);
- verify(mImsManager, times(1)).makeCall(eq(0), eq(mImsCallProfile),
+ verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
} catch (Exception ex) {
ex.printStackTrace();
@@ -456,7 +461,7 @@
assertEquals(Call.State.IDLE, mCTUT.mBackgroundCall.getState());
try {
mCTUT.dial("+17005554141", ImsCallProfile.CALL_TYPE_VOICE, null);
- verify(mImsManager, times(1)).makeCall(eq(mServiceId), eq(mImsCallProfile),
+ verify(mImsManager, times(1)).makeCall(eq(mImsCallProfile),
eq(new String[]{"+17005554141"}), (ImsCall.Listener) any());
} catch (Exception ex) {
ex.printStackTrace();
@@ -492,10 +497,9 @@
verify(mImsCall, times(1)).sendDtmf(eq(PhoneNumberUtils.PAUSE), (Message) isNull());
// mock a new MT
try {
- doReturn(mSecondImsCall).when(mImsManager).takeCall(eq(mServiceId), (Intent) any(),
- (ImsCall.Listener) any());
- Intent mIntent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
- mContext.sendBroadcast(mIntent);
+ doReturn(mSecondImsCall).when(mImsManager).takeCall(any(IImsCallSession.class),
+ any(Bundle.class), any(ImsCall.Listener.class));
+ mMmTelListener.onIncomingCall(mock(IImsCallSession.class), Bundle.EMPTY);
mCTUT.acceptCall(ImsCallProfile.CALL_TYPE_VOICE);
} catch (Exception ex) {
ex.printStackTrace();
@@ -529,7 +533,7 @@
@SmallTest
public void testDialImsServiceUnavailable() throws ImsException {
doThrow(new ImsException("Test Exception", ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN)).when(
- mImsManager).createCallProfile(anyInt(), anyInt(), anyInt());
+ mImsManager).createCallProfile(anyInt(), anyInt());
mCTUT.mRetryTimeout = () -> 0; //ms
assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
@@ -542,12 +546,12 @@
// wait for handler to process ImsService connection retry
waitForHandlerAction(mCTHander, 1000); // 1 second timeout
- verify(mImsManager, never()).makeCall(anyInt(), nullable(ImsCallProfile.class),
+ verify(mImsManager, never()).makeCall(nullable(ImsCallProfile.class),
eq(new String[]{"+17005554141"}), nullable(ImsCall.Listener.class));
// Make sure that open is called in ImsPhoneCallTracker when it was first connected and
// again after retry.
- verify(mImsManager, times(2)).open(anyInt(), nullable(PendingIntent.class),
- nullable(ImsConnectionStateListener.class));
+ verify(mImsManager, times(2)).open(
+ nullable(MmTelFeature.Listener.class));
}
@FlakyTest
@@ -567,8 +571,8 @@
waitForHandlerAction(mCTHander, 100);
// Make sure that open is called in ImsPhoneCallTracker to re-establish connection to
// ImsService
- verify(mImsManager, times(2)).open(anyInt(), nullable(PendingIntent.class),
- nullable(ImsConnectionStateListener.class));
+ verify(mImsManager, times(2)).open(
+ nullable(MmTelFeature.Listener.class));
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
index c089706..87d4467 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
@@ -23,10 +23,10 @@
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
+import android.telephony.ims.ImsCallProfile;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.ims.ImsCallProfile;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.GsmCdmaCall;
@@ -159,10 +159,10 @@
mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getNumberPresentation());
assertEquals(PhoneConstants.PRESENTATION_UNKNOWN, mConnectionUT.getCnapNamePresentation());
- doReturn(ImsCallProfile.OIR_PRESENTATION_PAYPHONE).when(mImsCallProfile)
- .getCallExtraInt(eq(ImsCallProfile.EXTRA_CNAP));
- doReturn(ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED).when(mImsCallProfile)
- .getCallExtraInt(eq(ImsCallProfile.EXTRA_OIR));
+ mImsCallProfile.setCallExtraInt(ImsCallProfile.EXTRA_CNAP,
+ ImsCallProfile.OIR_PRESENTATION_PAYPHONE);
+ mImsCallProfile.setCallExtraInt(ImsCallProfile.EXTRA_OIR,
+ ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED);
mConnectionUT.updateAddressDisplay(mImsCall);
assertEquals(ImsCallProfile.OIRToPresentation(ImsCallProfile.OIR_PRESENTATION_PAYPHONE),
@@ -287,8 +287,7 @@
mConnectionUT = new ImsPhoneConnection(mImsPhone, testAddress[0], mImsCT,
mForeGroundCall, false);
mConnectionUT.setIsIncoming(true);
- doReturn(testAddress[1]).when(mImsCallProfile)
- .getCallExtra(eq(ImsCallProfile.EXTRA_OI));
+ mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, testAddress[1]);
mConnectionUT.updateAddressDisplay(mImsCall);
assertEquals(testAddress[2], mConnectionUT.getAddress());
}
@@ -306,8 +305,7 @@
mConnectionUT = new ImsPhoneConnection(mImsPhone, inputAddress, mImsCT, mForeGroundCall,
false);
mConnectionUT.setIsIncoming(false);
- doReturn(updateAddress).when(mImsCallProfile)
- .getCallExtra(eq(ImsCallProfile.EXTRA_OI));
+ mImsCallProfile.setCallExtra(ImsCallProfile.EXTRA_OI, updateAddress);
mConnectionUT.updateAddressDisplay(mImsCall);
assertEquals(inputAddress, mConnectionUT.getAddress());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 5bc4df8..25ff7f5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -52,10 +52,10 @@
import android.telephony.ServiceState;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.ImsEcbmStateListener;
import com.android.ims.ImsManager;
-import com.android.ims.ImsReasonInfo;
+import android.telephony.ims.ImsReasonInfo;
import com.android.ims.ImsUtInterface;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CommandsInterface;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
index 146afd3..22d9f78 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
@@ -18,6 +18,7 @@
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
+import android.support.test.filters.FlakyTest;
import android.telecom.Connection;
import com.android.internal.telephony.TelephonyTest;
@@ -122,6 +123,7 @@
* Test that the text handler sends after enough characters have been sent from in-call
* @throws Exception
*/
+ @FlakyTest
@Test
public void testSendAfterEnoughChars() throws Exception {
// Register a read notifier
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
index 6d45db0..9d924ea 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
@@ -18,6 +18,7 @@
import static android.telephony.ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
import static android.telephony.ServiceState.ROAMING_TYPE_DOMESTIC;
+
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEACTIVATE_DATA_CALL;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
@@ -27,23 +28,25 @@
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IPV4V6;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
+import android.hardware.radio.V1_0.SetupDataCallResult;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
-import android.telephony.data.DataCallResponse;
+import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsCallSession;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.GsmCdmaConnection;
import com.android.internal.telephony.PhoneConstants;
@@ -69,7 +72,6 @@
import org.mockito.Mock;
import java.lang.reflect.Method;
-import java.util.Arrays;
public class TelephonyMetricsTest extends TelephonyTest {
@@ -77,9 +79,6 @@
private ImsCallSession mImsCallSession;
@Mock
- private ImsReasonInfo mImsReasonInfo;
-
- @Mock
private ServiceState mServiceState;
@Mock
@@ -89,15 +88,18 @@
private UUSInfo mUusInfo;
+ private ImsReasonInfo mImsReasonInfo;
+
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mMetrics = new TelephonyMetrics();
mUusInfo = new UUSInfo(1, 2, new byte[]{1, 2});
doReturn("123").when(mImsCallSession).getCallId();
- doReturn("extramessage").when(mImsReasonInfo).getExtraMessage();
- doReturn(123).when(mImsReasonInfo).getCode();
- doReturn(456).when(mImsReasonInfo).getExtraCode();
+ mImsReasonInfo = new ImsReasonInfo();
+ mImsReasonInfo.mExtraMessage = "extramessage";
+ mImsReasonInfo.mCode = 123;
+ mImsReasonInfo.mExtraCode = 456;
doReturn(ROAMING_TYPE_DOMESTIC).when(mServiceState).getVoiceRoamingType();
doReturn(ROAMING_TYPE_DOMESTIC).when(mServiceState).getDataRoamingType();
@@ -287,9 +289,11 @@
public void testWriteImsSetFeatureValue() throws Exception {
mMetrics.writeOnImsCallStart(mPhone.getPhoneId(), mImsCallSession);
mMetrics.writeImsSetFeatureValue(mPhone.getPhoneId(),
- ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE, 0, 1, 0);
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE, 1);
mMetrics.writeImsSetFeatureValue(mPhone.getPhoneId(),
- ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE, 0, 1, 0);
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE, 1);
mMetrics.writePhoneState(mPhone.getPhoneId(), PhoneConstants.State.IDLE);
TelephonyLog log = buildProto();
@@ -386,16 +390,21 @@
@Test
@SmallTest
public void testWriteOnSetupDataCallResponse() throws Exception {
- DataCallResponse response = new DataCallResponse(5, 6, 7, 8, "IPV4V6", FAKE_IFNAME,
- Arrays.asList(new LinkAddress(NetworkUtils.numericToInetAddress(FAKE_ADDRESS), 0)),
- Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_DNS)),
- Arrays.asList(NetworkUtils.numericToInetAddress(FAKE_GATEWAY)),
- Arrays.asList(FAKE_PCSCF_ADDRESS),
- 1440);
-
+ SetupDataCallResult result = new SetupDataCallResult();
+ result.status = 5;
+ result.suggestedRetryTime = 6;
+ result.cid = 7;
+ result.active = 8;
+ result.type = "IPV4V6";
+ result.ifname = FAKE_IFNAME;
+ result.addresses = FAKE_ADDRESS;
+ result.dnses = FAKE_DNS;
+ result.gateways = FAKE_GATEWAY;
+ result.pcscf = FAKE_PCSCF_ADDRESS;
+ result.mtu = 1440;
mMetrics.writeOnRilSolicitedResponse(mPhone.getPhoneId(), 1, 2,
- RIL_REQUEST_SETUP_DATA_CALL, response);
+ RIL_REQUEST_SETUP_DATA_CALL, result);
TelephonyLog log = buildProto();
assertEquals(1, log.events.length);
@@ -655,13 +664,19 @@
@Test
@SmallTest
public void testWriteOnImsCapabilities() throws Exception {
- boolean[] caps1 = new boolean[]{true, false, true, false, true, false};
- mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(), caps1);
- boolean[] caps2 = new boolean[]{true, false, true, false, true, false};
+ MmTelFeature.MmTelCapabilities caps1 = new MmTelFeature.MmTelCapabilities();
+ caps1.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+ caps1.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
+ mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(),
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE, caps1);
// The duplicate one should be filtered out.
- mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(), caps2);
- boolean[] caps3 = new boolean[]{false, true, false, true, false, true};
- mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(), caps3);
+ mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(),
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE, caps1);
+ MmTelFeature.MmTelCapabilities caps2 = new MmTelFeature.MmTelCapabilities();
+ caps2.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+ caps2.addCapabilities(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT);
+ mMetrics.writeOnImsCapabilities(mPhone.getPhoneId(),
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, caps2);
TelephonyLog log = buildProto();
assertEquals(2, log.events.length);
@@ -671,21 +686,27 @@
TelephonyEvent event = log.events[0];
assertEquals(TelephonyEvent.Type.IMS_CAPABILITIES_CHANGED, event.type);
- assertEquals(caps1[0], event.imsCapabilities.voiceOverLte);
- assertEquals(caps1[1], event.imsCapabilities.videoOverLte);
- assertEquals(caps1[2], event.imsCapabilities.voiceOverWifi);
- assertEquals(caps1[3], event.imsCapabilities.videoOverWifi);
- assertEquals(caps1[4], event.imsCapabilities.utOverLte);
- assertEquals(caps1[5], event.imsCapabilities.utOverWifi);
+ assertEquals(caps1.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
+ event.imsCapabilities.voiceOverLte);
+ assertEquals(caps1.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO),
+ event.imsCapabilities.videoOverLte);
+ assertEquals(caps1.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT),
+ event.imsCapabilities.utOverLte);
+ assertEquals(false, event.imsCapabilities.voiceOverWifi);
+ assertEquals(false, event.imsCapabilities.videoOverWifi);
+ assertEquals(false, event.imsCapabilities.utOverWifi);
event = log.events[1];
assertEquals(TelephonyEvent.Type.IMS_CAPABILITIES_CHANGED, event.type);
- assertEquals(caps3[0], event.imsCapabilities.voiceOverLte);
- assertEquals(caps3[1], event.imsCapabilities.videoOverLte);
- assertEquals(caps3[2], event.imsCapabilities.voiceOverWifi);
- assertEquals(caps3[3], event.imsCapabilities.videoOverWifi);
- assertEquals(caps3[4], event.imsCapabilities.utOverLte);
- assertEquals(caps3[5], event.imsCapabilities.utOverWifi);
+ assertEquals(caps2.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE),
+ event.imsCapabilities.voiceOverWifi);
+ assertEquals(caps2.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO),
+ event.imsCapabilities.videoOverWifi);
+ assertEquals(caps2.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT),
+ event.imsCapabilities.utOverWifi);
+ assertEquals(false, event.imsCapabilities.voiceOverLte);
+ assertEquals(false, event.imsCapabilities.videoOverLte);
+ assertEquals(false, event.imsCapabilities.utOverLte);
}
}