Merge "Fixed that RAT_UNKNOWN incorretly reported in metrics data." into nyc-mr1-dev
diff --git a/src/java/android/telephony/SmsManager.java b/src/java/android/telephony/SmsManager.java
index 4df3b40..8063364 100644
--- a/src/java/android/telephony/SmsManager.java
+++ b/src/java/android/telephony/SmsManager.java
@@ -245,6 +245,14 @@
*/
public static final String MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER =
CarrierConfigManager.KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL;
+ /**
+ * If true, add "Connection: close" header to MMS HTTP requests so the connection
+ * is immediately closed (disabling keep-alive). (Boolean type)
+ * @hide
+ */
+ public static final String MMS_CONFIG_CLOSE_CONNECTION =
+ CarrierConfigManager.KEY_MMS_CLOSE_CONNECTION_BOOL;
+
/*
* Forwarded constants from SimDialogActivity.
*/
@@ -1618,6 +1626,8 @@
config.getBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED));
filtered.putBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED,
config.getBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED));
+ filtered.putBoolean(MMS_CONFIG_CLOSE_CONNECTION,
+ config.getBoolean(MMS_CONFIG_CLOSE_CONNECTION));
filtered.putInt(MMS_CONFIG_MAX_MESSAGE_SIZE, config.getInt(MMS_CONFIG_MAX_MESSAGE_SIZE));
filtered.putInt(MMS_CONFIG_MAX_IMAGE_WIDTH, config.getInt(MMS_CONFIG_MAX_IMAGE_WIDTH));
filtered.putInt(MMS_CONFIG_MAX_IMAGE_HEIGHT, config.getInt(MMS_CONFIG_MAX_IMAGE_HEIGHT));
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index 3ba791d..d4e53d7 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -98,6 +98,7 @@
public void onConferenceMergedFailed();
public void onExtrasChanged(Bundle extras);
public void onExitedEcmMode();
+ public void onCallPullFailed(Connection externalConnection);
}
/**
@@ -127,6 +128,8 @@
public void onExtrasChanged(Bundle extras) {}
@Override
public void onExitedEcmMode() {}
+ @Override
+ public void onCallPullFailed(Connection externalConnection) {}
}
public static final int AUDIO_QUALITY_STANDARD = 1;
@@ -194,6 +197,13 @@
*/
private boolean mIsPulledCall = false;
+ /**
+ * Where {@link #mIsPulledCall} is {@code true}, contains the dialog Id of the external call
+ * which is being pulled (e.g.
+ * {@link com.android.internal.telephony.imsphone.ImsExternalConnection#getCallId()}).
+ */
+ private int mPulledDialogId;
+
protected Connection(int phoneType) {
mPhoneType = phoneType;
}
@@ -828,6 +838,21 @@
}
/**
+ * For an external call which is being pulled (e.g. {@link #isPulledCall()} is {@code true}),
+ * sets the dialog Id for the external call. Used to handle failures to pull a call so that the
+ * pulled call can be reconciled with its original external connection.
+ *
+ * @param pulledDialogId The dialog id associated with a pulled call.
+ */
+ public void setPulledDialogId(int pulledDialogId) {
+ mPulledDialogId = pulledDialogId;
+ }
+
+ public int getPulledDialogId() {
+ return mPulledDialogId;
+ }
+
+ /**
* Sets the call substate for the current connection and reports the changes to all listeners.
* Valid call substates are defined in {@link android.telecom.Connection}.
*
@@ -900,6 +925,20 @@
}
/**
+ * Notifies the connection that a call to {@link #pullExternalCall()} has failed to pull the
+ * call to the local device.
+ *
+ * @param externalConnection The original
+ * {@link com.android.internal.telephony.imsphone.ImsExternalConnection} from which the
+ * pull was initiated.
+ */
+ public void onCallPullFailed(Connection externalConnection) {
+ for (Listener l : mListeners) {
+ l.onCallPullFailed(externalConnection);
+ }
+ }
+
+ /**
* Notifies this Connection of a request to disconnect a participant of the conference managed
* by the connection.
*
@@ -931,6 +970,8 @@
StringBuilder str = new StringBuilder(128);
str.append(" callId: " + getTelecomCallId());
+ str.append(" isExternal: " + (((mConnectionCapabilities & Capability.IS_EXTERNAL_CONNECTION)
+ == Capability.IS_EXTERNAL_CONNECTION) ? "Y" : "N"));
if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) {
str.append("addr: " + getAddress())
.append(" pres.: " + getNumberPresentation())
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 173f25e..1392302 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -185,6 +185,8 @@
private int mRilVersion;
private boolean mBroadcastEmergencyCallStateChanges = false;
+ // flag to indicate if emergency call end broadcast should be sent
+ boolean mSendEmergencyCallEnd = true;
// Constructors
@@ -637,11 +639,24 @@
@Override
public void sendEmergencyCallStateChange(boolean callActive) {
if (mBroadcastEmergencyCallStateChanges) {
- Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
- intent.putExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, callActive);
- SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId());
- ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
- if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallStateChange");
+ if (callActive &&
+ getServiceState().getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
+ // if emergency call is started while on iwlan, do not send the start or end
+ // broadcast
+ mSendEmergencyCallEnd = false;
+ if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallStateChange: not sending call start " +
+ "intent as voice tech is IWLAN");
+ } else if (callActive || mSendEmergencyCallEnd) {
+ Intent intent = new Intent(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED);
+ intent.putExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, callActive);
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, getPhoneId());
+ ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
+ if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallStateChange");
+ } else {
+ if (DBG) Rlog.d(LOG_TAG, "sendEmergencyCallStateChange: not sending call end " +
+ "intent as start was not sent");
+ mSendEmergencyCallEnd = true;
+ }
}
}
@@ -1356,6 +1371,12 @@
if (isPhoneTypeGsm()) {
return mImei;
} else {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ boolean force_imei = configManager.getConfigForSubId(getSubId())
+ .getBoolean(CarrierConfigManager.KEY_FORCE_IMEI_BOOL);
+ if (force_imei) return mImei;
+
String id = getMeid();
if ((id == null) || id.matches("^0*$")) {
loge("getDeviceId(): MEID is not initialized use ESN");
@@ -2063,7 +2084,8 @@
if (b != null) {
boolean broadcastEmergencyCallStateChanges = b.getBoolean(
CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL);
- logd("broadcastEmergencyCallStateChanges =" + broadcastEmergencyCallStateChanges);
+ logd("broadcastEmergencyCallStateChanges = " +
+ broadcastEmergencyCallStateChanges);
setBroadcastEmergencyCallStateChanges(broadcastEmergencyCallStateChanges);
} else {
loge("didn't get broadcastEmergencyCallStateChanges from carrier config");
@@ -2673,10 +2695,10 @@
}
// if phone is not in Ecm mode, and it's changed to Ecm mode
if (mIsPhoneInEcmState == false) {
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
mIsPhoneInEcmState = true;
// notify change
sendEmergencyCallbackModeChange();
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
// Post this runnable so we will automatically exit
// if no one invokes exitEmergencyCallbackMode() directly.
@@ -2703,15 +2725,16 @@
}
// if exiting ecm success
if (ar.exception == null) {
+ if (mIsPhoneInEcmState) {
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ mIsPhoneInEcmState = false;
+ }
+
// release wakeLock
if (mWakeLock.isHeld()) {
mWakeLock.release();
}
- if (mIsPhoneInEcmState) {
- mIsPhoneInEcmState = false;
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- }
// send an Intent
sendEmergencyCallbackModeChange();
// Re-initiate data connection
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index b307a54..2a35370 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -22,7 +22,6 @@
import android.os.Looper;
import android.os.Message;
import android.telephony.Rlog;
-import android.util.Log;
import com.android.internal.telephony.uicc.AdnRecord;
import com.android.internal.telephony.uicc.AdnRecordCache;
@@ -42,7 +41,6 @@
public class IccPhoneBookInterfaceManager {
static final String LOG_TAG = "IccPhoneBookIM";
protected static final boolean DBG = true;
- protected static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
protected Phone mPhone;
private UiccCardApplication mCurrentApp = null;
@@ -174,9 +172,9 @@
if (DBG) logd("updateAdnRecordsInEfBySearch: efid=0x" +
- Integer.toHexString(efid).toUpperCase() + (VDBG ? " ("+ oldTag + "," +
- oldPhoneNumber + ")" + "==>" + " ("+ newTag + ","
- + newPhoneNumber + ")"+ " pin2=" + pin2 : ""));
+ Integer.toHexString(efid).toUpperCase() + " ("+ Rlog.pii(LOG_TAG, oldTag) + "," +
+ Rlog.pii(LOG_TAG, oldPhoneNumber) + ")" + "==>" + " ("+ Rlog.pii(LOG_TAG, newTag) +
+ "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")"+ " pin2=" + Rlog.pii(LOG_TAG, pin2));
efid = updateEfForIccType(efid);
@@ -226,8 +224,9 @@
}
if (DBG) logd("updateAdnRecordsInEfByIndex: efid=0x" +
- Integer.toHexString(efid).toUpperCase() + " Index=" + index +
- (VDBG ? " ==> " + "(" + newTag + "," + newPhoneNumber + ")" + " pin2=" + pin2 : ""));
+ Integer.toHexString(efid).toUpperCase() + " Index=" + index + " ==> " + "(" +
+ Rlog.pii(LOG_TAG, newTag) + "," + Rlog.pii(LOG_TAG, newPhoneNumber) + ")" +
+ " pin2=" + Rlog.pii(LOG_TAG, pin2));
synchronized(mLock) {
checkThread();
mSuccess = false;
diff --git a/src/java/com/android/internal/telephony/IccProvider.java b/src/java/com/android/internal/telephony/IccProvider.java
index 6d07698..222e1d6 100755
--- a/src/java/com/android/internal/telephony/IccProvider.java
+++ b/src/java/com/android/internal/telephony/IccProvider.java
@@ -29,7 +29,6 @@
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.telephony.Rlog;
-import android.util.Log;
import java.util.List;
@@ -43,7 +42,6 @@
public class IccProvider extends ContentProvider {
private static final String TAG = "IccProvider";
private static final boolean DBG = true;
- private static final boolean VDBG = Rlog.isLoggable(TAG, Log.VERBOSE);
private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] {
@@ -429,8 +427,8 @@
addIccRecordToEf(int efType, String name, String number, String[] emails,
String pin2, int subId) {
if (DBG) log("addIccRecordToEf: efType=0x" + Integer.toHexString(efType).toUpperCase() +
- (VDBG ? ", name=" + name + ", number=" + number + ", emails=" + emails : "") +
- ", subscription=" + subId);
+ ", name=" + Rlog.pii(TAG, name) + ", number=" + Rlog.pii(TAG, number) +
+ ", emails=" + Rlog.pii(TAG, emails) + ", subscription=" + subId);
boolean success = false;
@@ -459,8 +457,9 @@
updateIccRecordInEf(int efType, String oldName, String oldNumber,
String newName, String newNumber, String pin2, int subId) {
if (DBG) log("updateIccRecordInEf: efType=0x" + Integer.toHexString(efType).toUpperCase() +
- (VDBG ? ", oldname=" + oldName + ", oldnumber=" + oldNumber + ", newname=" +
- newName + ", newnumber=" + newName : "") + ", subscription=" + subId);
+ ", oldname=" + Rlog.pii(TAG, oldName) + ", oldnumber=" + Rlog.pii(TAG, oldNumber) +
+ ", newname=" + Rlog.pii(TAG, newName) + ", newnumber=" + Rlog.pii(TAG, newName) +
+ ", subscription=" + subId);
boolean success = false;
@@ -484,8 +483,9 @@
private boolean deleteIccRecordFromEf(int efType, String name, String number, String[] emails,
String pin2, int subId) {
if (DBG) log("deleteIccRecordFromEf: efType=0x" +
- Integer.toHexString(efType).toUpperCase() + (VDBG ? ", name=" + name + ", number=" +
- number + ", emails=" + emails + ", pin2=" + pin2 : "") + ", subscription=" + subId);
+ Integer.toHexString(efType).toUpperCase() + ", name=" + Rlog.pii(TAG, name) +
+ ", number=" + Rlog.pii(TAG, number) + ", emails=" + Rlog.pii(TAG, emails) +
+ ", pin2=" + Rlog.pii(TAG, pin2) + ", subscription=" + subId);
boolean success = false;
@@ -517,7 +517,7 @@
String alphaTag = record.getAlphaTag();
String number = record.getNumber();
- if (DBG) log("loadRecord: " + alphaTag + (VDBG ? ", " + number : ""));
+ if (DBG) log("loadRecord: " + alphaTag + ", " + Rlog.pii(TAG, number));
contact[0] = alphaTag;
contact[1] = number;
@@ -525,7 +525,7 @@
if (emails != null) {
StringBuilder emailString = new StringBuilder();
for (String email: emails) {
- if (VDBG) log("Adding email:" + email);
+ log("Adding email:" + Rlog.pii(TAG, email));
emailString.append(email);
emailString.append(",");
}
diff --git a/src/java/com/android/internal/telephony/MccTable.java b/src/java/com/android/internal/telephony/MccTable.java
index 2a531c4..1797e65 100644
--- a/src/java/com/android/internal/telephony/MccTable.java
+++ b/src/java/com/android/internal/telephony/MccTable.java
@@ -124,10 +124,17 @@
return null;
}
+ final String country = entry.mIso;
+
+ // Choose English as the default language for India.
+ if ("in".equals(country)) {
+ return "en";
+ }
+
// Ask CLDR for the language this country uses...
- Locale likelyLocale = ICU.addLikelySubtags(new Locale("und", entry.mIso));
+ Locale likelyLocale = ICU.addLikelySubtags(new Locale("und", country));
String likelyLanguage = likelyLocale.getLanguage();
- Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): country " + entry.mIso + " uses " +
+ Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): country " + country + " uses " +
likelyLanguage);
return likelyLanguage;
}
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index bbecd9c..c01be85 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -23,6 +23,7 @@
import android.content.SharedPreferences;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
+import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Build;
@@ -3321,6 +3322,15 @@
mDcTracker.setPolicyDataEnabled(enabled);
}
+ /**
+ * SIP URIs aliased to the current subscriber given by the IMS implementation.
+ * Applicable only on IMS; used in absence of line1number.
+ * @return array of SIP URIs aliased to the current subscriber
+ */
+ public Uri[] getCurrentSubscriberUris() {
+ return null;
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Phone: subId=" + getSubId());
pw.println(" mPhoneId=" + mPhoneId);
diff --git a/src/java/com/android/internal/telephony/RatRatcheter.java b/src/java/com/android/internal/telephony/RatRatcheter.java
index b782bc8..d582af0 100644
--- a/src/java/com/android/internal/telephony/RatRatcheter.java
+++ b/src/java/com/android/internal/telephony/RatRatcheter.java
@@ -22,6 +22,7 @@
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
import android.telephony.Rlog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -74,6 +75,19 @@
}
}
+ public void ratchetRat(ServiceState oldSS, ServiceState newSS) {
+ int newVoiceRat = ratchetRat(oldSS.getRilVoiceRadioTechnology(),
+ newSS.getRilVoiceRadioTechnology());
+ int newDataRat = ratchetRat(oldSS.getRilDataRadioTechnology(),
+ newSS.getRilDataRadioTechnology());
+ boolean newUsingCA = oldSS.isUsingCarrierAggregation() ||
+ newSS.isUsingCarrierAggregation();
+
+ newSS.setRilVoiceRadioTechnology(newVoiceRat);
+ newSS.setRilDataRadioTechnology(newDataRat);
+ newSS.setIsUsingCarrierAggregation(newUsingCA);
+ }
+
private BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 54edc37..a919af2 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -952,7 +952,8 @@
}
// This will do nothing in the 'radio not available' case
setPowerStateToDesired();
- pollState();
+ // These events are modem triggered, so pollState() needs to be forced
+ modemTriggeredPollState();
break;
case EVENT_NETWORK_STATE_CHANGED:
@@ -2548,10 +2549,7 @@
// ratchet the new tech up through it's rat family but don't drop back down
// until cell change
if (hasLocationChanged == false) {
- mNewSS.setRilVoiceRadioTechnology(mRatRatcheter.ratchetRat(
- mSS.getRilVoiceRadioTechnology(), mNewSS.getRilVoiceRadioTechnology()));
- mNewSS.setRilDataRadioTechnology(mRatRatcheter.ratchetRat(
- mSS.getRilDataRadioTechnology(), mNewSS.getRilDataRadioTechnology()));
+ mRatRatcheter.ratchetRat(mSS, mNewSS);
}
boolean hasRilVoiceRadioTechnologyChanged =
@@ -2794,6 +2792,14 @@
boolean hasCdmaDataConnectionChanged =
mSS.getDataRegState() != mNewSS.getDataRegState();
+ boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
+
+ // ratchet the new tech up through it's rat family but don't drop back down
+ // until cell change
+ if (hasLocationChanged == false) {
+ mRatRatcheter.ratchetRat(mSS, mNewSS);
+ }
+
boolean hasRilVoiceRadioTechnologyChanged =
mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology();
@@ -2810,8 +2816,6 @@
boolean hasDataRoamingOff = mSS.getDataRoaming() && !mNewSS.getDataRoaming();
- boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
-
TelephonyManager tm =
(TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
@@ -2989,6 +2993,14 @@
boolean hasCdmaDataConnectionChanged =
mSS.getDataRegState() != mNewSS.getDataRegState();
+ boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
+
+ // ratchet the new tech up through it's rat family but don't drop back down
+ // until cell change
+ if (hasLocationChanged == false) {
+ mRatRatcheter.ratchetRat(mSS, mNewSS);
+ }
+
boolean hasVoiceRadioTechnologyChanged = mSS.getRilVoiceRadioTechnology()
!= mNewSS.getRilVoiceRadioTechnology();
@@ -3005,8 +3017,6 @@
boolean hasDataRoamingOff = mSS.getDataRoaming() && !mNewSS.getDataRoaming();
- boolean hasLocationChanged = !mNewCellLoc.equals(mCellLoc);
-
boolean has4gHandoff =
mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE &&
((ServiceState.isLte(mSS.getRilDataRadioTechnology()) &&
diff --git a/src/java/com/android/internal/telephony/SmsApplication.java b/src/java/com/android/internal/telephony/SmsApplication.java
index 675d943..bf90350 100644
--- a/src/java/com/android/internal/telephony/SmsApplication.java
+++ b/src/java/com/android/internal/telephony/SmsApplication.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -74,7 +75,7 @@
/**
* Name of this SMS app for display.
*/
- public String mApplicationName;
+ private String mApplicationName;
/**
* Package name for this SMS app.
@@ -125,16 +126,32 @@
&& mRespondViaMessageClass != null && mSendToClass != null);
}
- public SmsApplicationData(String applicationName, String packageName, int uid) {
- mApplicationName = applicationName;
+ public SmsApplicationData(String packageName, int uid) {
mPackageName = packageName;
mUid = uid;
}
+ public String getApplicationName(Context context) {
+ if (mApplicationName == null) {
+ PackageManager pm = context.getPackageManager();
+ ApplicationInfo appInfo;
+ try {
+ appInfo = pm.getApplicationInfoAsUser(mPackageName, 0,
+ UserHandle.getUserId(mUid));
+ } catch (NameNotFoundException e) {
+ return null;
+ }
+ if (appInfo != null) {
+ CharSequence label = pm.getApplicationLabel(appInfo);
+ mApplicationName = (label == null) ? null : label.toString();
+ }
+ }
+ return mApplicationName;
+ }
+
@Override
public String toString() {
- return "mApplicationName: " + mApplicationName +
- " mPackageName: " + mPackageName +
+ return " mPackageName: " + mPackageName +
" mSmsReceiverClass: " + mSmsReceiverClass +
" mMmsReceiverClass: " + mMmsReceiverClass +
" mRespondViaMessageClass: " + mRespondViaMessageClass +
@@ -217,9 +234,8 @@
}
final String packageName = activityInfo.packageName;
if (!receivers.containsKey(packageName)) {
- final String applicationName = resolveInfo.loadLabel(packageManager).toString();
- final SmsApplicationData smsApplicationData = new SmsApplicationData(
- applicationName, packageName, activityInfo.applicationInfo.uid);
+ final SmsApplicationData smsApplicationData = new SmsApplicationData(packageName,
+ activityInfo.applicationInfo.uid);
smsApplicationData.mSmsReceiverClass = activityInfo.name;
receivers.put(packageName, smsApplicationData);
}
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index ea6fce8..a9553f6 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -147,7 +147,8 @@
throws RemoteException {
mCurrentlyActiveUserId = newUserId;
CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
- mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId);
+ mPackageManager, TelephonyManager.getDefault(),
+ mContext.getContentResolver(), mCurrentlyActiveUserId);
if (reply != null) {
try {
@@ -172,7 +173,8 @@
logd("Couldn't get current user ID; guessing it's 0: " + e.getMessage());
}
CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
- mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId);
+ mPackageManager, TelephonyManager.getDefault(), mContext.getContentResolver(),
+ mCurrentlyActiveUserId);
}
private final BroadcastReceiver sReceiver = new BroadcastReceiver() {
@@ -488,7 +490,8 @@
// Update set of enabled carrier apps now that the privilege rules may have changed.
CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
- mPackageManager, TelephonyManager.getDefault(), mCurrentlyActiveUserId);
+ mPackageManager, TelephonyManager.getDefault(), mContext.getContentResolver(),
+ mCurrentlyActiveUserId);
broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null);
updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
diff --git a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
index 055d574..ce991db 100644
--- a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
+++ b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
@@ -15,19 +15,18 @@
*/
package com.android.internal.telephony;
-import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
-import android.os.Bundle;
import android.provider.VoicemailContract;
+import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.telephony.VisualVoicemailSmsFilterSettings;
import android.util.Log;
-import android.telephony.SmsMessage;
-
import com.android.internal.telephony.VisualVoicemailSmsParser.WrappedMessageData;
+import java.nio.charset.StandardCharsets;
+
public class VisualVoicemailSmsFilter {
private static final String TAG = "VvmSmsFilter";
@@ -61,35 +60,50 @@
// TODO: filter base on originating number and destination port.
String messageBody = getFullMessage(pdus, format);
+
if(messageBody == null){
+ // Verizon WAP push SMS is not recognized by android, which has a ascii PDU.
+ // Attempt to parse it.
+ Log.i(TAG, "Unparsable SMS received");
+ String asciiMessage = parseAsciiPduMessage(pdus);
+ WrappedMessageData messageData = VisualVoicemailSmsParser
+ .parseAlternativeFormat(asciiMessage);
+ if (messageData != null) {
+ sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData);
+ }
+ // Confidence for what the message actually is is low. Don't remove the message and let
+ // system decide. Usually because it is not parsable it will be dropped.
return false;
+ } else {
+ String clientPrefix = settings.clientPrefix;
+ WrappedMessageData messageData = VisualVoicemailSmsParser
+ .parse(clientPrefix, messageBody);
+ if (messageData != null) {
+ sendVvmSmsBroadcast(context, vvmClientPackage, subId, messageData);
+ return true;
+ }
}
- String clientPrefix = settings.clientPrefix;
-
- WrappedMessageData messageData = VisualVoicemailSmsParser.parse(clientPrefix, messageBody);
- if (messageData != null) {
- Log.i(TAG, "VVM SMS received");
- Intent intent = new Intent(VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED);
- intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_PREFIX, messageData.prefix);
- intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS, messageData.fields);
- intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID, subId);
- intent.setPackage(vvmClientPackage);
- context.sendBroadcast(intent);
- return true;
- }
-
return false;
}
+ private static void sendVvmSmsBroadcast(Context context, String vvmClientPackage, int subId,
+ WrappedMessageData messageData) {
+ Log.i(TAG, "VVM SMS received");
+ Intent intent = new Intent(VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED);
+ intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_PREFIX, messageData.prefix);
+ intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_FIELDS, messageData.fields);
+ intent.putExtra(VoicemailContract.EXTRA_VOICEMAIL_SMS_SUBID, subId);
+ intent.setPackage(vvmClientPackage);
+ context.sendBroadcast(intent);
+ }
+
private static String getFullMessage(byte[][] pdus, String format) {
StringBuilder builder = new StringBuilder();
for (byte pdu[] : pdus) {
SmsMessage message =SmsMessage.createFromPdu(pdu, format);
- if(message == null || message.mWrappedSmsMessage == null) {
- // b/29123941 Certain PDU will cause createFromPdu() to return a SmsMessage with
- // null mWrappedSmsMessage, throwing NPE on any method called. In this case, just
- // ignore the message.
+ if (message == null) {
+ // The PDU is not recognized by android
return null;
}
String body = message.getMessageBody();
@@ -99,4 +113,12 @@
}
return builder.toString();
}
+
+ private static String parseAsciiPduMessage(byte[][] pdus) {
+ StringBuilder builder = new StringBuilder();
+ for (byte pdu[] : pdus) {
+ builder.append(new String(pdu, StandardCharsets.US_ASCII));
+ }
+ return builder.toString();
+ }
}
diff --git a/src/java/com/android/internal/telephony/VisualVoicemailSmsParser.java b/src/java/com/android/internal/telephony/VisualVoicemailSmsParser.java
index 0de37d5..b6b3202 100644
--- a/src/java/com/android/internal/telephony/VisualVoicemailSmsParser.java
+++ b/src/java/com/android/internal/telephony/VisualVoicemailSmsParser.java
@@ -20,6 +20,10 @@
public class VisualVoicemailSmsParser {
+ private static final String[] ALLOWED_ALTERNATIVE_FORMAT_EVENT = new String[] {
+ "MBOXUPDATE", "UNRECOGNIZED"
+ };
+
/**
* Class wrapping the raw OMTP message data, internally represented as as map of all key-value
* pairs found in the SMS body. <p> All the methods return null if either the field was not
@@ -80,6 +84,7 @@
* @param message The sms string with the prefix removed.
* @return A WrappedMessageData object containing the map.
*/
+ @Nullable
private static Bundle parseSmsBody(String message) {
// TODO: ensure fail if format does not match
Bundle keyValues = new Bundle();
@@ -107,4 +112,42 @@
return keyValues;
}
+
+ /**
+ * The alternative format is [Event]?([key]=[value])*, for example
+ *
+ * <p>"MBOXUPDATE?m=1;server=example.com;port=143;name=foo@example.com;pw=foo".
+ *
+ * <p>This format is not protected with a client prefix and should be handled with care. For
+ * safety, the event type must be one of {@link #ALLOWED_ALTERNATIVE_FORMAT_EVENT}
+ */
+ @Nullable
+ public static WrappedMessageData parseAlternativeFormat(String smsBody) {
+ try {
+ int eventTypeEnd = smsBody.indexOf("?");
+ if (eventTypeEnd == -1) {
+ return null;
+ }
+ String eventType = smsBody.substring(0, eventTypeEnd);
+ if (!isAllowedAlternativeFormatEvent(eventType)) {
+ return null;
+ }
+ Bundle fields = parseSmsBody(smsBody.substring(eventTypeEnd + 1));
+ if (fields == null) {
+ return null;
+ }
+ return new WrappedMessageData(eventType, fields);
+ } catch (IndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
+ private static boolean isAllowedAlternativeFormatEvent(String eventType) {
+ for (String event : ALLOWED_ALTERNATIVE_FORMAT_EVENT) {
+ if (event.equals(eventType)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/src/java/com/android/internal/telephony/cdma/sms/BearerData.java b/src/java/com/android/internal/telephony/cdma/sms/BearerData.java
index 89c1522..1de72db 100644
--- a/src/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/src/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -22,7 +22,6 @@
import android.telephony.cdma.CdmaSmsCbProgramResults;
import android.text.format.Time;
import android.telephony.Rlog;
-import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
@@ -436,8 +435,7 @@
builder.append(", readAckReq=" + readAckReq);
builder.append(", reportReq=" + reportReq);
builder.append(", numberOfMessages=" + numberOfMessages);
- builder.append(", callbackNumber=" +
- (Rlog.isLoggable(LOG_TAG, Log.DEBUG) ? callbackNumber : "XXX"));
+ builder.append(", callbackNumber=" + Rlog.pii(LOG_TAG, callbackNumber));
builder.append(", depositIndex=" + depositIndex);
builder.append(", hasUserDataHeader=" + hasUserDataHeader);
builder.append(", userData=" + userData);
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index 12c3945..7865bc4 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -450,9 +450,14 @@
}
}
- public boolean hasNoRestrictedRequests() {
+ public boolean hasNoRestrictedRequests(boolean excludeDun) {
synchronized (mRefCountLock) {
for (NetworkRequest nr : mNetworkRequests) {
+ if (excludeDun &&
+ nr.networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_DUN)) {
+ continue;
+ }
if (nr.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) == false) {
return false;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index c1319a4..0919af1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -760,6 +760,11 @@
private void updateTcpBufferSizes(int rilRat) {
String sizes = null;
+ if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) {
+ // for now treat CA as LTE. Plan to surface the extra bandwith in a more
+ // precise manner which should affect buffer sizes
+ rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+ }
String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT);
// ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex)
// - patch it up:
@@ -860,7 +865,7 @@
// first, if we have no restricted requests, this override can stay FALSE:
boolean noRestrictedRequests = true;
for (ApnContext apnContext : mApnContexts.keySet()) {
- noRestrictedRequests &= apnContext.hasNoRestrictedRequests();
+ noRestrictedRequests &= apnContext.hasNoRestrictedRequests(true /* exclude DUN */);
}
if (noRestrictedRequests) {
return;
@@ -948,6 +953,8 @@
}
if (mRestrictedNetworkOverride) {
result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ // don't use dun on restriction-overriden networks.
+ result.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
}
int up = 14;
@@ -2055,7 +2062,8 @@
+ " mLastFailCause=" + mLastFailCause
+ " mTag=" + mTag
+ " mLinkProperties=" + mLinkProperties
- + " linkCapabilities=" + makeNetworkCapabilities();
+ + " linkCapabilities=" + makeNetworkCapabilities()
+ + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride;
}
@Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 25b82ef..11e8cc1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -1514,10 +1514,12 @@
// request for the network.
// TODO - may want restricted requests to only apply to carrier-limited data access
// rather than applying to user limited as well.
+ // Exclude DUN for the purposes of the override until we get finer grained
+ // intention in NetworkRequests
boolean checkUserDataEnabled =
ApnSetting.isMeteredApnType(apnContext.getApnType(), mPhone.getContext(),
mPhone.getSubId(), mPhone.getServiceState().getDataRoaming()) &&
- apnContext.hasNoRestrictedRequests();
+ apnContext.hasNoRestrictedRequests(true /*exclude DUN */);
DataAllowFailReason failureReason = new DataAllowFailReason();
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
index a1a73e4..4bea73d 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
@@ -88,7 +88,8 @@
Log.e(TAG, "onPullExternalCall : No call puller defined");
return;
}
- mCallPuller.pullExternalCall(connection.getAddress(), connection.getVideoState());
+ mCallPuller.pullExternalCall(connection.getAddress(), connection.getVideoState(),
+ connection.getCallId());
}
}
@@ -324,7 +325,7 @@
// Add to list of tracked connections.
mExternalConnections.put(connection.getCallId(), connection);
- mExternalCallPullableState.put(connection.getCallId(), isCallPullPermitted);
+ mExternalCallPullableState.put(connection.getCallId(), state.isCallPullable());
// Note: The notification of unknown connection is ultimately handled by
// PstnIncomingCallNotifier#addNewUnknownCall. That method will ensure that an extra is set
@@ -365,9 +366,11 @@
connection.setVideoState(newVideoState);
}
+ mExternalCallPullableState.put(state.getCallId(), state.isCallPullable());
boolean isCallPullPermitted = isCallPullPermitted(state.isCallPullable(), newVideoState);
Log.d(TAG,
- "updateExistingConnection - pullable state : externalCallId = " + connection.getCallId()
+ "updateExistingConnection - pullable state : externalCallId = " + connection
+ .getCallId()
+ " ; isPullable = " + isCallPullPermitted
+ " ; networkPullable = " + state.isCallPullable()
+ " ; isVideo = "
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 030643f..0cfe257 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -24,6 +24,7 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
@@ -156,6 +157,17 @@
}
};
+ private Uri[] mCurrentSubscriberUris;
+
+ protected void setCurrentSubscriberUris(Uri[] currentSubscriberUris) {
+ this.mCurrentSubscriberUris = currentSubscriberUris;
+ }
+
+ @Override
+ public Uri[] getCurrentSubscriberUris() {
+ return mCurrentSubscriberUris;
+ }
+
// Create Cf (Call forward) so that dialling number &
// mIsCfu (true if reason is call forward unconditional)
// mOnComplete (Message object passed by client) can be packed &
@@ -1293,10 +1305,10 @@
}
// if phone is not in Ecm mode, and it's changed to Ecm mode
if (mIsPhoneInEcmState == false) {
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
mIsPhoneInEcmState = true;
// notify change
sendEmergencyCallbackModeChange();
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
// Post this runnable so we will automatically exit
// if no one invokes exitEmergencyCallbackMode() directly.
@@ -1313,6 +1325,12 @@
Rlog.d(LOG_TAG, "handleExitEmergencyCallbackMode: mIsPhoneInEcmState = "
+ mIsPhoneInEcmState);
}
+
+ if (mIsPhoneInEcmState) {
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
+ mIsPhoneInEcmState = false;
+ }
+
// Remove pending exit Ecm runnable, if any
removeCallbacks(mExitEcmRunnable);
@@ -1325,10 +1343,6 @@
mWakeLock.release();
}
- if (mIsPhoneInEcmState) {
- mIsPhoneInEcmState = false;
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
- }
// send an Intent
sendEmergencyCallbackModeChange();
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 897b374..d3de950 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -30,6 +30,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
@@ -195,9 +196,15 @@
private static final int EVENT_EXIT_ECBM_BEFORE_PENDINGMO = 21;
private static final int EVENT_VT_DATA_USAGE_UPDATE = 22;
private static final int EVENT_DATA_ENABLED_CHANGED = 23;
+ private static final int EVENT_GET_IMS_SERVICE = 24;
private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
+ // The number of times we will try to connect to the ImsService before giving up.
+ private static final int NUM_IMS_SERVICE_RETRIES = 10;
+ // The number of milliseconds in between each try.
+ private static final int TIME_BETWEEN_IMS_SERVICE_RETRIES_MS = 400; // ms
+
//***** Instance Variables
private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>();
private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
@@ -230,6 +237,7 @@
private PhoneConstants.State mState = PhoneConstants.State.IDLE;
+ private int mImsServiceRetryCount;
private ImsManager mImsManager;
private int mServiceId = -1;
@@ -297,12 +305,10 @@
mPhone.getDefaultPhone().registerForDataEnabledChanged(
this, EVENT_DATA_ENABLED_CHANGED, null);
- Thread t = new Thread() {
- public void run() {
- getImsService();
- }
- };
- t.start();
+ mImsServiceRetryCount = 0;
+ // Send a message to connect to the Ims Service and open a connection through
+ // getImsService().
+ sendEmptyMessage(EVENT_GET_IMS_SERVICE);
}
private PendingIntent createIncomingCallPendingIntent() {
@@ -312,37 +318,31 @@
PendingIntent.FLAG_UPDATE_CURRENT);
}
- private void getImsService() {
+ private void getImsService() throws ImsException {
if (DBG) log("getImsService");
mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
- try {
- mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
- createIncomingCallPendingIntent(),
- mImsConnectionStateListener);
+ mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
+ createIncomingCallPendingIntent(),
+ mImsConnectionStateListener);
- mImsManager.setImsConfigListener(mImsConfigListener);
+ mImsManager.setImsConfigListener(mImsConfigListener);
- // Get the ECBM interface and set IMSPhone's listener object for notifications
- getEcbmInterface().setEcbmStateListener(mPhone.getImsEcbmStateListener());
- if (mPhone.isInEcm()) {
- // Call exit ECBM which will invoke onECBMExited
- mPhone.exitEmergencyCallbackMode();
- }
- int mPreferredTtyMode = Settings.Secure.getInt(
- mPhone.getContext().getContentResolver(),
- Settings.Secure.PREFERRED_TTY_MODE,
- Phone.TTY_MODE_OFF);
- mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, mPreferredTtyMode, null);
+ // Get the ECBM interface and set IMSPhone's listener object for notifications
+ getEcbmInterface().setEcbmStateListener(mPhone.getImsEcbmStateListener());
+ if (mPhone.isInEcm()) {
+ // Call exit ECBM which will invoke onECBMExited
+ mPhone.exitEmergencyCallbackMode();
+ }
+ int mPreferredTtyMode = Settings.Secure.getInt(
+ mPhone.getContext().getContentResolver(),
+ Settings.Secure.PREFERRED_TTY_MODE,
+ Phone.TTY_MODE_OFF);
+ mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, mPreferredTtyMode, null);
- ImsMultiEndpoint multiEndpoint = getMultiEndpointInterface();
- if (multiEndpoint != null) {
- multiEndpoint.setExternalCallStateListener(
- mPhone.getExternalCallTracker().getExternalCallStateListener());
- }
- } catch (ImsException e) {
- loge("getImsService: " + e);
- //Leave mImsManager as null, then CallStateException will be thrown when dialing
- mImsManager = null;
+ ImsMultiEndpoint multiEndpoint = getMultiEndpointInterface();
+ if (multiEndpoint != null) {
+ multiEndpoint.setExternalCallStateListener(
+ mPhone.getExternalCallTracker().getExternalCallStateListener());
}
}
@@ -356,6 +356,7 @@
clearDisconnected();
mPhone.getContext().unregisterReceiver(mReceiver);
mPhone.unregisterForDataEnabledChanged(this);
+ removeMessages(EVENT_GET_IMS_SERVICE);
}
@Override
@@ -609,7 +610,10 @@
if (intentExtras.containsKey(ImsCallProfile.EXTRA_IS_CALL_PULL)) {
profile.mCallExtras.putBoolean(ImsCallProfile.EXTRA_IS_CALL_PULL,
intentExtras.getBoolean(ImsCallProfile.EXTRA_IS_CALL_PULL));
+ int dialogId = intentExtras.getInt(
+ ImsExternalCallTracker.EXTRA_IMS_EXTERNAL_CALL_ID);
conn.setIsPulledCall(true);
+ conn.setPulledDialogId(dialogId);
}
// Pack the OEM-specific call extras.
@@ -1448,6 +1452,15 @@
ImsPhoneConnection conn = findConnection(imsCall);
if (DBG) log("cause = " + cause + " conn = " + conn);
+ if (conn != null) {
+ android.telecom.Connection.VideoProvider videoProvider = conn.getVideoProvider();
+ if (videoProvider instanceof ImsVideoCallProviderWrapper) {
+ ImsVideoCallProviderWrapper wrapper = (ImsVideoCallProviderWrapper)
+ videoProvider;
+
+ wrapper.removeImsVideoProviderCallback(conn);
+ }
+ }
if (mOnHoldToneId == System.identityHashCode(conn)) {
if (conn != null && mOnHoldToneStarted) {
mPhone.stopOnHoldTone(conn);
@@ -1455,17 +1468,33 @@
mOnHoldToneStarted = false;
mOnHoldToneId = -1;
}
- if (conn != null && conn.isIncoming() && conn.getConnectTime() == 0
- && cause != DisconnectCause.ANSWERED_ELSEWHERE) {
- // Missed
- if (cause == DisconnectCause.NORMAL) {
- cause = DisconnectCause.INCOMING_MISSED;
- } else {
- cause = DisconnectCause.INCOMING_REJECTED;
- }
- if (DBG) log("Incoming connection of 0 connect time detected - translated cause = "
- + cause);
+ if (conn != null) {
+ if (conn.isPulledCall() && (
+ reasonInfo.getCode() == ImsReasonInfo.CODE_CALL_PULL_OUT_OF_SYNC ||
+ reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_TEMPRARILY_UNAVAILABLE) &&
+ mPhone != null && mPhone.getExternalCallTracker() != null) {
+ log("Call pull failed.");
+ // Call was being pulled, but the call pull has failed -- inform the associated
+ // TelephonyConnection that the pull failed, and provide it with the original
+ // external connection which was pulled so that it can be swapped back.
+ conn.onCallPullFailed(mPhone.getExternalCallTracker()
+ .getConnectionById(conn.getPulledDialogId()));
+ // Do not mark as disconnected; the call will just change from being a regular
+ // call to being an external call again.
+ cause = DisconnectCause.NOT_DISCONNECTED;
+
+ } else if (conn.isIncoming() && conn.getConnectTime() == 0
+ && cause != DisconnectCause.ANSWERED_ELSEWHERE) {
+ // Missed
+ if (cause == DisconnectCause.NORMAL) {
+ cause = DisconnectCause.INCOMING_MISSED;
+ } else {
+ cause = DisconnectCause.INCOMING_REJECTED;
+ }
+ if (DBG) log("Incoming connection of 0 connect time detected - translated " +
+ "cause = " + cause);
+ }
}
if (cause == DisconnectCause.NORMAL && conn != null && conn.getImsCall().isMerged()) {
@@ -2004,6 +2033,12 @@
if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
mPhone.mDefaultPhone.setVoiceMessageCount(count);
}
+
+ @Override
+ public void registrationAssociatedUriChanged(Uri[] uris) {
+ if (DBG) log("registrationAssociatedUriChanged");
+ mPhone.setCurrentSubscriberUris(uris);
+ }
};
private ImsConfigListener.Stub mImsConfigListener = new ImsConfigListener.Stub() {
@@ -2153,6 +2188,27 @@
onDataEnabledChanged(p.first, p.second);
}
break;
+ case EVENT_GET_IMS_SERVICE:
+ try {
+ getImsService();
+ } catch (ImsException e) {
+ loge("getImsService: " + e);
+ //Leave mImsManager as null, then CallStateException will be thrown when dialing
+ mImsManager = null;
+ if (mImsServiceRetryCount < NUM_IMS_SERVICE_RETRIES) {
+ loge("getImsService: Retrying getting ImsService...");
+ sendEmptyMessageDelayed(EVENT_GET_IMS_SERVICE,
+ TIME_BETWEEN_IMS_SERVICE_RETRIES_MS);
+ mImsServiceRetryCount++;
+ } else {
+ // We have been unable to connect for
+ // NUM_IMS_SERVICE_RETRIES*TIME_BETWEEN_IMS_SERVICE_RETRIES_MS ms. We will
+ // probably never be able to connect, so we should just give up.
+ loge("getImsService: ImsService retrieval timeout... ImsService is " +
+ "unavailable.");
+ }
+ }
+ break;
}
}
@@ -2299,6 +2355,7 @@
conn.setVideoProvider(imsVideoCallProviderWrapper);
imsVideoCallProviderWrapper.registerForDataUsageUpdate
(this, EVENT_VT_DATA_USAGE_UPDATE, imsCall);
+ imsVideoCallProviderWrapper.addImsVideoProviderCallback(conn);
}
}
@@ -2383,11 +2440,14 @@
*
* @param number The phone number of the call to be pulled.
* @param videoState The desired video state of the pulled call.
+ * @param dialogId The {@link ImsExternalConnection#getCallId()} dialog id associated with the
+ * call which is being pulled.
*/
@Override
- public void pullExternalCall(String number, int videoState) {
+ public void pullExternalCall(String number, int videoState, int dialogId) {
Bundle extras = new Bundle();
extras.putBoolean(ImsCallProfile.EXTRA_IS_CALL_PULL, true);
+ extras.putInt(ImsExternalCallTracker.EXTRA_IMS_EXTERNAL_CALL_ID, dialogId);
try {
Connection connection = dial(number, videoState, extras);
mPhone.notifyUnknownConnection(connection);
@@ -2423,9 +2483,15 @@
boolean isActiveCallVideo = activeCall.isVideoCall() ||
(mTreatDowngradedVideoCallsAsVideoCalls && activeCall.wasVideoCall());
boolean isActiveCallOnWifi = activeCall.isWifiCall();
+ boolean isVoWifiEnabled = mImsManager.isWfcEnabledByPlatform(mPhone.getContext()) &&
+ mImsManager.isWfcEnabledByUser(mPhone.getContext());
boolean isIncomingCallAudio = !incomingCall.isVideoCall();
- return isActiveCallVideo && isActiveCallOnWifi && isIncomingCallAudio;
+ log("shouldDisconnectActiveCallOnAnswer : isActiveCallVideo=" + isActiveCallVideo +
+ " isActiveCallOnWifi=" + isActiveCallOnWifi + " isIncomingCallAudio=" +
+ isIncomingCallAudio + " isVowifiEnabled=" + isVoWifiEnabled);
+
+ return isActiveCallVideo && isActiveCallOnWifi && isIncomingCallAudio && !isVoWifiEnabled;
}
/** Get aggregated video call data usage since boot.
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index d517bb1..7462daa 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -27,7 +27,7 @@
import android.os.PowerManager;
import android.os.Registrant;
import android.os.SystemClock;
-import android.telecom.Log;
+import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
@@ -37,6 +37,7 @@
import com.android.ims.ImsException;
import com.android.ims.ImsStreamMediaProfile;
+import com.android.ims.internal.ImsVideoCallProviderWrapper;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
@@ -51,7 +52,9 @@
/**
* {@hide}
*/
-public class ImsPhoneConnection extends Connection {
+public class ImsPhoneConnection extends Connection implements
+ ImsVideoCallProviderWrapper.ImsVideoProviderWrapperCallback {
+
private static final String LOG_TAG = "ImsPhoneConnection";
private static final boolean DBG = true;
@@ -89,6 +92,15 @@
private boolean mIsEmergency = false;
/**
+ * Used to indicate that video state changes detected by
+ * {@link #updateMediaCapabilities(ImsCall)} should be ignored. When a video state change from
+ * unpaused to paused occurs, we set this flag and then update the existing video state when
+ * new {@link #onReceiveSessionModifyResponse(int, VideoProfile, VideoProfile)} callbacks come
+ * in. When the video un-pauses we continue receiving the video state updates.
+ */
+ private boolean mShouldIgnoreVideoStateChanges = false;
+
+ /**
* Used to indicate whether the wifi state is based on
* {@link com.android.ims.ImsConnectionStateListener#
* onFeatureCapabilityChanged(int, int[], int[])} callbacks, or values received via the
@@ -379,7 +391,9 @@
@Override
public boolean onDisconnect(int cause) {
Rlog.d(LOG_TAG, "onDisconnect: cause=" + cause);
- if (mCause != DisconnectCause.LOCAL) mCause = cause;
+ if (mCause != DisconnectCause.LOCAL || cause == DisconnectCause.INCOMING_REJECTED) {
+ mCause = cause;
+ }
return onDisconnect();
}
@@ -740,7 +754,7 @@
int namep = ImsCallProfile.OIRToPresentation(
callProfile.getCallExtraInt(ImsCallProfile.EXTRA_CNAP));
if (Phone.DEBUG_PHONE) {
- Rlog.d(LOG_TAG, "address = " + address + " name = " + name +
+ Rlog.d(LOG_TAG, "address = " + Rlog.pii(LOG_TAG, address) + " name = " + name +
" nump = " + nump + " namep = " + namep);
}
if(equalsHandlesNulls(mAddress, address)) {
@@ -792,8 +806,35 @@
.getVideoStateFromImsCallProfile(negotiatedCallProfile);
if (oldVideoState != newVideoState) {
- setVideoState(newVideoState);
- changed = true;
+ // The video state has changed. See also code in onReceiveSessionModifyResponse
+ // below. When the video enters a paused state, subsequent changes to the video
+ // state will not be reported by the modem. In onReceiveSessionModifyResponse
+ // we will be updating the current video state while paused to include any
+ // changes the modem reports via the video provider. When the video enters an
+ // unpaused state, we will resume passing the video states from the modem as is.
+ if (VideoProfile.isPaused(oldVideoState) &&
+ !VideoProfile.isPaused(newVideoState)) {
+ // Video entered un-paused state; recognize updates from now on; we want to
+ // ensure that the new un-paused state is propagated to Telecom, so change
+ // this now.
+ mShouldIgnoreVideoStateChanges = false;
+ }
+
+ if (!mShouldIgnoreVideoStateChanges) {
+ setVideoState(newVideoState);
+ changed = true;
+ } else {
+ Rlog.d(LOG_TAG, "updateMediaCapabilities - ignoring video state change " +
+ "due to paused state.");
+ }
+
+ if (!VideoProfile.isPaused(oldVideoState) &&
+ VideoProfile.isPaused(newVideoState)) {
+ // Video entered pause state; ignore updates until un-paused. We do this
+ // after setVideoState is called above to ensure Telecom is notified that
+ // the device has entered paused state.
+ mShouldIgnoreVideoStateChanges = true;
+ }
}
}
@@ -982,7 +1023,7 @@
sb.append(" telecomCallID: ");
sb.append(getTelecomCallId());
sb.append(" address: ");
- sb.append(Log.pii(getAddress()));
+ sb.append(Rlog.pii(LOG_TAG, getAddress()));
sb.append(" ImsCall: ");
if (mImsCall == null) {
sb.append("null");
@@ -1000,4 +1041,48 @@
protected boolean isEmergency() {
return mIsEmergency;
}
+
+ /**
+ * Handles notifications from the {@link ImsVideoCallProviderWrapper} of session modification
+ * responses received.
+ *
+ * @param status The status of the original request.
+ * @param requestProfile The requested video profile.
+ * @param responseProfile The response upon video profile.
+ */
+ @Override
+ public void onReceiveSessionModifyResponse(int status, VideoProfile requestProfile,
+ VideoProfile responseProfile) {
+ if (status == android.telecom.Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS &&
+ mShouldIgnoreVideoStateChanges) {
+ int currentVideoState = getVideoState();
+ int newVideoState = responseProfile.getVideoState();
+
+ // If the current video state is paused, the modem will not send us any changes to
+ // the TX and RX bits of the video state. Until the video is un-paused we will
+ // "fake out" the video state by applying the changes that the modem reports via a
+ // response.
+
+ // First, find out whether there was a change to the TX or RX bits:
+ int changedBits = currentVideoState ^ newVideoState;
+ changedBits &= VideoProfile.STATE_BIDIRECTIONAL;
+ if (changedBits == 0) {
+ // No applicable change, bail out.
+ return;
+ }
+
+ // Turn off any existing bits that changed.
+ currentVideoState &= ~(changedBits & currentVideoState);
+ // Turn on any new bits that turned on.
+ currentVideoState |= changedBits & newVideoState;
+
+ Rlog.d(LOG_TAG, "onReceiveSessionModifyResponse : received " +
+ VideoProfile.videoStateToString(requestProfile.getVideoState()) +
+ " / " +
+ VideoProfile.videoStateToString(responseProfile.getVideoState()) +
+ " while paused ; sending new videoState = " +
+ VideoProfile.videoStateToString(currentVideoState));
+ setVideoState(currentVideoState);
+ }
+ }
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java b/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
index 793fb0b..dbb4036 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPullCall.java
@@ -31,6 +31,8 @@
*
* @param number The phone number of the call to be pulled.
* @param videoState The video state of the call to be pulled.
+ * @param dialogId The {@link ImsExternalConnection#getCallId()} dialog Id associated with the
+ * call to be pulled.
*/
- void pullExternalCall(String number, int videoState);
+ void pullExternalCall(String number, int videoState, int dialogId);
}
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index db29bc4..d943148 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -541,7 +541,7 @@
try {
if (validEfCfis(mEfCfis)) {
- // lsb is of byte 1 is voice status
+ // lsb is of byte f1 is voice status
if (enable) {
mEfCfis[1] |= 1;
} else {
@@ -554,9 +554,7 @@
// Update dialNumber if not empty and CFU is enabled.
// Spec reference for EF_CFIS contents, TS 51.011 section 10.3.46.
if (enable && !TextUtils.isEmpty(dialNumber)) {
- if (VDBG) {
- logv("EF_CFIS: updating cf number, " + dialNumber);
- }
+ logv("EF_CFIS: updating cf number, " + Rlog.pii(LOG_TAG, dialNumber));
byte[] bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(dialNumber);
System.arraycopy(bcdNumber, 0, mEfCfis, CFIS_TON_NPI_OFFSET, bcdNumber.length);
@@ -674,7 +672,7 @@
}
log("IMSI: mMncLength=" + mMncLength);
- log("IMSI: " + mImsi.substring(0, 6) + "xxxxxxx");
+ log("IMSI: " + mImsi.substring(0, 6) + Rlog.pii(LOG_TAG, mImsi.substring(6)));
if (((mMncLength == UNKNOWN) || (mMncLength == 2)) &&
((mImsi != null) && (mImsi.length() >= 6))) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index da1f1c8..9974a6d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -19,23 +19,40 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.test.InstrumentationTestCase;
+import android.test.mock.MockContentProvider;
+import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
+import android.util.ArrayMap;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
public class CarrierAppUtilsTest extends InstrumentationTestCase {
private static final String CARRIER_APP = "com.example.carrier";
private static final String[] CARRIER_APPS = new String[] { CARRIER_APP };
+ private static final String ASSOCIATED_APP = "com.example.associated";
+ private static final ArrayMap<String, List<String>> ASSOCIATED_APPS = new ArrayMap<>();
+ static {
+ List<String> associatedAppList = new ArrayList<>();
+ associatedAppList.add(ASSOCIATED_APP);
+ ASSOCIATED_APPS.put(CARRIER_APP, associatedAppList);
+ }
private static final int USER_ID = 12345;
private static final String CALLING_PACKAGE = "phone";
@Mock private IPackageManager mPackageManager;
@Mock private TelephonyManager mTelephonyManager;
+ private SettingsMockContentProvider mContentProvider;
+ private MockContentResolver mContentResolver;
@Override
public void setUp() throws Exception {
@@ -44,13 +61,20 @@
getInstrumentation().getTargetContext().getCacheDir().getPath());
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
MockitoAnnotations.initMocks(this);
+
+ mContentResolver = new MockContentResolver();
+ mContentProvider = new SettingsMockContentProvider();
+ mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider);
+ Settings.Secure.putIntForUser(
+ mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 0, USER_ID);
}
/** No apps configured - should do nothing. */
@Test @SmallTest
public void testDisableCarrierAppsUntilPrivileged_EmptyList() {
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, new String[0]);
+ mTelephonyManager, mContentResolver, USER_ID, new String[0],
+ ASSOCIATED_APPS);
Mockito.verifyNoMoreInteractions(mPackageManager, mTelephonyManager);
}
@@ -58,9 +82,10 @@
@Test @SmallTest
public void testDisableCarrierAppsUntilPrivileged_MissingApp() throws Exception {
Mockito.when(mPackageManager.getApplicationInfo("com.example.missing.app",
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(null);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(null);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, new String[] { "com.example.missing.app" });
+ mTelephonyManager, mContentResolver, USER_ID,
+ new String[] { "com.example.missing.app" }, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -75,9 +100,9 @@
public void testDisableCarrierAppsUntilPrivileged_NonSystemApp() throws Exception {
ApplicationInfo appInfo = new ApplicationInfo();
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -99,11 +124,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -119,11 +144,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -139,11 +164,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -159,11 +184,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -171,43 +196,139 @@
new String[] {appInfo.packageName}, USER_ID);
}
- /** Configured app has privileges, and is in the default state - should enable. */
+ /**
+ * Configured app has privileges, and is in the default state - should enable. Associated app
+ * is missing and should not be touched.
+ */
@Test @SmallTest
- public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Default() throws Exception {
+ public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_MissingAssociated_Default()
+ throws Exception {
ApplicationInfo appInfo = new ApplicationInfo();
appInfo.packageName = CARRIER_APP;
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager).setApplicationEnabledSetting(
CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
new String[] {appInfo.packageName}, USER_ID);
}
- /** Configured app has privileges, and is disabled until used - should enable. */
+ /**
+ * Configured app has privileges, and is in the default state along with associated app - should
+ * enable both.
+ */
@Test @SmallTest
- public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_DisabledUntilUsed()
+ public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Associated_Default()
+ throws Exception {
+ // Enabling should be done even if this isn't the first run.
+ Settings.Secure.putIntForUser(
+ mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1, USER_ID);
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = CARRIER_APP;
+ appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
+ Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+ CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+ new String[] {appInfo.packageName}, USER_ID);
+ }
+
+ /**
+ * Configured app has privileges, and is disabled until used - should enable. Associated app has
+ * been updated and should not be touched.
+ */
+ @Test @SmallTest
+ public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_UpdatedAssociated_DisabledUntilUsed()
throws Exception {
ApplicationInfo appInfo = new ApplicationInfo();
appInfo.packageName = CARRIER_APP;
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |=
+ ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+ associatedAppInfo.enabledSetting =
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager).setApplicationEnabledSetting(
CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
+ new String[] {appInfo.packageName}, USER_ID);
+ }
+
+ /**
+ * Configured app has privileges, and is disabled until used along with associated app - should
+ * enable both.
+ */
+ @Test @SmallTest
+ public void testDisableCarrierAppsUntilPrivileged_HasPrivileges_Associated_DisabledUntilUsed()
+ throws Exception {
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = CARRIER_APP;
+ appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
+ Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ associatedAppInfo.enabledSetting =
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
+ Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
+ CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP, USER_ID, CALLING_PACKAGE);
Mockito.verify(mPackageManager).grantDefaultPermissionsToEnabledCarrierApps(
new String[] {appInfo.packageName}, USER_ID);
}
@@ -220,11 +341,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -242,9 +363,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -261,11 +383,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -282,9 +404,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -301,11 +424,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -322,9 +445,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -341,11 +465,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -362,9 +486,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -373,22 +498,108 @@
Mockito.any(String[].class), Mockito.anyInt());
}
- /** Configured app has no privileges, and is in the default state - should disable until use. */
+ /**
+ * Configured app has no privileges, and is in the default state - should disable until use.
+ * Associated app is enabled and should not be touched.
+ */
@Test @SmallTest
- public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Default() throws Exception {
+ public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_EnabledAssociated_Default()
+ throws Exception {
ApplicationInfo appInfo = new ApplicationInfo();
appInfo.packageName = CARRIER_APP;
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager).setApplicationEnabledSetting(
CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0,
+ USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never())
+ .grantDefaultPermissionsToEnabledCarrierApps(
+ Mockito.any(String[].class), Mockito.anyInt());
+ }
+
+ /**
+ * Configured app has no privileges, and is in the default state along with associated app -
+ * should disable both.
+ */
+ @Test @SmallTest
+ public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default()
+ throws Exception {
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = CARRIER_APP;
+ appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
+ Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+ CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
+ CALLING_PACKAGE);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ ASSOCIATED_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0,
+ USER_ID, CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never())
+ .grantDefaultPermissionsToEnabledCarrierApps(
+ Mockito.any(String[].class), Mockito.anyInt());
+ }
+
+ /**
+ * Configured app has no privileges, and is in the default state along with associated app, and
+ * disabling has already occurred - should only disable configured app.
+ */
+ @Test @SmallTest
+ public void testDisableCarrierAppsUntilPrivileged_NoPrivileges_Associated_Default_AlreadyRun()
+ throws Exception {
+ Settings.Secure.putIntForUser(
+ mContentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1, USER_ID);
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = CARRIER_APP;
+ appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ ApplicationInfo associatedAppInfo = new ApplicationInfo();
+ associatedAppInfo.packageName = ASSOCIATED_APP;
+ associatedAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+ associatedAppInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ Mockito.when(mPackageManager.getApplicationInfo(ASSOCIATED_APP,
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID))
+ .thenReturn(associatedAppInfo);
+ Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
+ .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
+ CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
+ Mockito.verify(mPackageManager).setApplicationEnabledSetting(
+ CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
+ CALLING_PACKAGE);
+ Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
+ Mockito.eq(ASSOCIATED_APP), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
+ Mockito.anyString());
Mockito.verify(mPackageManager, Mockito.never())
.grantDefaultPermissionsToEnabledCarrierApps(
Mockito.any(String[].class), Mockito.anyInt());
@@ -402,9 +613,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager).setApplicationEnabledSetting(
CARRIER_APP, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED, 0, USER_ID,
CALLING_PACKAGE);
@@ -422,11 +634,11 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
Mockito.when(mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(CARRIER_APP))
.thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- mTelephonyManager, USER_ID, CARRIER_APPS);
+ mTelephonyManager, mContentResolver, USER_ID, CARRIER_APPS, ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -444,9 +656,10 @@
appInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
appInfo.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
Mockito.when(mPackageManager.getApplicationInfo(CARRIER_APP,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, USER_ID)).thenReturn(appInfo);
CarrierAppUtils.disableCarrierAppsUntilPrivileged(CALLING_PACKAGE, mPackageManager,
- null /* telephonyManager */, USER_ID, CARRIER_APPS);
+ null /* telephonyManager */, mContentResolver, USER_ID, CARRIER_APPS,
+ ASSOCIATED_APPS);
Mockito.verify(mPackageManager, Mockito.never()).setApplicationEnabledSetting(
Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt(),
Mockito.anyString());
@@ -454,5 +667,21 @@
.grantDefaultPermissionsToEnabledCarrierApps(
Mockito.any(String[].class), Mockito.anyInt());
}
+
+ class SettingsMockContentProvider extends MockContentProvider {
+ private int mExpectedValue;
+
+ @Override
+ public Bundle call(String method, String request, Bundle args) {
+ Bundle result = new Bundle();
+ if (Settings.CALL_METHOD_GET_SECURE.equals(method)) {
+ result.putString(Settings.NameValueTable.VALUE, Integer.toString(mExpectedValue));
+ } else {
+ mExpectedValue = Integer.parseInt(args.getString(Settings.NameValueTable.VALUE));
+ }
+ return result;
+ }
+ }
+
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index fb4ab24..edb4554 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -353,21 +353,34 @@
// verify getCurrentCalls is called on init
verify(mSimulatedCommandsVerifier).getCurrentCalls(any(Message.class));
- // update phone type
- mCTUT.updatePhoneType();
+ // update phone type (call the function on same thread as the call tracker)
+ Handler updatePhoneTypeHandler = new Handler(mCTUT.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ mCTUT.updatePhoneType();
+ }
+ };
+ updatePhoneTypeHandler.sendEmptyMessage(0);
+ waitForMs(100);
// verify getCurrentCalls is called on updating phone type
verify(mSimulatedCommandsVerifier, times(2)).getCurrentCalls(any(Message.class));
- // verify that if phone type is updated, calls and callTracker go to idle
+ // we'd like to verify that if phone type is updated, calls and callTracker go to idle.
+ // However, as soon as phone type is updated, call tracker queries for calls from RIL and
+ // will go back to OFFHOOK
+
+ // call tracker goes to OFFHOOK
testMOCallPickUp();
- // update phone type
- mCTUT.updatePhoneType();
+ // update phone type - call tracker goes to IDLE and then due to getCurrentCalls(),
+ // goes back to OFFHOOK
+ updatePhoneTypeHandler.sendEmptyMessage(0);
+ waitForMs(100);
// verify CT and calls go to idle
- assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
- assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mForegroundCall.getState());
+ assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
+ assertEquals(GsmCdmaCall.State.ACTIVE, mCTUT.mForegroundCall.getState());
assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mBackgroundCall.getState());
assertEquals(GsmCdmaCall.State.IDLE, mCTUT.mRingingCall.getState());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java b/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
index 8346a9d..7030440 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java
@@ -63,6 +63,13 @@
}
@SmallTest
+ public void testLang_India() throws Exception {
+ assertEquals(MccTable.defaultLanguageForMcc(404), "en");
+ assertEquals(MccTable.defaultLanguageForMcc(405), "en");
+ assertEquals(MccTable.defaultLanguageForMcc(406), "en");
+ }
+
+ @SmallTest
public void testSmDigits() throws Exception {
assertEquals(MccTable.smallestDigitsMccForMnc(312), 3);
assertEquals(MccTable.smallestDigitsMccForMnc(430), 2);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 101640e..805ee93 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -58,6 +58,7 @@
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
import com.android.internal.telephony.mocks.TelephonyRegistryMock;
@@ -172,6 +173,8 @@
protected IBinder mConnMetLoggerBinder;
@Mock
protected CarrierSignalAgent mCarrierSignalAgent;
+ @Mock
+ protected ImsExternalCallTracker mImsExternalCallTracker;
protected TelephonyManager mTelephonyManager;
protected SubscriptionManager mSubscriptionManager;
@@ -340,6 +343,8 @@
anyInt(), any(Object.class));
doReturn(mIDeviceIdleController).when(mTelephonyComponentFactory)
.getIDeviceIdleController();
+ doReturn(mImsExternalCallTracker).when(mTelephonyComponentFactory).
+ makeImsExternalCallTracker(any(ImsPhone.class));
//mPhone
doReturn(mContext).when(mPhone).getContext();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsParserTest.java b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsParserTest.java
index 6caea7d..12a4655 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsParserTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsParserTest.java
@@ -16,9 +16,7 @@
package com.android.internal.telephony;
import android.test.suitebuilder.annotation.SmallTest;
-
import com.android.internal.telephony.VisualVoicemailSmsParser.WrappedMessageData;
-
import junit.framework.TestCase;
public class VisualVoicemailSmsParserTest extends TestCase {
@@ -147,4 +145,42 @@
assertEquals("STATUS", result.prefix);
assertEquals("", result.fields.getString("key"));
}
+
+ @SmallTest
+ public void testAlternativeParsing_Mboxupdate() {
+ WrappedMessageData result = VisualVoicemailSmsParser.parseAlternativeFormat(
+ "MBOXUPDATE?m=1;server=example.com;port=143;name=foo@example.com;pw=bar");
+
+ assertEquals("MBOXUPDATE", result.prefix);
+ assertEquals("1", result.fields.getString("m"));
+ assertEquals("example.com", result.fields.getString("server"));
+ assertEquals("143", result.fields.getString("port"));
+ assertEquals("foo@example.com", result.fields.getString("name"));
+ assertEquals("bar", result.fields.getString("pw"));
+ }
+
+ @SmallTest
+ public void testAlternativeParsing_Unrecognized() {
+ WrappedMessageData result = VisualVoicemailSmsParser.parseAlternativeFormat(
+ "UNRECOGNIZED?cmd=STATUS");
+
+ assertEquals("UNRECOGNIZED", result.prefix);
+ assertEquals("STATUS", result.fields.getString("cmd"));
+ }
+
+ @SmallTest
+ public void testAlternativeParsingFail_MissingSeparator() {
+ WrappedMessageData result = VisualVoicemailSmsParser.parseAlternativeFormat(
+ "I send SMS in weird formats");
+
+ assertNull(result);
+ }
+
+ @SmallTest
+ public void testAlternativeParsingFail_NotWhitelistedEvent() {
+ WrappedMessageData result = VisualVoicemailSmsParser.parseAlternativeFormat(
+ "AreYouStillThere?");
+
+ assertNull(result);
+ }
}