Merge "Tests for correct decoding when TP-OA contains non-integer information"
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index e4e7f35..5960051 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -1392,11 +1392,14 @@
case EVENT_CONFERENCE_RESULT:
if (isPhoneTypeGsm()) {
- // The conference merge failed, so notify listeners. Ultimately this bubbles up
- // to Telecom, which will inform the InCall UI of the failure.
- Connection connection = mForegroundCall.getLatestConnection();
- if (connection != null) {
- connection.onConferenceMergeFailed();
+ ar = (AsyncResult) msg.obj;
+ if (ar.exception != null) {
+ // The conference merge failed, so notify listeners. Ultimately this
+ // bubbles up to Telecom, which will inform the InCall UI of the failure.
+ Connection connection = mForegroundCall.getLatestConnection();
+ if (connection != null) {
+ connection.onConferenceMergeFailed();
+ }
}
}
// fall through
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index b4884fd..9873d97 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -2065,6 +2065,7 @@
private void syncClirSetting() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
int clirSetting = sp.getInt(CLIR_KEY + getPhoneId(), -1);
+ Rlog.i(LOG_TAG, "syncClirSetting: " + CLIR_KEY + getPhoneId() + "=" + clirSetting);
if (clirSetting >= 0) {
mCi.setCLIR(clirSetting, null);
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 75b6052..1ccf1c4 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -1333,6 +1333,8 @@
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sp.edit();
editor.putInt(CLIR_KEY + getPhoneId(), commandInterfaceCLIRMode);
+ Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getPhoneId() + "=" +
+ commandInterfaceCLIRMode);
// Commit and log the result.
if (!editor.commit()) {
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 4598b0c..2ec5101 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -76,6 +76,7 @@
import android.widget.TextView;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccController;
@@ -970,7 +971,8 @@
* raw pdu of the status report is in the extended data ("pdu").
* -param destAddr the destination phone number (for short code confirmation)
*/
- protected void sendRawPdu(SmsTracker tracker) {
+ @VisibleForTesting
+ public void sendRawPdu(SmsTracker tracker) {
HashMap map = tracker.getData();
byte pdu[] = (byte[]) map.get("pdu");
@@ -1075,7 +1077,7 @@
// Wait for user confirmation unless the user has set permission to always allow/deny
int premiumSmsPermission = mUsageMonitor.getPremiumSmsPermission(
- tracker.mAppInfo.packageName);
+ tracker.getAppPackageName());
if (premiumSmsPermission == SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
// First time trying to send to premium SMS.
premiumSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER;
@@ -1150,7 +1152,7 @@
return; // queue limit reached; error was returned to caller
}
- CharSequence appLabel = getAppLabel(tracker.mAppInfo.packageName, tracker.mUserId);
+ CharSequence appLabel = getAppLabel(tracker.getAppPackageName(), tracker.mUserId);
Resources r = Resources.getSystem();
Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel));
@@ -1188,7 +1190,7 @@
detailsId = R.string.sms_short_code_details;
}
- CharSequence appLabel = getAppLabel(tracker.mAppInfo.packageName, tracker.mUserId);
+ CharSequence appLabel = getAppLabel(tracker.getAppPackageName(), tracker.mUserId);
Resources r = Resources.getSystem();
Spanned messageText = Html.fromHtml(r.getString(R.string.sms_short_code_confirm_message,
appLabel, tracker.mDestAddress));
@@ -1401,6 +1403,14 @@
}
/**
+ * Get the App package name
+ * @return App package name info
+ */
+ public String getAppPackageName() {
+ return mAppInfo != null ? mAppInfo.packageName : null;
+ }
+
+ /**
* Update the status of this message if we persisted it
*/
public void updateSentMessageStatus(Context context, int status) {
@@ -1710,7 +1720,7 @@
}
sendMessage(msg);
}
- setPremiumSmsPermission(mTracker.mAppInfo.packageName, newSmsPermission);
+ setPremiumSmsPermission(mTracker.getAppPackageName(), newSmsPermission);
}
@Override
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 2049d05..fb8231e 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -721,6 +721,7 @@
try {
mPhone.notifySignalStrength();
notified = true;
+ mLastSignalStrength = mSignalStrength;
} catch (NullPointerException ex) {
loge("updateSignalStrength() Phone already destroyed: " + ex
+ "SignalStrength not notified");
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index 73e9a42..402a5ef 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -29,8 +29,8 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
-import android.util.AtomicFile;
import android.telephony.Rlog;
+import android.util.AtomicFile;
import android.util.Xml;
import com.android.internal.util.FastXmlSerializer;
@@ -48,10 +48,10 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
/**
@@ -85,7 +85,7 @@
static final int CATEGORY_STANDARD_SHORT_CODE = 2;
/** Return value from {@link #checkDestination} for possible premium short codes. */
- static final int CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+ public static final int CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
/** Return value from {@link #checkDestination} for premium short codes. */
static final int CATEGORY_PREMIUM_SHORT_CODE = 4;
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 634a3c4..5bd3eea 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -113,6 +113,10 @@
void onPhoneStateChanged(PhoneConstants.State oldState, PhoneConstants.State newState);
}
+ public interface SharedPreferenceProxy {
+ SharedPreferences getDefaultSharedPreferences(Context context);
+ }
+
private static final boolean DBG = true;
// When true, dumps the state of ImsPhoneCallTracker after changes to foreground and background
@@ -128,6 +132,7 @@
"UTLTE", "UTWiFi"};
private TelephonyMetrics mMetrics;
+ private boolean mCarrierConfigLoaded = false;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -212,6 +217,7 @@
log("onReceive : Updating mAllowEmergencyVideoCalls = " +
mAllowEmergencyVideoCalls);
}
+ mCarrierConfigLoaded = true;
} else if (TelecomManager.ACTION_CHANGE_DEFAULT_DIALER.equals(intent.getAction())) {
mDefaultDialerUid.set(getPackageUid(context, intent.getStringExtra(
TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME)));
@@ -598,6 +604,13 @@
*/
private boolean mShouldUpdateImsConfigOnDisconnect = false;
+ /**
+ * Default implementation for retrieving shared preferences; uses the actual PreferencesManager.
+ */
+ private SharedPreferenceProxy mSharedPreferenceProxy = (Context context) -> {
+ return PreferenceManager.getDefaultSharedPreferences(context);
+ };
+
// Callback fires when ImsManager MMTel Feature changes state
private ImsServiceProxy.INotifyStatusChanged mNotifyStatusChangedCallback = () -> {
try {
@@ -678,11 +691,23 @@
sendEmptyMessage(EVENT_GET_IMS_SERVICE);
}
+ /**
+ * Test-only method used to mock out access to the shared preferences through the
+ * {@link PreferenceManager}.
+ * @param sharedPreferenceProxy
+ */
+ @VisibleForTesting
+ public void setSharedPreferenceProxy(SharedPreferenceProxy sharedPreferenceProxy) {
+ mSharedPreferenceProxy = sharedPreferenceProxy;
+ }
+
private int getPackageUid(Context context, String pkg) {
if (pkg == null) {
return NetworkStats.UID_ALL;
}
+ // Initialize to UID_ALL so at least it can be counted to overall data usage if
+ // the dialer's package uid is not available.
int uid = NetworkStats.UID_ALL;
try {
uid = context.getPackageManager().getPackageUid(pkg, 0);
@@ -735,10 +760,16 @@
multiEndpoint.setExternalCallStateListener(
mPhone.getExternalCallTracker().getExternalCallStateListener());
}
+
+ if (mCarrierConfigLoaded) {
+ ImsManager.updateImsServiceConfig(mPhone.getContext(),
+ mPhone.getPhoneId(), true);
+ }
}
private void stopListeningForCalls() {
try {
+ resetImsCapabilities();
// Only close on valid session.
if (mImsManager != null && mServiceId > 0) {
mImsManager.close(mServiceId);
@@ -794,8 +825,16 @@
public Connection dial(String dialString, int videoState, Bundle intentExtras) throws
CallStateException {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
- int oirMode = sp.getInt(Phone.CLIR_KEY, CommandsInterface.CLIR_DEFAULT);
+ int oirMode;
+ if (mSharedPreferenceProxy != null && mPhone.getDefaultPhone() != null) {
+ SharedPreferences sp = mSharedPreferenceProxy.getDefaultSharedPreferences(
+ mPhone.getContext());
+ oirMode = sp.getInt(Phone.CLIR_KEY + mPhone.getDefaultPhone().getPhoneId(),
+ CommandsInterface.CLIR_DEFAULT);
+ } else {
+ loge("dial; could not get default CLIR mode.");
+ oirMode = CommandsInterface.CLIR_DEFAULT;
+ }
return dial(dialString, oirMode, videoState, intentExtras);
}
@@ -2302,10 +2341,21 @@
mPhone.stopOnHoldTone(conn);
mOnHoldToneStarted = false;
}
-
conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_UNHELD, null);
}
+ boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_useVideoPauseWorkaround);
+ if (useVideoPauseWorkaround && mSupportPauseVideo &&
+ VideoProfile.isVideo(conn.getVideoState())) {
+ // If we are using the video pause workaround, the vendor IMS code has issues
+ // with video pause signalling. In this case, when a call is remotely
+ // held, the modem does not reliably change the video state of the call to be
+ // paused.
+ // As a workaround, we will turn on that bit now.
+ conn.changeToUnPausedState();
+ }
+
SuppServiceNotification supp = new SuppServiceNotification();
// Type of notification: 0 = MO; 1 = MT
// Refer SuppServiceNotification class documentation.
@@ -2327,8 +2377,19 @@
mOnHoldToneStarted = true;
mOnHoldToneId = System.identityHashCode(conn);
}
-
conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_REMOTELY_HELD, null);
+
+ boolean useVideoPauseWorkaround = mPhone.getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_useVideoPauseWorkaround);
+ if (useVideoPauseWorkaround && mSupportPauseVideo &&
+ VideoProfile.isVideo(conn.getVideoState())) {
+ // If we are using the video pause workaround, the vendor IMS code has issues
+ // with video pause signalling. In this case, when a call is remotely
+ // held, the modem does not reliably change the video state of the call to be
+ // paused.
+ // As a workaround, we will turn on that bit now.
+ conn.changeToPausedState();
+ }
}
SuppServiceNotification supp = new SuppServiceNotification();
@@ -2907,6 +2968,17 @@
// a separate entry if uid is different from the previous snapshot.
NetworkStats vtDataUsageUidSnapshot = new NetworkStats(currentTime, 1);
vtDataUsageUidSnapshot.combineAllValues(mVtDataUsageUidSnapshot);
+
+ // The dialer uid might not be initialized correctly during boot up due to telecom service
+ // not ready or its default dialer cache not ready. So we double check again here to see if
+ // default dialer uid is really not available.
+ if (mDefaultDialerUid.get() == NetworkStats.UID_ALL) {
+ final TelecomManager telecomManager =
+ (TelecomManager) mPhone.getContext().getSystemService(Context.TELECOM_SERVICE);
+ mDefaultDialerUid.set(
+ getPackageUid(mPhone.getContext(), telecomManager.getDefaultDialerPackage()));
+ }
+
// Since the modem only reports the total vt data usage rather than rx/tx separately,
// the only thing we can do here is splitting the usage into half rx and half tx.
vtDataUsageUidSnapshot.combineValues(new NetworkStats.Entry(
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index 4f99a57..b39a6fb 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -828,10 +828,7 @@
}
if (!mShouldIgnoreVideoStateChanges) {
- if (mImsVideoCallProviderWrapper != null) {
- mImsVideoCallProviderWrapper.onVideoStateChanged(newVideoState);
- }
- setVideoState(newVideoState);
+ updateVideoState(newVideoState);
changed = true;
} else {
Rlog.d(LOG_TAG, "updateMediaCapabilities - ignoring video state change " +
@@ -894,6 +891,13 @@
return changed;
}
+ private void updateVideoState(int newVideoState) {
+ if (mImsVideoCallProviderWrapper != null) {
+ mImsVideoCallProviderWrapper.onVideoStateChanged(newVideoState);
+ }
+ setVideoState(newVideoState);
+ }
+
public void sendRttModifyRequest(android.telecom.Connection.RttTextStream textStream) {
getImsCall().sendRttModifyRequest();
setCurrentRttTextStream(textStream);
@@ -1175,4 +1179,18 @@
return mImsVideoCallProviderWrapper.wasVideoPausedFromSource(source);
}
+
+ public void changeToPausedState() {
+ int newVideoState = getVideoState() | VideoProfile.STATE_PAUSED;
+ Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToPausedState - setting paused bit; "
+ + "newVideoState=" + VideoProfile.videoStateToString(newVideoState));
+ updateVideoState(newVideoState);
+ }
+
+ public void changeToUnPausedState() {
+ int newVideoState = getVideoState() & ~VideoProfile.STATE_PAUSED;
+ Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToUnPausedState - unsetting paused bit; "
+ + "newVideoState=" + VideoProfile.videoStateToString(newVideoState));
+ updateVideoState(newVideoState);
+ }
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index fa0add5..93d54d0 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -94,6 +94,8 @@
private static final String TAG_PKG_REF_DO = "CA";
private static final String TAG_AR_DO = "E3";
private static final String TAG_PERM_AR_DO = "DB";
+ private static final String TAG_AID_REF_DO = "4F";
+ private static final String CARRIER_PRIVILEGE_AID = "FFFFFFFFFFFF";
private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 1;
private static final int EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE = 2;
@@ -562,37 +564,52 @@
if (rule.startsWith(TAG_REF_DO)) {
TLV refDo = new TLV(TAG_REF_DO); //E1
rule = refDo.parse(rule, false);
-
- // Skip unrelated rules.
- if (!refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
+ // Allow 4F tag with a default value "FF FF FF FF FF FF" to be compatible with
+ // devices having GP access control enforcer:
+ // - If no 4F tag is present, it's a CP rule.
+ // - If 4F tag has value "FF FF FF FF FF FF", it's a CP rule.
+ // - If 4F tag has other values, it's not a CP rule and Android should ignore it.
+ TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1
+ if (refDo.value.startsWith(TAG_AID_REF_DO)) {
+ TLV cpDo = new TLV(TAG_AID_REF_DO); //4F
+ String remain = cpDo.parse(refDo.value, false);
+ if (!cpDo.lengthBytes.equals("06") || !cpDo.value.equals(CARRIER_PRIVILEGE_AID)
+ || remain.isEmpty() || !remain.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
+ return null;
+ }
+ tmp = deviceDo.parse(remain, false);
+ certificateHash = deviceDo.value;
+ } else if (refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
+ tmp = deviceDo.parse(refDo.value, false);
+ certificateHash = deviceDo.value;
+ } else {
return null;
}
-
- TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO); //C1
- tmp = deviceDo.parse(refDo.value, false);
- certificateHash = deviceDo.value;
-
if (!tmp.isEmpty()) {
- if (!tmp.startsWith(TAG_PKG_REF_DO)) {
- return null;
- }
- TLV pkgDo = new TLV(TAG_PKG_REF_DO); //CA
- pkgDo.parse(tmp, true);
- packageName = new String(IccUtils.hexStringToBytes(pkgDo.value));
+ if (!tmp.startsWith(TAG_PKG_REF_DO)) {
+ return null;
+ }
+ TLV pkgDo = new TLV(TAG_PKG_REF_DO); //CA
+ pkgDo.parse(tmp, true);
+ packageName = new String(IccUtils.hexStringToBytes(pkgDo.value));
} else {
- packageName = null;
+ packageName = null;
}
} else if (rule.startsWith(TAG_AR_DO)) {
TLV arDo = new TLV(TAG_AR_DO); //E3
rule = arDo.parse(rule, false);
-
- // Skip unrelated rules.
- if (!arDo.value.startsWith(TAG_PERM_AR_DO)) {
+ // Skip all the irrelevant tags (All the optional tags here are two bytes
+ // according to the spec GlobalPlatform Secure Element Access Control).
+ String remain = arDo.value;
+ while (!remain.isEmpty() && !remain.startsWith(TAG_PERM_AR_DO)) {
+ TLV tmpDo = new TLV(remain.substring(0, 2));
+ remain = tmpDo.parse(remain, false);
+ }
+ if (remain.isEmpty()) {
return null;
}
-
TLV permDo = new TLV(TAG_PERM_AR_DO); //DB
- permDo.parse(arDo.value, true);
+ permDo.parse(remain, true);
} else {
// Spec requires it must be either TAG_REF_DO or TAG_AR_DO.
throw new RuntimeException("Invalid Rule type");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index d62a23a..23e30a2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -439,7 +439,14 @@
@Override
public int checkCallingOrSelfPermission(String permission) {
- return PackageManager.PERMISSION_GRANTED;
+ if (mPermissionTable.contains(permission)
+ || mPermissionTable.contains(PERMISSION_ENABLE_ALL)) {
+ logd("checkCallingOrSelfPermission: " + permission + " return GRANTED");
+ return PackageManager.PERMISSION_GRANTED;
+ } else {
+ logd("checkCallingOrSelfPermission: " + permission + " return DENIED");
+ return PackageManager.PERMISSION_DENIED;
+ }
}
@Override
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
index 8ab749c..335634d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -16,9 +16,14 @@
package com.android.internal.telephony.gsm;
+import static android.telephony.SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED;
+
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
+import static com.android.internal.telephony.SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW;
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -35,6 +40,7 @@
import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.provider.Telephony;
import android.support.test.filters.FlakyTest;
import android.telephony.SmsManager;
@@ -42,8 +48,10 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Singleton;
+import com.android.internal.telephony.ContextFixture;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.ImsSMSDispatcher;
+import com.android.internal.telephony.SMSDispatcher;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.TelephonyTestUtils;
import com.android.internal.telephony.TestApplication;
@@ -51,8 +59,11 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import java.util.HashMap;
+
public class GsmSmsDispatcherTest extends TelephonyTest {
@Mock
private android.telephony.SmsMessage mSmsMessage;
@@ -65,6 +76,8 @@
@Mock
private CountryDetector mCountryDetector;
@Mock
+ private SMSDispatcher.SmsTracker mSmsTracker;
+ @Mock
private ISub.Stub mISubStub;
private Object mLock = new Object();
private boolean mReceivedTestIntent = false;
@@ -191,4 +204,35 @@
assertEquals(SmsManager.RESULT_ERROR_NULL_PDU, mTestReceiver.getResultCode());
}
}
+
+ @Test
+ public void testSendRawPduWithEventStopSending() throws Exception {
+ setupMockPackagePermissionChecks();
+ mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+
+ // return a fake value to pass getData()
+ HashMap data = new HashMap<String, String>();
+ data.put("pdu", new byte[1]);
+ when(mSmsTracker.getData()).thenReturn(data);
+
+ // Set values to return to simulate EVENT_STOP_SENDING
+ when(mSmsUsageMonitor.checkDestination(any(), any()))
+ .thenReturn(CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE);
+ when(mSmsUsageMonitor.getPremiumSmsPermission(any()))
+ .thenReturn(PREMIUM_SMS_PERMISSION_NEVER_ALLOW);
+ when(mSmsTracker.getAppPackageName()).thenReturn("");
+
+ // Settings.Global.DEVICE_PROVISIONED to 1
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+
+ mGsmSmsDispatcher.sendRawPdu(mSmsTracker);
+
+ verify(mSmsUsageMonitor, times(1)).checkDestination(any(), any());
+ verify(mSmsUsageMonitor, times(1)).getPremiumSmsPermission(any());
+ ArgumentCaptor<Integer> argumentCaptor = ArgumentCaptor
+ .forClass(Integer.class);
+ verify(mSmsTracker, times(1)).onFailed(any(), argumentCaptor.capture(), anyInt());
+ assertEquals(RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED, (int) argumentCaptor.getValue());
+ }
}
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 0b3d6f1..be8d6f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -37,12 +37,14 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.test.filters.FlakyTest;
import android.telephony.DisconnectCause;
+import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
import android.telephony.ims.feature.ImsFeature;
import android.test.suitebuilder.annotation.SmallTest;
@@ -57,6 +59,8 @@
import com.android.ims.ImsServiceClass;
import com.android.ims.internal.ImsCallSession;
import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyTest;
@@ -66,6 +70,7 @@
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -81,6 +86,8 @@
private int mServiceId;
@Mock
private ImsCallSession mImsCallSession;
+ @Mock
+ private SharedPreferences mSharedPreferences;
private Handler mCTHander;
private class ImsCTHandlerThread extends HandlerThread {
@@ -348,6 +355,31 @@
assertEquals(Call.State.HOLDING, mCTUT.mBackgroundCall.getState());
}
+ /**
+ * Ensures that the dial method will perform a shared preferences lookup using the correct
+ * shared preference key to determine the CLIR mode.
+ */
+ @Test
+ @SmallTest
+ public void testDialClirMode() {
+ mCTUT.setSharedPreferenceProxy((Context context) -> {
+ return mSharedPreferences;
+ });
+ ArgumentCaptor<String> mStringCaptor = ArgumentCaptor.forClass(String.class);
+ doReturn(CommandsInterface.CLIR_INVOCATION).when(mSharedPreferences).getInt(
+ mStringCaptor.capture(), anyInt());
+
+ try {
+ mCTUT.dial("+17005554141", VideoProfile.STATE_AUDIO_ONLY, null);
+ } catch (CallStateException cse) {
+ cse.printStackTrace();
+ Assert.fail("unexpected exception thrown" + cse.getMessage());
+ }
+
+ // Ensure that the correct key was queried from the shared prefs.
+ assertEquals("clir_key0", mStringCaptor.getValue());
+ }
+
@FlakyTest
@Test
@SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
new file mode 100644
index 0000000..e6ca407
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.uicc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doAnswer;
+
+import android.content.pm.Signature;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.telephony.TelephonyTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+public class UiccCarrierPrivilegeRulesTest extends TelephonyTest {
+ private UiccCarrierPrivilegeRules mUiccCarrierPrivilegeRules;
+ public UiccCarrierPrivilegeRulesTest() {
+ super();
+ }
+ private UiccCarrierPrivilegeRulesHandlerThread mTestHandlerThread;
+ private Handler mHandler;
+
+ private static final int EVENT_OPEN_LOGICAL_CHANNEL_DONE = 1;
+ private static final int EVENT_TEST_DONE = 2;
+
+ @Mock
+ private UiccCard mUiccCard;
+
+ private class UiccCarrierPrivilegeRulesHandlerThread extends HandlerThread {
+
+ private UiccCarrierPrivilegeRulesHandlerThread(String name) {
+ super(name);
+ }
+
+ @Override
+ public void onLooperPrepared() {
+ /* create a custom handler for the Handler Thread */
+ mHandler = new Handler(mTestHandlerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_OPEN_LOGICAL_CHANNEL_DONE:
+ /* Upon handling this event, new CarrierPrivilegeRule
+ will be created with the looper of HandlerThread */
+ mUiccCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(
+ mUiccCard, mHandler.obtainMessage(EVENT_TEST_DONE));
+ break;
+ case EVENT_TEST_DONE:
+ setReady(true);
+ break;
+ default:
+ logd("Unknown Event " + msg.what);
+ }
+ }
+ };
+ setReady(true);
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp(getClass().getSimpleName());
+ mTestHandlerThread = new UiccCarrierPrivilegeRulesHandlerThread(TAG);
+ mTestHandlerThread.start();
+
+ waitUntilReady();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mTestHandlerThread.quit();
+ super.tearDown();
+ mUiccCarrierPrivilegeRules = null;
+ }
+
+ private void testHelper(String hexString) {
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Message message = (Message) invocation.getArguments()[2];
+ AsyncResult ar = new AsyncResult(null, new int[]{0}, null);
+ message.obj = ar;
+ message.sendToTarget();
+ return null;
+ }
+ }).when(mUiccCard).iccOpenLogicalChannel(anyString(), anyInt(), any(Message.class));
+
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Message message = (Message) invocation.getArguments()[7];
+ IccIoResult iir = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes(hexString));
+ AsyncResult ar = new AsyncResult(null, iir, null);
+ message.obj = ar;
+ message.sendToTarget();
+ return null;
+ }
+ }).when(mUiccCard).iccTransmitApduLogicalChannel(anyInt(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyString(), any(Message.class));
+
+
+ Message mCardOpenLogicalChannel = mHandler.obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE);
+ setReady(false);
+ mCardOpenLogicalChannel.sendToTarget();
+ waitUntilReady();
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_Normal() {
+ /**
+ * FF40 45
+ * E2 43
+ * E1 35
+ * C1 14 ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4
+ * CA 1D 636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070
+ * E3 0A
+ * DB 08 0000000000000001
+ */
+ final String hexString =
+ "FF4045E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4CA1D636F6D2E676F6F676"
+ + "C652E616E64726F69642E617070732E6D79617070E30ADB080000000000000001";
+
+ testHelper(hexString);
+
+ assertTrue(mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(1, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ assertEquals("com.google.android.apps.myapp",
+ mUiccCarrierPrivilegeRules.getPackageNames().get(0));
+ Signature signature = new Signature("abcd92cbb156b280fa4e1429a6eceeb6e5c1bfe4");
+ assertEquals(0, mUiccCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature,
+ mUiccCarrierPrivilegeRules.getPackageNames().get(0)));
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_With4FD0D1() {
+ /**
+ * FF40 34
+ * E2 32
+ * E1 1E
+ * 4F 06 FF FF FF FF FF FF
+ * C1 14 B6 1B E3 4A D2 C2 0D 7A FE D8 49 3C 31 3A 13 7F 89 FA 27 65
+ * E3 10
+ * D0 01 01
+ * D1 01 01
+ * DB 08 00 00 00 00 00 00 00 01
+ */
+ final String hexString = "FF4034E232E11E4F06FFFFFFFFFFFFC114B61BE34AD2C20D7AFED84"
+ + "93C313A137F89FA2765E310D00101D10101DB080000000000000001";
+
+ testHelper(hexString);
+
+ assertTrue(mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(0, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_With4FD0() {
+ /**
+ * FF40 31
+ * E2 2F
+ * E1 1E
+ * 4F 06 FF FF FF FF FF FF
+ * C1 14 B6 1B E3 4A D2 C2 0D 7A FE D8 49 3C 31 3A 13 7F 89 FA 27 65
+ * E3 0D
+ * D0 01 01
+ * DB 08 00 00 00 00 00 00 00 01
+ */
+ final String hexString = "FF4031E22FE11E4F06FFFFFFFFFFFFC114B61BE34AD2C20D7AFED8493C313A"
+ + "137F89FA2765E30DD00101DB080000000000000001";
+
+ testHelper(hexString);
+
+ assertTrue(mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(0, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_TwoMessages() {
+ /**
+ * FF40 68
+ * E2 39
+ * E1 2B
+ * 4F 06 FFFFFFFFFFFF
+ * C1 02 B61B
+ * CA 1D 636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070
+ * E3 0A
+ * D0 01 01
+ * D1 01 01
+ * DB 02 0001
+ * E2 2B
+ * E1 23
+ * C1 02 ABCD
+ * CA 1D 636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070
+ * E3 04
+ * DB 02 0001
+ */
+ final String hexString =
+ "FF4068E239E12B4F06FFFFFFFFFFFFC102B61BCA1D636F6D2E676F6F676C652E616E64726F69642"
+ + "E617070732E6D79617070E30AD00101D10101DB020001E22BE123C102ABCDCA1D636F"
+ + "6D2E676F6F676C652E616E64726F69642E617070732E6D79617070E304DB020001";
+
+ testHelper(hexString);
+
+ assertTrue(mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(2, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ assertEquals("com.google.android.apps.myapp",
+ mUiccCarrierPrivilegeRules.getPackageNames().get(0));
+ Signature signature1 = new Signature("b61b");
+ assertEquals(0, mUiccCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature1,
+ mUiccCarrierPrivilegeRules.getPackageNames().get(0)));
+
+ assertEquals("com.google.android.apps.myapp",
+ mUiccCarrierPrivilegeRules.getPackageNames().get(1));
+ Signature signature2 = new Signature("abcd");
+ assertEquals(0, mUiccCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature2,
+ mUiccCarrierPrivilegeRules.getPackageNames().get(0)));
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_InvalidRulesWith4F00() {
+ /**
+ * FF40 24
+ * E2 22
+ * E1 18
+ * 4F 00
+ * C1 14 75C073AFD219AEB221948E828F066E778ADFDF23
+ * E3 06
+ * D0 01 01
+ * D1 01 01
+ */
+ final String hexString = "FF4024E222E1184F00C11475C073AFD219AEB221948E828F066E778ADFDF23"
+ + "E306D00101D10101";
+
+ testHelper(hexString);
+
+ assertTrue(!mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(0, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ }
+
+ @Test
+ @SmallTest
+ public void testHandleMessage_InvalidRulesWithoutDB() {
+ /**
+ * FF40 2A
+ * E2 28
+ * E1 1E
+ * 4F 06 FF FF FF FF FF FF
+ * C1 14 B6 1B E3 4A D2 C2 0D 7A FE D8 49 3C 31 3A 13 7F 89 FA 27 65
+ * E3 06
+ * D0 01 01
+ * D1 01 01
+ */
+ final String hexString = "FF402AE228E11E4F06FFFFFFFFFFFFC114B61BE34AD2C20D7AFED8493C313A"
+ + "137F89FA2765E306D00101D10101";
+
+ testHelper(hexString);
+
+ assertTrue(!mUiccCarrierPrivilegeRules.hasCarrierPrivilegeRules());
+ assertEquals(0, mUiccCarrierPrivilegeRules.getPackageNames().size());
+ }
+}