Merge "LegacyState does not send notifyDisplayInfoChanged am: 545dd7778c am: 6acc0754d3 am: b5a0a93648" into rvc-qpr-dev-plus-aosp am: f111895a79
Change-Id: I4db55ff770ad4db3d07a54023e6cd12a7593ac4d
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 6790fa7..466aca3 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -74,6 +74,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.UiccAccessRule;
import android.telephony.UssdResponse;
import android.telephony.data.ApnSetting;
import android.text.TextUtils;
@@ -115,6 +116,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
@@ -182,7 +184,7 @@
private SIMRecords mSimRecords;
// For non-persisted manual network selection
- private String mManualNetworkSelectionPlmn = "";
+ private String mManualNetworkSelectionPlmn;
//Common
// Instance Variables
@@ -1889,7 +1891,23 @@
public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn) {
mCarrierResolver.setTestOverrideApn(apn);
- mCarrierResolver.setTestOverrideCarrierPriviledgeRule(carrierPrivilegeRules);
+ UiccProfile uiccProfile = mUiccController.getUiccProfileForPhone(getPhoneId());
+ if (uiccProfile != null) {
+ List<UiccAccessRule> testRules;
+ if (carrierPrivilegeRules == null) {
+ testRules = null;
+ } else if (carrierPrivilegeRules.isEmpty()) {
+ testRules = Collections.emptyList();
+ } else {
+ UiccAccessRule accessRule = new UiccAccessRule(
+ IccUtils.hexStringToBytes(carrierPrivilegeRules), null, 0);
+ testRules = Collections.singletonList(accessRule);
+ }
+ uiccProfile.setTestOverrideCarrierPrivilegeRules(testRules);
+ } else {
+ // TODO: Fix "privilege" typo throughout telephony.
+ mCarrierResolver.setTestOverrideCarrierPriviledgeRule(carrierPrivilegeRules); // NOTYPO
+ }
IccRecords r = null;
if (isPhoneTypeGsm()) {
r = mIccRecords.get();
@@ -1972,7 +1990,7 @@
mManualNetworkSelectionPlmn = nsm.operatorNumeric;
} else {
//on Phone0 in emergency mode (no SIM), or in some races then clear the cache
- mManualNetworkSelectionPlmn = "";
+ mManualNetworkSelectionPlmn = null;
Rlog.e(LOG_TAG, "Cannot update network selection due to invalid subId "
+ subId);
}
@@ -3078,7 +3096,8 @@
case EVENT_SET_CARRIER_DATA_ENABLED:
ar = (AsyncResult) msg.obj;
boolean enabled = (boolean) ar.result;
- mDataEnabledSettings.setCarrierDataEnabled(enabled);
+ mDataEnabledSettings.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
+ enabled);
break;
case EVENT_DEVICE_PROVISIONED_CHANGE:
mDataEnabledSettings.updateProvisionedChanged();
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index c99b282..8182994 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -405,12 +405,12 @@
isRetry,
pdu);
mMetrics.writeImsServiceSendSms(mPhone.getPhoneId(), format,
- ImsSmsImplBase.SEND_STATUS_OK);
+ ImsSmsImplBase.SEND_STATUS_OK, tracker.mMessageId);
} catch (ImsException e) {
loge("sendSms failed. Falling back to PSTN. Error: " + e.getMessage());
fallbackToPstn(token, tracker);
mMetrics.writeImsServiceSendSms(mPhone.getPhoneId(), format,
- ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK);
+ ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK, tracker.mMessageId);
}
}
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 992a454..ec0ae09 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -24,6 +24,7 @@
import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
@@ -83,6 +84,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
/**
@@ -163,7 +165,7 @@
public static final int EVENT_BROADCAST_SMS = 2;
/** Message from resultReceiver notifying {@link WaitingState} of a completed broadcast. */
- private static final int EVENT_BROADCAST_COMPLETE = 3;
+ public static final int EVENT_BROADCAST_COMPLETE = 3;
/** Sent on exit from {@link WaitingState} to return to idle after sending all broadcasts. */
private static final int EVENT_RETURN_TO_IDLE = 4;
@@ -258,6 +260,8 @@
others in order to update metrics. */
private boolean mLastSmsWasInjected = false;
+ private List<SmsFilter> mSmsFilters;
+
/**
* Create a new SMS broadcast helper.
* @param name the class name for logging
@@ -287,6 +291,8 @@
(PowerWhitelistManager) mContext.getSystemService(Context.POWER_WHITELIST_MANAGER);
mCellBroadcastServiceManager = new CellBroadcastServiceManager(context, phone);
+ mSmsFilters = createDefaultSmsFilters();
+
addState(mDefaultState);
addState(mStartupState, mDefaultState);
addState(mIdleState, mDefaultState);
@@ -1091,51 +1097,77 @@
}
/**
+ * Creates the default filters used to filter SMS messages.
+ *
+ * <p>Currently 3 filters exist: the carrier package, the VisualVoicemailSmsFilter, and the
+ * missed incoming call SMS filter.
+ *
+ * <p>Since the carrier filter is asynchronous, if a message passes through the carrier filter,
+ * the remaining filters will be applied in the callback.
+ */
+ private List<SmsFilter> createDefaultSmsFilters() {
+ List<SmsFilter> smsFilters = new ArrayList<>(3);
+ smsFilters.add(
+ (pdus, destPort, tracker, resultReceiver, userUnlocked, remainingFilters) -> {
+ CarrierServicesSmsFilterCallback filterCallback =
+ new CarrierServicesSmsFilterCallback(
+ pdus, destPort, tracker, tracker.getFormat(), resultReceiver,
+ userUnlocked,
+ tracker.isClass0(), tracker.getSubId(), tracker.getMessageId(),
+ remainingFilters);
+ CarrierServicesSmsFilter carrierServicesFilter = new CarrierServicesSmsFilter(
+ mContext, mPhone, pdus, destPort, tracker.getFormat(),
+ filterCallback, getName(), mLocalLog);
+ return carrierServicesFilter.filter();
+ });
+ smsFilters.add(
+ (pdus, destPort, tracker, resultReceiver, userUnlocked, remainingFilters) -> {
+ if (VisualVoicemailSmsFilter.filter(
+ mContext, pdus, tracker.getFormat(), destPort, tracker.getSubId())) {
+ log("Visual voicemail SMS dropped");
+ dropSms(resultReceiver);
+ return true;
+ }
+ return false;
+ });
+ smsFilters.add(
+ (pdus, destPort, tracker, resultReceiver, userUnlocked, remainingFilters) -> {
+ MissedIncomingCallSmsFilter missedIncomingCallSmsFilter =
+ new MissedIncomingCallSmsFilter(mPhone);
+ if (missedIncomingCallSmsFilter.filter(pdus, tracker.getFormat())) {
+ log("Missed incoming call SMS received.");
+ dropSms(resultReceiver);
+ return true;
+ }
+ return false;
+ });
+ return smsFilters;
+ }
+
+ /**
* Filters the SMS.
*
- * <p>currently 3 filters exists: the carrier package, the system package, and the
- * VisualVoicemailSmsFilter.
- *
- * <p>The filtering process is:
- *
- * <p>If the carrier package exists, the SMS will be filtered with it first. If the carrier
- * package did not drop the SMS, then the VisualVoicemailSmsFilter will filter it in the
- * callback.
- *
- * <p>If the carrier package does not exists, we will let the VisualVoicemailSmsFilter filter
- * it. If the SMS passed the filter, then we will try to find the system package to do the
- * filtering.
+ * <p>Each filter in {@link #mSmsFilters} is invoked sequentially. If any filter returns true,
+ * this method returns true and subsequent filters are ignored.
*
* @return true if a filter is invoked and the SMS processing flow is diverted, false otherwise.
*/
private boolean filterSms(byte[][] pdus, int destPort,
- InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked) {
- CarrierServicesSmsFilterCallback filterCallback =
- new CarrierServicesSmsFilterCallback(
- pdus, destPort, tracker.getFormat(), resultReceiver, userUnlocked,
- tracker.isClass0(), tracker.getSubId(), tracker.getMessageId());
- CarrierServicesSmsFilter carrierServicesFilter = new CarrierServicesSmsFilter(
- mContext, mPhone, pdus, destPort, tracker.getFormat(),
- filterCallback, getName(), mLocalLog);
- if (carrierServicesFilter.filter()) {
- return true;
- }
+ InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked) {
+ return filterSms(pdus, destPort, tracker, resultReceiver, userUnlocked, mSmsFilters);
+ }
- if (VisualVoicemailSmsFilter.filter(
- mContext, pdus, tracker.getFormat(), destPort, tracker.getSubId())) {
- log("Visual voicemail SMS dropped");
- dropSms(resultReceiver);
- return true;
+ private static boolean filterSms(byte[][] pdus, int destPort,
+ InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked,
+ List<SmsFilter> filters) {
+ ListIterator<SmsFilter> iterator = filters.listIterator();
+ while (iterator.hasNext()) {
+ SmsFilter smsFilter = iterator.next();
+ if (smsFilter.filterSms(pdus, destPort, tracker, resultReceiver, userUnlocked,
+ filters.subList(iterator.nextIndex(), filters.size()))) {
+ return true;
+ }
}
-
- MissedIncomingCallSmsFilter missedIncomingCallSmsFilter =
- new MissedIncomingCallSmsFilter(mPhone);
- if (missedIncomingCallSmsFilter.filter(pdus, tracker.getFormat())) {
- log("Missed incoming call SMS received.");
- dropSms(resultReceiver);
- return true;
- }
-
return false;
}
@@ -1476,7 +1508,8 @@
* Handler for an {@link InboundSmsTracker} broadcast. Deletes PDUs from the raw table and
* logs the broadcast duration (as an error if the other receivers were especially slow).
*/
- private final class SmsBroadcastReceiver extends BroadcastReceiver {
+ @VisibleForTesting
+ public final class SmsBroadcastReceiver extends BroadcastReceiver {
@UnsupportedAppUsage
private final String mDeleteWhere;
@UnsupportedAppUsage
@@ -1561,35 +1594,37 @@
CarrierServicesSmsFilter.CarrierServicesSmsFilterCallbackInterface {
private final byte[][] mPdus;
private final int mDestPort;
+ private final InboundSmsTracker mTracker;
private final String mSmsFormat;
private final SmsBroadcastReceiver mSmsBroadcastReceiver;
private final boolean mUserUnlocked;
private final boolean mIsClass0;
private final int mSubId;
private final long mMessageId;
+ private final List<SmsFilter> mRemainingFilters;
- CarrierServicesSmsFilterCallback(byte[][] pdus, int destPort, String smsFormat,
- SmsBroadcastReceiver smsBroadcastReceiver, boolean userUnlocked,
- boolean isClass0, int subId, long messageId) {
+ CarrierServicesSmsFilterCallback(byte[][] pdus, int destPort, InboundSmsTracker tracker,
+ String smsFormat, SmsBroadcastReceiver smsBroadcastReceiver, boolean userUnlocked,
+ boolean isClass0, int subId, long messageId, List<SmsFilter> remainingFilters) {
mPdus = pdus;
mDestPort = destPort;
+ mTracker = tracker;
mSmsFormat = smsFormat;
mSmsBroadcastReceiver = smsBroadcastReceiver;
mUserUnlocked = userUnlocked;
mIsClass0 = isClass0;
mSubId = subId;
mMessageId = messageId;
+ mRemainingFilters = remainingFilters;
}
@Override
public void onFilterComplete(int result) {
logv("onFilterComplete: result is " + result);
if ((result & CarrierMessagingService.RECEIVE_OPTIONS_DROP) == 0) {
- if (VisualVoicemailSmsFilter.filter(mContext, mPdus,
- mSmsFormat, mDestPort, mSubId)) {
- log("Visual voicemail SMS dropped"
- + " id: " + mMessageId);
- dropSms(mSmsBroadcastReceiver);
+ // Message isn't dropped, so run it through the remaining filters.
+ if (filterSms(mPdus, mDestPort, mTracker, mSmsBroadcastReceiver, mUserUnlocked,
+ mRemainingFilters)) {
return;
}
@@ -1768,6 +1803,20 @@
}
/**
+ * Set the SMS filters used by {@link #filterSms} for testing purposes.
+ *
+ * @param smsFilters List of SMS filters, or null to restore the default filters.
+ */
+ @VisibleForTesting
+ public void setSmsFiltersForTesting(@Nullable List<SmsFilter> smsFilters) {
+ if (smsFilters == null) {
+ mSmsFilters = createDefaultSmsFilters();
+ } else {
+ mSmsFilters = smsFilters;
+ }
+ }
+
+ /**
* Handler for the broadcast sent when the new message notification is clicked. It launches the
* default SMS app.
*/
@@ -1846,4 +1895,16 @@
}
}
}
+
+ /** A filter for incoming messages allowing the normal processing flow to be skipped. */
+ @VisibleForTesting
+ public interface SmsFilter {
+ /**
+ * Returns true if a filter is invoked and the SMS processing flow should be diverted, false
+ * otherwise.
+ */
+ boolean filterSms(byte[][] pdus, int destPort, InboundSmsTracker tracker,
+ SmsBroadcastReceiver resultReceiver, boolean userUnlocked,
+ List<SmsFilter> remainingFilters);
+ }
}
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index a90daf9..e8c7dc9 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -699,7 +699,8 @@
&& phone.isUserDataEnabled()
&& !areSubscriptionsInSameGroup(defaultDataSub, phone.getSubId())) {
log("setting data to false on " + phone.getSubId());
- phone.getDataEnabledSettings().setUserDataEnabled(false);
+ phone.getDataEnabledSettings().setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
}
}
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 5188ba0..22d372f 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -1980,7 +1980,7 @@
* Retrieves manually selected network info.
*/
public String getManualNetworkSelectionPlmn() {
- return "";
+ return null;
}
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index e7a6d44..f767340 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -1643,13 +1643,30 @@
try {
radioProxy.sendSms(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
- SmsSession.Event.Format.SMS_FORMAT_3GPP);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendSMS", e);
}
}
}
+ /**
+ * Extract the outgoing sms messageId from the tracker, if there is one. This is specifically
+ * for SMS related APIs.
+ * @param result the result Message
+ * @return messageId unique identifier or 0 if there is no message id
+ */
+ public static long getOutgoingSmsMessageId(Message result) {
+ if (result == null || !(result.obj instanceof SMSDispatcher.SmsTracker)) {
+ return 0L;
+ }
+ long messageId = ((SMSDispatcher.SmsTracker) result.obj).mMessageId;
+ if (RILJ_LOGV) {
+ Rlog.d(RILJ_LOG_TAG, "getOutgoingSmsMessageId messageId: " + messageId);
+ }
+ return messageId;
+ }
+
@Override
public void sendSMSExpectMore(String smscPdu, String pdu, Message result) {
IRadio radioProxy = getRadioProxy(result);
@@ -1665,7 +1682,7 @@
try {
radioProxy.sendSMSExpectMore(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
- SmsSession.Event.Format.SMS_FORMAT_3GPP);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
}
@@ -3521,7 +3538,8 @@
try {
radioProxy15.sendCdmaSmsExpectMore(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
- SmsSession.Event.Format.SMS_FORMAT_3GPP2);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP2,
+ getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendCdmaSMSExpectMore", e);
}
@@ -3547,7 +3565,7 @@
try {
radioProxy.sendCdmaSms(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
- SmsSession.Event.Format.SMS_FORMAT_3GPP2);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP2, getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
}
@@ -4072,7 +4090,7 @@
try {
radioProxy.sendImsSms(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
- SmsSession.Event.Format.SMS_FORMAT_3GPP);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendImsGsmSms", e);
}
@@ -4101,7 +4119,7 @@
try {
radioProxy.sendImsSms(rr.mSerial, msg);
mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
- SmsSession.Event.Format.SMS_FORMAT_3GPP2);
+ SmsSession.Event.Format.SMS_FORMAT_3GPP2, getOutgoingSmsMessageId(result));
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
}
@@ -5599,9 +5617,9 @@
}
private void processResponseCleanUp(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
- mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error,
- rr.mRequest, ret);
if (rr != null) {
+ mMetrics.writeOnRilSolicitedResponse(mPhoneId, rr.mSerial, responseInfo.error,
+ rr.mRequest, ret);
if (responseInfo.type == RadioResponseType.SOLICITED) {
decrementWakeLock(rr);
}
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index 0afbd13..ffebae4 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -2157,7 +2157,8 @@
RILRequest rr = mRil.processResponse(responseInfo);
if (rr != null) {
- SmsResponse ret = new SmsResponse(sms.messageRef, sms.ackPDU, sms.errorCode);
+ long messageId = RIL.getOutgoingSmsMessageId(rr.mResult);
+ SmsResponse ret = new SmsResponse(sms.messageRef, sms.ackPDU, sms.errorCode, messageId);
if (responseInfo.error == RadioError.NONE) {
sendMessageResponse(rr.mResult, ret);
}
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index c7f8c1b..30162b2 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -514,7 +514,8 @@
return;
}
- SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE);
+ SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE,
+ tracker.mMessageId);
switch (result) {
case CarrierMessagingService.SEND_STATUS_OK:
diff --git a/src/java/com/android/internal/telephony/SmsResponse.java b/src/java/com/android/internal/telephony/SmsResponse.java
index e2209be..5e9aab2 100644
--- a/src/java/com/android/internal/telephony/SmsResponse.java
+++ b/src/java/com/android/internal/telephony/SmsResponse.java
@@ -39,18 +39,26 @@
@UnsupportedAppUsage
public int mErrorCode;
+ public long mMessageId;
+
@UnsupportedAppUsage
public SmsResponse(int messageRef, String ackPdu, int errorCode) {
+ this(messageRef, ackPdu, errorCode, /* messageId= */ 0L);
+ }
+
+ public SmsResponse(int messageRef, String ackPdu, int errorCode, long messageId) {
mMessageRef = messageRef;
mAckPdu = ackPdu;
mErrorCode = errorCode;
+ mMessageId = messageId;
}
@Override
public String toString() {
String ret = "{ mMessageRef = " + mMessageRef
+ ", mErrorCode = " + mErrorCode
- + ", mAckPdu = " + mAckPdu
+ + ", mAckPdu = " + mAckPdu
+ + ", mMessageId = " + mMessageId
+ "}";
return ret;
}
diff --git a/src/java/com/android/internal/telephony/SmsUsageMonitor.java b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
index 8f583d9..5bf2792 100644
--- a/src/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import android.app.role.RoleManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
@@ -51,6 +52,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
@@ -125,6 +127,8 @@
/** Last modified time for pattern file */
private long mPatternFileLastModified = 0;
+ private RoleManager mRoleManager;
+
/** Directory for per-app SMS permission XML file. */
private static final String SMS_POLICY_FILE_DIRECTORY = "/data/misc/sms";
@@ -248,6 +252,7 @@
public SmsUsageMonitor(Context context) {
mContext = context;
ContentResolver resolver = context.getContentResolver();
+ mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
mMaxAllowed = Settings.Global.getInt(resolver,
Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
@@ -345,7 +350,7 @@
/**
* Check to see if an application is allowed to send new SMS messages, and confirm with
* user if the send limit was reached or if a non-system app is potentially sending to a
- * premium SMS short code or number.
+ * premium SMS short code or number. If the app is the default SMS app, there's no send limit.
*
* @param appName the package name of the app requesting to send an SMS
* @param smsWaiting the number of new messages desired to send
@@ -363,7 +368,12 @@
mSmsStamp.put(appName, sentList);
}
- return isUnderLimit(sentList, smsWaiting);
+ List<String> defaultApp = mRoleManager.getRoleHolders(RoleManager.ROLE_SMS);
+ if (defaultApp.contains(appName)) {
+ return true;
+ } else {
+ return isUnderLimit(sentList, smsWaiting);
+ }
}
}
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index dc842d2..036d61c 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -576,10 +576,6 @@
}
}
- // Update set of enabled carrier apps now that the privilege rules may have changed.
- CarrierAppUtils.disableCarrierAppsUntilPrivileged(sContext.getOpPackageName(),
- TelephonyManager.getDefault(), mCurrentlyActiveUserId, sContext);
-
/**
* The sim loading sequence will be
* 1. ACTION_SUBINFO_CONTENT_CHANGE happens through updateSubscriptionInfoByIccId() above.
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index 10c9db6..fc4619c 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -69,7 +69,8 @@
REASON_PROVISIONED_CHANGED,
REASON_PROVISIONING_DATA_ENABLED_CHANGED,
REASON_OVERRIDE_RULE_CHANGED,
- REASON_OVERRIDE_CONDITION_CHANGED
+ REASON_OVERRIDE_CONDITION_CHANGED,
+ REASON_THERMAL_DATA_ENABLED
})
public @interface DataEnabledChangedReason {}
@@ -91,6 +92,8 @@
public static final int REASON_OVERRIDE_CONDITION_CHANGED = 8;
+ public static final int REASON_THERMAL_DATA_ENABLED = 9;
+
/**
* responds to the setInternalDataEnabled call - used internally to turn off data.
* For example during emergency calls
@@ -108,6 +111,15 @@
*/
private boolean mCarrierDataEnabled = true;
+ /**
+ * Flag indicating data allowed by Thermal service or not.
+ */
+ private boolean mThermalDataEnabled = true;
+
+ /**
+ * Flag indicating whether data is allowed or not for the device. It can be disabled by
+ * user, carrier, policy or thermal
+ */
private boolean mIsDataEnabled = false;
private final Phone mPhone;
@@ -172,6 +184,7 @@
+ ", mPolicyDataEnabled=" + mPolicyDataEnabled
+ ", mCarrierDataEnabled=" + mCarrierDataEnabled
+ ", mIsDataEnabled=" + mIsDataEnabled
+ + ", mThermalDataEnabled=" + mThermalDataEnabled
+ ", " + mDataEnabledOverride
+ "]";
}
@@ -204,7 +217,7 @@
return mInternalDataEnabled;
}
- public synchronized void setUserDataEnabled(boolean enabled) {
+ private synchronized void setUserDataEnabled(boolean enabled) {
// By default the change should propagate to the group.
setUserDataEnabled(enabled, true);
}
@@ -233,6 +246,32 @@
}
}
+ /**
+ * Policy control of data connection with reason
+ * @param reason the reason the data enable change is taking place
+ * @param enabled True if enabling the data, otherwise disabling.
+ */
+ public synchronized void setDataEnabled(@TelephonyManager.DataEnabledReason int reason,
+ boolean enabled) {
+ switch (reason) {
+ case TelephonyManager.DATA_ENABLED_REASON_USER:
+ setUserDataEnabled(enabled);
+ break;
+ case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
+ setCarrierDataEnabled(enabled);
+ break;
+ case TelephonyManager.DATA_ENABLED_REASON_POLICY:
+ setPolicyDataEnabled(enabled);
+ break;
+ case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
+ setThermalDataEnabled(enabled);
+ break;
+ default:
+ log("Invalid data enable reason " + reason);
+ break;
+ }
+ }
+
public synchronized boolean isUserDataEnabled() {
// User data should always be true for opportunistic subscription.
if (isStandAloneOpportunistic(mPhone.getSubId(), mPhone.getContext())) return true;
@@ -300,7 +339,7 @@
return mDataEnabledOverride.isDataAllowedInVoiceCall();
}
- public synchronized void setPolicyDataEnabled(boolean enabled) {
+ private synchronized void setPolicyDataEnabled(boolean enabled) {
if (mPolicyDataEnabled != enabled) {
localLog("PolicyDataEnabled", enabled);
mPolicyDataEnabled = enabled;
@@ -312,7 +351,7 @@
return mPolicyDataEnabled;
}
- public synchronized void setCarrierDataEnabled(boolean enabled) {
+ private synchronized void setCarrierDataEnabled(boolean enabled) {
if (mCarrierDataEnabled != enabled) {
localLog("CarrierDataEnabled", enabled);
mCarrierDataEnabled = enabled;
@@ -324,6 +363,18 @@
return mCarrierDataEnabled;
}
+ private synchronized void setThermalDataEnabled(boolean enabled) {
+ if (mThermalDataEnabled != enabled) {
+ localLog("ThermalDataEnabled", enabled);
+ mThermalDataEnabled = enabled;
+ updateDataEnabledAndNotify(REASON_THERMAL_DATA_ENABLED);
+ }
+ }
+
+ public synchronized boolean isThermalDataEnabled() {
+ return mThermalDataEnabled;
+ }
+
public synchronized void updateProvisionedChanged() {
updateDataEnabledAndNotify(REASON_PROVISIONED_CHANGED);
}
@@ -336,6 +387,27 @@
return mIsDataEnabled;
}
+ /**
+ * Check if data is enabled for a specific reason {@@TelephonyManager.DataEnabledReason}
+ *
+ * @return {@code true} if the overall data is enabled; {@code false} if not.
+ */
+ public synchronized boolean isDataEnabledWithReason(
+ @TelephonyManager.DataEnabledReason int reason) {
+ switch (reason) {
+ case TelephonyManager.DATA_ENABLED_REASON_USER:
+ return isUserDataEnabled();
+ case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
+ return isCarrierDataEnabled();
+ case TelephonyManager.DATA_ENABLED_REASON_POLICY:
+ return isPolicyDataEnabled();
+ case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
+ return isThermalDataEnabled();
+ default:
+ return false;
+ }
+ }
+
private synchronized void updateDataEnabledAndNotify(int reason) {
boolean prevDataEnabled = mIsDataEnabled;
@@ -352,7 +424,7 @@
} else {
mIsDataEnabled = mInternalDataEnabled && (isUserDataEnabled() || mDataEnabledOverride
.shouldOverrideDataEnabledSettings(mPhone, ApnSetting.TYPE_ALL))
- && mPolicyDataEnabled && mCarrierDataEnabled;
+ && mPolicyDataEnabled && mCarrierDataEnabled && mThermalDataEnabled;
}
}
@@ -469,7 +541,7 @@
.shouldOverrideDataEnabledSettings(mPhone, apnType);
return (mInternalDataEnabled && mPolicyDataEnabled && mCarrierDataEnabled
- && (userDataEnabled || isDataEnabledOverridden));
+ && mThermalDataEnabled && (userDataEnabled || isDataEnabledOverridden));
}
}
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 246d2e0..bf81bd5 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -1820,8 +1820,10 @@
} else {
int errorCode = SmsResponse.NO_ERROR_CODE;
+ long messageId = 0L;
if (response != null) {
errorCode = response.mErrorCode;
+ messageId = response.mMessageId;
}
smsSession.addEvent(new SmsSessionEventBuilder(
@@ -1829,6 +1831,7 @@
.setErrorCode(errorCode)
.setRilErrno(rilError + 1)
.setRilRequestId(rilSerial)
+ .setMessageId(messageId)
);
smsSession.decreaseExpectedResponse();
@@ -1856,7 +1859,7 @@
SmsSession.Event.Type.SMS_SEND_RESULT)
.setImsServiceErrno(resultCode)
.setErrorCode(errorReason)
- .setMessageId((messageId))
+ .setMessageId(messageId)
);
smsSession.decreaseExpectedResponse();
@@ -2237,14 +2240,17 @@
* @param rilSerial RIL request serial number
* @param tech SMS RAT
* @param format SMS format. Either 3GPP or 3GPP2.
+ * @param messageId Unique id for this message.
*/
- public synchronized void writeRilSendSms(int phoneId, int rilSerial, int tech, int format) {
+ public synchronized void writeRilSendSms(int phoneId, int rilSerial, int tech, int format,
+ long messageId) {
InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_SEND)
.setTech(tech)
.setRilRequestId(rilSerial)
.setFormat(format)
+ .setMessageId(messageId)
);
smsSession.increaseExpectedResponse();
@@ -2259,14 +2265,16 @@
* {@link SmsMessage#FORMAT_3GPP2}.
* @param resultCode The result of sending the new SMS to the vendor layer to be sent to the
* carrier network.
+ * @param messageId Unique id for this message.
*/
public synchronized void writeImsServiceSendSms(int phoneId, String format,
- @ImsSmsImplBase.SendStatusResult int resultCode) {
+ @ImsSmsImplBase.SendStatusResult int resultCode, long messageId) {
InProgressSmsSession smsSession = startNewSmsSessionIfNeeded(phoneId);
smsSession.addEvent(new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_SEND)
.setTech(SmsSession.Event.Tech.SMS_IMS)
.setImsServiceErrno(resultCode)
.setFormat(convertSmsFormat(format))
+ .setMessageId(messageId)
);
smsSession.increaseExpectedResponse();
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index e1bc0b7..c1a6960 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -32,6 +32,7 @@
import android.text.TextUtils;
import android.util.LocalLog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandException;
import com.android.telephony.Rlog;
@@ -228,6 +229,14 @@
openChannel(mAIDInUse);
}
+ @VisibleForTesting
+ public UiccCarrierPrivilegeRules(List<UiccAccessRule> rules) {
+ mAccessRules = rules;
+ mState = new AtomicInteger(STATE_LOADED);
+ mRules = "";
+ mStatusMessage.log("Loaded from test rules.");
+ }
+
/**
* Returns true if the carrier privilege rules have finished loading.
*/
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index a0276c7..cac849e 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.uicc;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -48,6 +50,7 @@
import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccCardConstants;
@@ -106,6 +109,7 @@
private final UiccCard mUiccCard; //parent
private CatService mCatService;
private UiccCarrierPrivilegeRules mCarrierPrivilegeRules;
+ private UiccCarrierPrivilegeRules mTestOverrideCarrierPrivilegeRules;
private boolean mDisposed = false;
private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList();
@@ -128,6 +132,7 @@
private static final int EVENT_SIM_IO_DONE = 12;
private static final int EVENT_CARRIER_PRIVILEGES_LOADED = 13;
private static final int EVENT_CARRIER_CONFIG_CHANGED = 14;
+ private static final int EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET = 15;
// NOTE: any new EVENT_* values must be added to eventToString.
private TelephonyManager mTelephonyManager;
@@ -245,6 +250,16 @@
((Message) ar.userObj).sendToTarget();
break;
+ case EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET:
+ if (msg.obj == null) {
+ mTestOverrideCarrierPrivilegeRules = null;
+ } else {
+ mTestOverrideCarrierPrivilegeRules =
+ new UiccCarrierPrivilegeRules((List<UiccAccessRule>) msg.obj);
+ }
+ refresh();
+ break;
+
default:
loge("handleMessage: Unhandled message with number: " + msg.what);
break;
@@ -1250,6 +1265,11 @@
}
private void onCarrierPrivilegesLoadedMessage() {
+ // Update set of enabled carrier apps now that the privilege rules may have changed.
+ ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
+ mTelephonyManager, am.getCurrentUser(), mContext);
+
UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(
Context.USAGE_STATS_SERVICE);
if (usm != null) {
@@ -1317,11 +1337,12 @@
if (certPackageMap.isEmpty()) {
return Collections.emptySet();
}
- if (mCarrierPrivilegeRules == null) {
+ UiccCarrierPrivilegeRules rules = getCarrierPrivilegeRules();
+ if (rules == null) {
return Collections.emptySet();
}
Set<String> uninstalledCarrierPackages = new ArraySet<>();
- List<UiccAccessRule> accessRules = mCarrierPrivilegeRules.getAccessRules();
+ List<UiccAccessRule> accessRules = rules.getAccessRules();
for (UiccAccessRule accessRule : accessRules) {
String certHexString = accessRule.getCertificateHexString().toUpperCase();
String pkgName = certPackageMap.get(certHexString);
@@ -1661,6 +1682,9 @@
/** Returns a reference to the current {@link UiccCarrierPrivilegeRules}. */
private UiccCarrierPrivilegeRules getCarrierPrivilegeRules() {
synchronized (mLock) {
+ if (mTestOverrideCarrierPrivilegeRules != null) {
+ return mTestOverrideCarrierPrivilegeRules;
+ }
return mCarrierPrivilegeRules;
}
}
@@ -1728,11 +1752,14 @@
case EVENT_ICC_RECORD_EVENTS: return "ICC_RECORD_EVENTS";
case EVENT_OPEN_LOGICAL_CHANNEL_DONE: return "OPEN_LOGICAL_CHANNEL_DONE";
case EVENT_CLOSE_LOGICAL_CHANNEL_DONE: return "CLOSE_LOGICAL_CHANNEL_DONE";
- case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: return "TRANSMIT_APDU_LOGICAL_CHANNEL_DONE";
+ case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
+ return "TRANSMIT_APDU_LOGICAL_CHANNEL_DONE";
case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: return "TRANSMIT_APDU_BASIC_CHANNEL_DONE";
case EVENT_SIM_IO_DONE: return "SIM_IO_DONE";
case EVENT_CARRIER_PRIVILEGES_LOADED: return "CARRIER_PRIVILEGES_LOADED";
case EVENT_CARRIER_CONFIG_CHANGED: return "CARRIER_CONFIG_CHANGED";
+ case EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET:
+ return "CARRIER_PRIVILEGES_TEST_OVERRIDE_SET";
default: return "UNKNOWN(" + event + ")";
}
}
@@ -1760,6 +1787,19 @@
}
/**
+ * Set a test set of carrier privilege rules which will override the actual rules on the SIM.
+ *
+ * <p>May be null, in which case the rules on the SIM will be used and any previous overrides
+ * will be cleared.
+ *
+ * @see TelephonyManager#setCarrierTestOverride
+ */
+ public void setTestOverrideCarrierPrivilegeRules(@Nullable List<UiccAccessRule> rules) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(EVENT_CARRIER_PRIVILEGES_TEST_OVERRIDE_SET, rules));
+ }
+
+ /**
* Dump
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1812,6 +1852,11 @@
pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules);
mCarrierPrivilegeRules.dump(fd, pw, args);
}
+ if (mTestOverrideCarrierPrivilegeRules != null) {
+ pw.println(" mTestOverrideCarrierPrivilegeRules: "
+ + mTestOverrideCarrierPrivilegeRules);
+ mTestOverrideCarrierPrivilegeRules.dump(fd, pw, args);
+ }
pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size());
for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
pw.println(" mCarrierPrivilegeRegistrants[" + i + "]="
diff --git a/src/java/com/android/internal/telephony/vendor/VendorMultiSimSettingController.java b/src/java/com/android/internal/telephony/vendor/VendorMultiSimSettingController.java
index 026b6f5..117b0ea 100644
--- a/src/java/com/android/internal/telephony/vendor/VendorMultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/vendor/VendorMultiSimSettingController.java
@@ -18,17 +18,17 @@
import android.content.Context;
import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
import android.util.Log;
+
import com.android.internal.telephony.GlobalSettingsHelper;
import com.android.internal.telephony.MultiSimSettingController;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.SubscriptionController;
import java.util.List;
-import java.util.stream.Collectors;
/*
* Extending VendorMultiSimSettingController to override default
@@ -90,7 +90,8 @@
// For active subscription, call setUserDataEnabled through DataEnabledSettings.
Phone phone = PhoneFactory.getPhone(mSubController.getPhoneId(currentSubId));
if (phone != null) {
- phone.getDataEnabledSettings().setUserDataEnabled(enable);
+ phone.getDataEnabledSettings().setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, enable);
}
} else {
// For inactive subscription, directly write into global settings.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index 106a2a8..a0e786f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -290,6 +290,8 @@
return Context.POWER_WHITELIST_MANAGER;
} else if (serviceClass == SystemConfigManager.class) {
return Context.SYSTEM_CONFIG_SERVICE;
+ } else if (serviceClass == ActivityManager.class) {
+ return Context.ACTIVITY_SERVICE;
}
return super.getSystemServiceName(serviceClass);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index af72c70..04e2eee 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -313,7 +313,8 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
// Enable on non-default sub should trigger setDefaultDataSubId.
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
@@ -324,7 +325,8 @@
doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
processAllMessages();
- verify(mDataEnabledSettingsMock1).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock1).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
doReturn(1).when(mSubControllerMock).getDefaultSmsSubId();
@@ -391,7 +393,8 @@
doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
processAllMessages();
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, false);
processAllMessages();
assertFalse(GlobalSettingsHelper.getBoolean(
@@ -439,7 +442,8 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
verify(mSubControllerMock).setDefaultDataSubId(2);
- verify(mDataEnabledSettingsMock1, never()).setUserDataEnabled(anyBoolean());
+ verify(mDataEnabledSettingsMock1, never()).setDataEnabled(
+ anyInt(), anyBoolean());
// No user selection needed, no intent should be sent.
verify(mContext, never()).sendBroadcast(any());
@@ -456,8 +460,10 @@
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
processAllMessages();
verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
- verify(mDataEnabledSettingsMock1, never()).setUserDataEnabled(anyBoolean());
- verify(mDataEnabledSettingsMock2, never()).setUserDataEnabled(anyBoolean());
+ verify(mDataEnabledSettingsMock1, never()).setDataEnabled(
+ eq(TelephonyManager.DATA_ENABLED_REASON_USER), anyBoolean());
+ verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
}
@Test
@@ -551,13 +557,16 @@
// loaded on both subscriptions.
mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
processAllMessages();
- verify(mDataEnabledSettingsMock2, never()).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
processAllMessages();
- verify(mDataEnabledSettingsMock2, never()).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
// Switch from sub 2 to sub 3 in phone[1].
clearInvocations(mSubControllerMock);
@@ -639,7 +648,8 @@
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
processAllMessages();
// Nothing should happen as carrier config is not ready for sub 2.
- verify(mDataEnabledSettingsMock2, never()).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
// Still notify carrier config without specifying subId2, but this time subController
// and CarrierConfigManager have subId 2 active and ready.
@@ -651,6 +661,7 @@
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
processAllMessages();
// This time user data should be disabled on phone1.
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(false);
+ verify(mDataEnabledSettingsMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
index 52c9573..b3fe158 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.verify;
import android.os.HandlerThread;
+import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
@@ -104,7 +105,7 @@
@Test
@SmallTest
public void testSetAlwaysAllowMmsData() throws Exception {
- mDataEnabledSettingsUT.setUserDataEnabled(false);
+ mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, false);
assertTrue(mDataEnabledSettingsUT.setAlwaysAllowMmsData(true));
ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
verify(mSubscriptionController).setDataEnabledOverrideRules(anyInt(),
@@ -120,7 +121,23 @@
assertEquals("", stringCaptor.getValue());
assertFalse(mDataEnabledSettingsUT.isDataEnabled(ApnSetting.TYPE_MMS));
- mDataEnabledSettingsUT.setUserDataEnabled(true);
+ mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, true);
assertTrue(mDataEnabledSettingsUT.isDataEnabled(ApnSetting.TYPE_MMS));
}
+
+ @Test
+ @SmallTest
+ public void testSetThermalDataEnabled() throws Exception {
+ mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
+ false);
+ assertFalse(mDataEnabledSettingsUT.isDataEnabledWithReason(
+ TelephonyManager.DATA_ENABLED_REASON_THERMAL));
+ assertFalse(mDataEnabledSettingsUT.isDataEnabled());
+
+ mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
+ true);
+ assertTrue(mDataEnabledSettingsUT.isDataEnabledWithReason(
+ TelephonyManager.DATA_ENABLED_REASON_THERMAL));
+ assertTrue(mDataEnabledSettingsUT.isDataEnabled());
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index 411738a..39b78db 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
@@ -34,6 +35,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
@@ -75,9 +77,13 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+import org.mockito.verification.VerificationMode;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
@RunWith(AndroidTestingRunner.class)
@@ -102,6 +108,11 @@
private ContentValues mInboundSmsTrackerCVSub1;
@Mock
private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
+ @Mock
+ private InboundSmsHandler.SmsFilter mSmsFilter;
+ @Mock
+ private InboundSmsHandler.SmsFilter mSmsFilter2;
+ private List<InboundSmsHandler.SmsFilter> mSmsFilters;
private GsmInboundSmsHandler mGsmInboundSmsHandler;
@@ -235,6 +246,10 @@
mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(mContext,
mSmsStorageMonitor, mPhone);
+ mSmsFilters = new ArrayList<>();
+ mSmsFilters.add(mSmsFilter);
+ mSmsFilters.add(mSmsFilter2);
+ mGsmInboundSmsHandler.setSmsFiltersForTesting(mSmsFilters);
monitorTestableLooper(new TestableLooper(mGsmInboundSmsHandler.getHandler().getLooper()));
processAllMessages();
}
@@ -341,6 +356,8 @@
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
+
+ verifySmsFiltersInvoked(times(1));
}
@Test
@@ -355,6 +372,67 @@
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
+
+ // verify no filter was invoked.
+ // TODO(b/136262737): Adjust test once blocked SMSes are passed through filters too.
+ verifySmsFiltersInvoked(never());
+ }
+
+ @Test
+ @MediumTest
+ public void testNewSms_filterInvoked_noBroadcastsSent() {
+ // Configure the first filter to drop the SMS.
+ when(mSmsFilter.filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()))
+ .thenAnswer((Answer<Boolean>) invocation -> {
+ mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE);
+ return true;
+ });
+
+ transitionFromStartupToIdle();
+
+ sendNewSms();
+
+ verify(mContext, never()).sendBroadcast(any(Intent.class));
+ assertEquals("IdleState", getCurrentState().getName());
+
+ // verify second filter was never invoked.
+ verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
+ }
+
+ @Test
+ @MediumTest
+ public void testNewSms_filterChaining_noBroadcastsSent() {
+ // Have the first filter indicate it matched without completing the flow.
+ when(mSmsFilter.filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any())).thenReturn(true);
+
+ transitionFromStartupToIdle();
+
+ sendNewSms();
+
+ verify(mContext, never()).sendBroadcast(any(Intent.class));
+ // Now waiting for the first filter to complete.
+ assertEquals("WaitingState", getCurrentState().getName());
+
+ // Verify the first filter was invoked with the right set of remaining filters.
+ verify(mSmsFilter).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), eq(Collections.singletonList(mSmsFilter2)));
+
+ // Verify second filter was never invoked.
+ verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
+
+ // Clean up by completing the broadcast, as an asynchronous filter must do.
+ mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE);
+ processAllMessages();
+ assertEquals("IdleState", getCurrentState().getName());
}
private void verifyDataSmsIntentBroadcasts(int numPastBroadcasts) {
@@ -401,6 +479,7 @@
processAllMessages();
verifySmsIntentBroadcasts(0, true /* allowBgActivityStarts */);
+ verifySmsFiltersInvoked(times(1));
}
@Test
@@ -438,6 +517,8 @@
processAllMessages();
verifyDataSmsIntentBroadcasts(1);
+
+ verifySmsFiltersInvoked(times(2));
}
@FlakyTest
@@ -459,6 +540,8 @@
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
+
+ verifySmsFiltersInvoked(times(1));
}
private void prepareMultiPartSms(boolean is3gpp2WapPush) {
@@ -538,6 +621,7 @@
// verify no broadcast sent.
verify(mContext, times(0)).sendBroadcast(any(Intent.class));
+ verifySmsFiltersInvoked(never());
// additional copy of part 1 of non-3gpp2wap
prepareMultiPartSms(false);
@@ -554,6 +638,8 @@
// verify there are three segments in the db and only one of them is not marked as deleted.
assertEquals(3, mContentProvider.getNumRows());
assertEquals(1, mContentProvider.query(sRawUri, null, "deleted=0", null, null).getCount());
+
+ verifySmsFiltersInvoked(times(1));
}
@FlakyTest
@@ -587,6 +673,7 @@
// verify broadcast intents
verifySmsIntentBroadcasts(0);
+ verifySmsFiltersInvoked(times(1));
// if an additional copy of one of the segments above is received, it should not be kept in
// the db and should not be combined with any subsequent messages received from the same
@@ -602,6 +689,7 @@
// verify no additional broadcasts sent
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
+ verifySmsFiltersInvoked(times(1));
// part 1 of new sms recieved from same sender with same parameters, just different
// timestamps, should not be combined with the additional part 2 received above
@@ -619,6 +707,7 @@
// verify no additional broadcasts sent
verify(mContext, times(2)).sendBroadcast(any(Intent.class));
+ verifySmsFiltersInvoked(times(1));
assertEquals("IdleState", getCurrentState().getName());
}
@@ -681,6 +770,7 @@
assertEquals(mMessageBodyPart2, c.getString(c.getColumnIndex("message_body")));
// State machine should go back to idle
assertEquals("IdleState", getCurrentState().getName());
+ verifySmsFiltersInvoked(never());
}
@Test
@@ -736,6 +826,7 @@
verify(mContext, never()).sendBroadcast(any(Intent.class));
// State machine should go back to idle
assertEquals("IdleState", getCurrentState().getName());
+ verifySmsFiltersInvoked(never());
}
@Test
@@ -770,6 +861,8 @@
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
+ // TODO(b/136262737): Adjust test once blocked SMSes are passed through filters too.
+ verifySmsFiltersInvoked(never());
}
@Test
@@ -820,6 +913,55 @@
verify(mContext, never()).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
+ // TODO(b/136262737): Adjust test once blocked SMSes are passed through filters too.
+ verifySmsFiltersInvoked(never());
+ }
+
+ @Test
+ @MediumTest
+ public void testMultipartSms_filterInvoked_noBroadcastsSent() {
+ // Configure the first filter to drop the SMS.
+ when(mSmsFilter.filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any()))
+ .thenAnswer((Answer<Boolean>) invocation -> {
+ mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_BROADCAST_COMPLETE);
+ return true;
+ });
+
+ transitionFromStartupToIdle();
+
+ // prepare SMS part 1 and part 2
+ prepareMultiPartSms(false);
+
+ mSmsHeader.concatRef = new SmsHeader.ConcatRef();
+ doReturn(mSmsHeader).when(mGsmSmsMessage).getUserDataHeader();
+
+ doReturn(mInboundSmsTrackerPart1).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(),
+ anyInt(), anyBoolean(),
+ nullable(String.class), nullable(String.class), anyInt(), anyInt(),
+ anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
+ sendNewSms();
+
+ // State machine should go back to idle and wait for second part
+ assertEquals("IdleState", getCurrentState().getName());
+
+ doReturn(mInboundSmsTrackerPart2).when(mTelephonyComponentFactory)
+ .makeInboundSmsTracker(any(Context.class), nullable(byte[].class), anyLong(),
+ anyInt(), anyBoolean(),
+ nullable(String.class), nullable(String.class), anyInt(), anyInt(),
+ anyInt(), anyBoolean(), nullable(String.class), anyBoolean(), anyInt());
+ sendNewSms();
+
+ // verify no broadcasts sent
+ verify(mContext, never()).sendBroadcast(any(Intent.class));
+ assertEquals("IdleState", getCurrentState().getName());
+
+ // verify second filter was never invoked.
+ verify(mSmsFilter2, never()).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
}
@Test
@@ -859,6 +1001,7 @@
processAllMessages();
verifyDataSmsIntentBroadcasts(1);
+ verifySmsFiltersInvoked(times(1));
}
@Test
@@ -879,6 +1022,7 @@
// user is unlocked; intent should be broadcast right away
verifyDataSmsIntentBroadcasts(0);
+ verifySmsFiltersInvoked(times(1));
}
@Test
@@ -917,7 +1061,7 @@
verify(mContext, times(1)).sendBroadcast(any(Intent.class));
assertEquals("IdleState", getCurrentState().getName());
-
+ verifySmsFiltersInvoked(never());
}
@FlakyTest
@@ -944,6 +1088,7 @@
processAllMessages();
verifySmsIntentBroadcasts(0);
+ verifySmsFiltersInvoked(times(1));
}
@Test
@@ -962,5 +1107,15 @@
verifySmsIntentBroadcasts(0, mSubId0, true);
verifySmsIntentBroadcasts(2, mSubId1, false);
+ verifySmsFiltersInvoked(times(2));
+ }
+
+ private void verifySmsFiltersInvoked(VerificationMode verificationMode) {
+ verify(mSmsFilter, verificationMode).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
+ verify(mSmsFilter2, verificationMode).filterSms(any(byte[][].class), anyInt(),
+ any(InboundSmsTracker.class), any(InboundSmsHandler.SmsBroadcastReceiver.class),
+ anyBoolean(), Mockito.<List<InboundSmsHandler.SmsFilter>>any());
}
}
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 c1d0bce..6c1cfad 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
@@ -560,14 +560,17 @@
@Test
@SmallTest
public void testWriteRilSendSms() throws Exception {
- mMetrics.writeRilSendSms(mPhone.getPhoneId(), 1, 2, 1);
- mMetrics.writeRilSendSms(mPhone.getPhoneId(), 4, 5, 2);
+ long fakeMessageId1 = 123123L;
+ long fakeMessageId2 = -987L;
- SmsResponse response = new SmsResponse(0, null, 123);
+ mMetrics.writeRilSendSms(mPhone.getPhoneId(), 1, 2, 1, fakeMessageId1);
+ mMetrics.writeRilSendSms(mPhone.getPhoneId(), 4, 5, 2, fakeMessageId2);
+
+ SmsResponse response = new SmsResponse(0, null, 123, fakeMessageId1);
mMetrics.writeOnRilSolicitedResponse(mPhone.getPhoneId(), 1, 0, RIL_REQUEST_SEND_SMS,
response);
- response = new SmsResponse(0, null, 456);
+ response = new SmsResponse(0, null, 456, fakeMessageId2);
mMetrics.writeOnRilSolicitedResponse(mPhone.getPhoneId(), 4, 0, RIL_REQUEST_SEND_SMS,
response);
TelephonyLog log = buildProto();
@@ -583,21 +586,25 @@
assertEquals(1, events[0].rilRequestId);
assertEquals(2, events[0].tech);
assertEquals(1, events[0].format);
+ assertEquals(fakeMessageId1, events[0].messageId);
assertEquals(SmsSession.Event.Type.SMS_SEND, events[1].type);
assertEquals(4, events[1].rilRequestId);
assertEquals(5, events[1].tech);
assertEquals(2, events[1].format);
+ assertEquals(fakeMessageId2, events[1].messageId);
assertEquals(SmsSession.Event.Type.SMS_SEND_RESULT, events[2].type);
assertEquals(1, events[2].rilRequestId);
assertEquals(1, events[2].error);
assertEquals(123, events[2].errorCode);
+ assertEquals(fakeMessageId1, events[2].messageId);
assertEquals(SmsSession.Event.Type.SMS_SEND_RESULT, events[3].type);
assertEquals(4, events[3].rilRequestId);
assertEquals(1, events[3].error);
assertEquals(456, events[3].errorCode);
+ assertEquals(fakeMessageId2, events[3].messageId);
}
// Test write phone state